This commit is contained in:
wtq
2025-11-13 14:42:30 +08:00
commit 7d879ff3bc
349 changed files with 54558 additions and 0 deletions

View File

@@ -0,0 +1,305 @@
.skuName-cell {
box-sizing: border-box;
background: white;
padding: 19rpx;
border-radius: 10rpx;
margin: 15rpx 15rpx;
box-shadow: 0rpx 2rpx 10rpx rgb(207, 207, 207);
.skuName {
display: flex;
align-items: flex-start;
position: relative;
.skuName-img {
position: relative;
view {
position: absolute;
z-index: 9;
left: 0;
top: 0;
width: 182rpx;
height: 182rpx;
border-radius: 10rpx;
background: rgba(0, 0, 0, .4);
text-align: center;
line-height: 182rpx;
color: #fff;
font-weight: bold;
}
.imglabel {
width: 180rpx;
height: 180rpx;
border-radius: 10rpx;
border: 1rpx solid rgb(218, 218, 218);
}
}
.skuName-info {
display: flex;
flex-direction: column;
justify-content: space-between;
margin-left: 17rpx;
width: 100%;
height: 180rpx;
.input-price {
position: absolute;
border: 1rpx solid rgba(0, 0, 0, 0.1);
background: white;
border-radius: 8rpx;
padding: 20rpx;
top: 60rpx;
color: #333;
}
.skuName-name {
color: #333;
font-size: 32rpx;
line-height: 1;
display: flex;
align-items: flex-start;
}
.skuName-monthsale {
font-size: 28rpx;
color: #999;
line-height: 1;
margin-top: 7rpx;
}
.skuName-failsync {
font-size: 28rpx;
color: #F60D58;
line-height: 1;
margin-top: 7rpx;
margin-bottom: -30rpx;
}
.skuName-price {
display: flex;
color: #F60D58;
line-height: 1;
.icon-modify {
margin-left: 15rpx;
}
}
.skuName-tips {
font-size: 28rpx;
line-height: 1;
color: #333;
}
.red {
color: #F60D58;
}
.green {
color: $jx-primary;
}
}
}
// sku
.skus {
border-top: 1rpx dashed #ccc;
display: flex;
flex-flow: row wrap;
// justify-content: flex-end;
// padding-top: 16rpx;
// overflow: hidden;
margin-top: 10rpx;
align-items: flex-start;
.sku-cell:nth-of-type(even) {
margin-left: 10rpx;
}
}
// 价格审核中样式
.check-display {
color: #f44;
font-size: 24rpx;
font-weight: bold;
animation: rubberBand 1s infinite alternate;
}
}
.skus-wrapper-new {
border-top: 1rpx solid rgb(219, 219, 219);
.error {
text-align: center;
font-size: 24rpx;
font-weight: bold;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.mt {
color: #f29a40;
}
.eb {
color: #51a7fc;
}
.sku-cell2 {
padding: 10rpx 0 0 0;
border-bottom: 1rpx solid rgb(219, 219, 219);
position: relative;
}
.isSale2 {}
.cell-top {
display: flex;
align-items: center;
.price {
color: #333;
width: 23%;
flex-shrink: 0;
text-align: center;
display: flex;
justify-content: center;
flex-flow: column;
.sku-spec {
font-size: 26rpx;
}
.sku-price {
font-size: 26rpx;
}
}
.promotion-price {
color: #F60D58;
}
.btn-group {
width: 78%;
flex-shrink: 0;
display: flex;
justify-content: space-around;
.btn {
box-sizing: border-box;
flex: 1;
height: 80rpx;
text-align: center;
font-size: 24rpx;
border-radius: 10rpx;
color: $jx-primary;
border: 2rpx solid $jx-primary;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
margin-right: 8rpx;
}
.tmpSaleNo {
box-sizing: border-box;
display: flex;
flex-direction: column;
font-size: 28rpx;
line-height: 1.02;
margin: 0;
}
.onActive {
background: $jx-primary;
color: white;
}
}
}
.cell-bottom {
font-size: 28rpx;
text-align: center;
color: #666;
padding: 5rpx 0;
}
.sku-autoSaleAt {
font-size: 26rpx;
text-align: center;
color: #F25340;
padding: 5rpx 0;
text {
font-weight: bold;
}
}
}
.checkBoxWrap {
display: flex;
width: 100%;
justify-content: flex-end;
padding-top: 15rpx;
}
.aduit-type {
font-size: 28rpx;
text-align: center;
color: $jx-primary;
}
.aduit-btn-group {
display: flex;
align-items: center;
justify-content: center;
padding-top: 20rpx;
.btn {
font-size: 28rpx;
padding: 20rpx 40rpx;
background: $jx-primary;
border-radius: 10rpx;
color: white;
margin: 0 20rpx;
}
.refuse {
background: #f44;
}
}
@keyframes rubberBand {
from {
transform: scale3d(1, 1, 1);
}
30% {
transform: scale3d(1.01, 0.75, 1);
}
40% {
transform: scale3d(0.95, 1.25, 1);
}
50% {
transform: scale3d(1.02, 0.85, 1);
}
65% {
transform: scale3d(0.98, 1.05, 1);
}
75% {
transform: scale3d(1.01, 0.95, 1);
}
to {
transform: scale3d(1, 1, 1);
}
}

View File

@@ -0,0 +1,177 @@
import shopping from "@/api/https/shopping"
import { store } from "@/store"
import { getStorage } from "@/utils/storage"
import toast from "@/utils/toast"
import { jx_throttles, timeFormatD } from "@/utils/tools"
import { computed } from "@vue/reactivity"
import configCms from "@/utils/configCms"
interface propType {
skuName: AnyObject
isAudit: boolean
isHot: boolean
showMountTab: boolean
}
/*************************************************
* 商品列表
*/
function goodsListFn(props: Readonly<propType>) {
/*************************************************
* 列表判断条件
*/
const isNewPriceDisplay: any = computed(() => {
store.getters['storeInfo/isNewPriceDisplay']
})
/*************************************************
* 获取userType
*/
const userType = computed(() => {
return +getStorage('userType')
})
/*************************************************
* 修改商品售卖状态
*/
function updateSaleStatus(sku: AnyObject, skuName: AnyObject, status: number) {
if (+sku.storeSkuStatus === +status && !sku.autoSaleAt) return false
let data = {
sku,
skuName,
status
}
updateSaleStatusThrottles(data)
}
const updateSaleStatusThrottles = jx_throttles({
time: 500,
success: async (e: AnyObject) => {
let data = {
storeIDs: JSON.stringify([getStorage('storeID')]),
payload: JSON.stringify([
{
nameID: e.skuName.id,
skus: [
{
skuID: e.sku.id,
isSale: +e.status === 0 ? -1 : +e.status,
},
],
},
]),
}
let res = await shopping.update_stores_skus(data)
if (res.code == 0) {
changeSaleStatus(e.sku, e.skuName, e.status)
if (e.sku.autoSaleAt) e.sku.autoSaleAt = 0
} else {
toast('修改失败', 2)
}
},
fail: (t: number) => {
toast(`操作太快`)
}
})
/*************************************************
* 修改商品临时不可售
*/
function tmpSaleNo(sku: AnyObject, skuName: AnyObject) {
if (sku.storeSkuStatus === 0 && sku.autoSaleAt) return false
let data = {
sku,
skuName,
}
tmpSaleNoThrottles(data)
}
const tmpSaleNoThrottles = jx_throttles({
time: 500,
success: async (e: AnyObject) => {
let autoSaleAt = computedAutoSaleAt()
let data = {
storeIDs: JSON.stringify([getStorage('storeID')]),
payload: JSON.stringify([{
skuID: e.sku.id,
isSale: -1,
isAsync: false,
}]),
autoSaleAt: autoSaleAt
}
let res = await shopping.update_stores_skus_sale(data)
// let res:AnyObject = {
// code: "-105",
// desc: "本地数据修改成功,但同步失败,请根据错误提示处理!,同步错误信息:[{\"商品ID\":0,\"分类名\":\"\",\"门店ID\":804947,\"平台名\":\"抖店平台\",\"平台商品ID\":\"\",\"商品nameID\":0,\"平台价\":0,\"同步类型\":\"异常同步错误\",\"错误信息\":\"门店:804947修改没有创建的商品:22807\"},{\"商品ID\":22807,\"分类名\":\"\",\"门店ID\":804947,\"平台名\":\"京东到家\",\"平台商品ID\":\"2792687352\",\"商品nameID\":8643,\"平台价\":0,\"同步类型\":\"更新商品状态\",\"错误信息\":\"未查询到到家商品编码\"}]",
// data: ""
// }
// if (res.code === '0') {
// changeSaleStatus(e.sku, e.skuName, 0)
// e.sku.autoSaleAt = autoSaleAt
// } else {
// if(res.code === '-105' && res.desc.includes('本地数据修改成功,但同步失败,请根据错误提示处理')) toast(res.desc)
// else toast('修改失败', 2)
// }
if (res.code == 0) {
changeSaleStatus(e.sku, e.skuName, 0)
e.sku.autoSaleAt = autoSaleAt
} else {
let findIndex = res.desc.indexOf('[')
let str = ''
if(findIndex !== -1){
JSON.parse(res.desc.substring(findIndex)).forEach((element:AnyObject) => {
str = str.length >0 ? str + '\n' + element['平台名'] + ':【' + element['错误信息'] + '】': str + element['平台名'] +':【' + element['错误信息']+'】'
});
}
if(res.code === '-105' && res.desc.includes('本地数据修改成功,但同步失败,请根据错误提示处理')) toast(`${str}`)
else toast('修改失败', 2)
}
},
fail: (t: number) => {
toast(`操作太快`)
}
})
/*************************************************
* 计算自动可售时间
*/
function computedAutoSaleAt() {
let now = +new Date()
let autoTime = +new Date(`${timeFormatD(+new Date())} ${autoSaleAt.value}`)
if (now < autoTime) {
return `${timeFormatD(+new Date())} ${autoSaleAt.value}`
} else {
return `${timeFormatD(+new Date() + 24 * 3600 * 1000)} ${autoSaleAt.value}`
}
}
// 自动可售时间
const autoSaleAt = computed(() => {
let { autoSaleAt = '' } = configCms.serveInfo
return autoSaleAt
})
/*************************************************
* 修改商品可售状态
*/
async function changeSaleStatus(sku: AnyObject, skuName: AnyObject, status: number) {
if (props.isAudit) return false
sku.storeSkuStatus = +status
// 计算可售不可售图标
if (skuName.skus.some((item: AnyObject) => item.storeSkuStatus)) {
skuName.skuAllnoSale = false
} else {
skuName.skuAllnoSale = true
}
}
return {
isNewPriceDisplay, // 列表判断条件
userType, // 获取userType
updateSaleStatus, // 修改商品售卖状态
tmpSaleNo, // 临时不可售
}
}
export default goodsListFn

View File

@@ -0,0 +1,264 @@
<template>
<view class="skuName-cell">
<!-- skuName -->
<view class="skuName">
<!-- 图片 -->
<view class="skuName-img" @tap="previewImg(skuName)">
<view v-show="skuName.skuAllnoSale">不可售</view>
<image
class="imglabel"
mode="scaleToFill"
lazy-load
:src="skuName.img"
/>
</view>
<!-- 图片 -->
<!-- 其他信息 -->
<view class="skuName-info">
<!-- 名称 -->
<view class="skuName-name">
{{ skuName.prefix ? '[' + skuName.prefix + ']' : ''
}}{{ skuName.name }}
</view>
<!-- skuNameID -->
<view @tap.stop="copyInfo(''+ skuName.id, '复制nameID成功')" style="color:#818181;">
<text>{{ skuName.id }}</text>
<jx-icon icon="fuzhi" color="#818181" style="margin-left: 10rpx;"></jx-icon>
</view>
<!-- 价格 改价 -->
<view class="skuName-price" @tap="openPriceDialog(skuName)">
<jx-price
:price="skuName.unitPrice"
color="#F60D58"
sizeM="22rpx"
sizeN="38rpx"
/>
<view class="icon-modify" v-if="!isAudit">
<jx-icon icon="shuxie" color="#999" :size="38" />
</view>
</view>
<!-- 提示信息 -->
<view>
<view class="skuName-tips" v-if="skuName.unit === '份'">
该价格为每斤价格
</view>
<view class="skuName-tips green" v-if="skuName.unit !== '份'">
该价格为每{{ skuName.unit }}价格
</view>
<!-- 审核状态 -->
<view class="check-display" v-show="skuName.auditUnitPrice">
审核中价格<jx-price
:price="skuName.auditUnitPrice"
color="#f44"
size="24rpx"
/>
</view>
</view>
</view>
<!-- 其他信息 -->
</view>
<!-- skuName -->
<!-- sku2 -->
<view class="skus-wrapper-new" v-if="!isAudit">
<view v-for="(sku, j) in skuName.skus" :key="j" class="sku-cell2">
<!-- 异常商品 -->
<view
class="error mt"
v-if="
sku.mtwmID !== '' &&
(sku.mtwmSyncStatus & 16) === 16 &&
(sku.mtwmSyncStatus & 2) !== 2 &&
(sku.mtwmSyncStatus & 4) !== 4
"
>美团:该商品无法修改价格,请联系运营修改</view
>
<view
class="error eb"
v-if="
sku.ebaiID !== '' &&
(sku.ebaiSyncStatus & 16) === 16 &&
(sku.ebaiSyncStatus & 2) !== 2 &&
(sku.ebaiSyncStatus & 4) !== 4
"
>饿佰:该商品无法修改价格,请联系运营修改</view
>
<view class="cell-top">
<view class="price">
<view class="sku-spec">
{{ sku.specQuality }}{{ sku.specUnit }}
</view>
<view
class="sku-price"
:class="{ 'promotion-price': !isNewPriceDisplay && sku.actPrice }"
>
<jx-price
:price="sku.comparePrice"
sizeM="22rpx"
sizeN="28rpx"
color="#000"
/>
</view>
</view>
<view class="btn-group">
<view
class="btn"
:class="{ onActive: sku.storeSkuStatus }"
@tap="updateSaleStatus(sku, skuName, 1)"
>
可售
</view>
<view
class="btn"
:class="{ onActive: !sku.storeSkuStatus && !sku.autoSaleAt }"
@tap="updateSaleStatus(sku, skuName, 0)"
>
不可售
</view>
<view
v-if="!isHot"
class="btn tmpSaleNo"
:class="{ onActive: !sku.storeSkuStatus && sku.autoSaleAt }"
@tap="tmpSaleNo(sku, skuName)"
>
<text>临时</text>
<text>不可售</text>
</view>
</view>
</view>
<!-- 库存以及位置码 -->
<view style="display: flex;color:#666;margin-top:20rpx;justify-content: center">
<view @tap="openDialog(skuName,sku,'stock')">
库存:{{sku.stock}}
<jx-icon icon="shuxie" color="#999" :size="24" />
</view>
<view style="margin-left: 20rpx;" @tap="openDialog(skuName,sku,'locationCode')">
货架码:{{sku.locationCode && sku.locationCode !== 'EMPTY_VALUE' ? sku.locationCode : ''}}
<jx-icon icon="shuxie" color="#999" :size="24" />
</view>
</view>
<view class="cell-bottom">{{ sku.comment ? sku.comment : '' }}</view>
<view class="sku-autoSaleAt" v-if="sku.autoSaleAt">
该规格将在 <text>{{ sku.autoSaleAt }}</text> 可售
</view>
</view>
<view v-if="showMountTab" class="checkBoxWrap">
<label @tap="handleSale(skuName)">
<checkbox color="#4eb331" style="transform: scale(0.8)" />选中商品
</label>
</view>
</view>
<!-- 待审核商品操作面板 -->
<view class="aduit-wall" v-else>
<view class="aduit-type">{{
skuName.type === 1 ? '【价格】正在审核中' : '【新建】正在审核中'
}}</view>
<!-- ((userType & 4) === 4) 运营 -->
<view class="aduit-btn-group" v-if="(+getStorage('userType') & 4) === 4">
<view class="btn refuse" @tap="toExamine(skuName, -1)">拒绝</view>
<view class="btn" @tap="toExamine(skuName, 1)">批准</view>
</view>
<view class="aduit-btn-group" v-else>
<view class="btn" @tap="phoneCall(storeInfo.marketManName)"
>联系运营加快审核</view
>
</view>
</view>
</view>
</template>
<script lang="ts" setup >
import useGlobalFunc from '@/composables/useGlobalFunc'
import { store } from '@/store'
import { getStorage } from '@/utils/storage'
import { computed } from 'vue'
import goodsListFn from './right-main'
import useOrderInfo from '@/composables/useOrderInfo'
const { copyInfo } = useOrderInfo()
const { phoneCall } = useGlobalFunc()
/*************************************************
* 接收数据
*/
interface propType {
skuName: AnyObject
isAudit: boolean
isHot: boolean
showMountTab: boolean
}
const prop = defineProps<propType>()
const {
isNewPriceDisplay, // 列表判断条件
updateSaleStatus, // 修改商品售卖状态
tmpSaleNo, // 临时不可售
} = goodsListFn(prop)
const {
previewImage, // 预览图片
} = useGlobalFunc()
const emit = defineEmits<{
(e: 'handleSale', data: AnyObject): void
(e: 'openPriceDialog', data: AnyObject): void
(e: 'openDialog', data: AnyObject): void
(e: 'toExamine', data: AnyObject): void
}>()
function handleSale(skuName: AnyObject) {
emit('handleSale', skuName)
}
/*************************************************
* 预览图片
*/
function previewImg(skuName:AnyObject) {
let arr = [skuName.img,skuName.img2,skuName.img3,skuName.img4,skuName.img5].filter(item => { return item && item.length > 0 })
previewImage(arr)
}
/*************************************************
* 修改操作
*/
function openPriceDialog(skuName: AnyObject) {
if (prop.isAudit) return
emit('openPriceDialog', skuName)
}
function openDialog(skuName: AnyObject,sku:AnyObject,type:String) {
let payload = {
nameID:skuName.id,
Skus:[{
skuID:sku.id,
stock:sku.stock,
locationCode:sku.locationCode && sku.locationCode !== 'EMPTY_VALUE' ? sku.locationCode : ''
}]
}
emit('openDialog', {payload,type,name:skuName.name})
}
/*************************************************
* 拒绝改价
*/
function toExamine(skuName: AnyObject, type: any) {
let data = {
status: type,
nameID: skuName.nameID,
storeID: getStorage('storeID'),
auditPrice: skuName.auditUnitPrice,
}
emit('toExamine', data)
}
/***************************************************************
* 获取门店信息
*/
const storeInfo = computed(() => {
return store.state.storeInfo.allStoreInfo
})
</script>
<style lang="scss" scoped>
@import './right-main.scss';
</style>

View File

@@ -0,0 +1,218 @@
<template>
<view class="filter-root"
:class="{'filter-fill':isCheckoutFilter}">
<template v-if="isCheckoutFilter">
<view
class="item item-fill"
:class="{ active: filteActive2 == item.lable }"
v-for="(item, index) in filterData2"
:key="index"
@tap="fliterFn2(item.lable, item.status)"
>{{ item.title }}</view
>
</template>
<template v-else>
<view
class="item item-filter"
:class="{ active: filteActive == item.lable }"
v-for="(item, index) in filterData"
:key="index"
@tap="fliterFn(item, item.status)"
>{{ item.title }}</view
>
</template>
</view>
</template>
<script lang="ts" setup >
import toast from '@/utils/toast'
import { jx_throttles } from '@/utils/tools'
import { ref, watch } from 'vue'
interface propsType {
isCheckoutFilter: boolean
updateStateOk: boolean
}
const props = defineProps<propsType>()
/*************************************************
* 参数1
*/
const filterData = ref<Array<AnyObject>>([
{
title: '全部',
name:'all',
lable: 2,
status: -1,
},
{
title: '可售',
name:'status',
lable: 1,
status: 1,
},
{
title: '不可售',
name:'status',
lable: 0,
status: 0,
},
{
title: '有库存', //库存 1 全查~ 2 有~ 3 无~
name:'stock',
lable:4,
status: 2,
},
{
title: '无库存',
name:'stock',
lable:5,
status: 3,
},
// {
// title: '有货架码',
// name:'locationCode',
// lable:6,
// status:false // 实际上是全部查,感觉没用
// },
{
title: '无货架码',
name:'locationCode',
lable:7,
status:true
},
{
title: '批量',
name:'',
lable: 3,
status: -1,
},
])
/*************************************************
* 参数2
*/
const filterData2 = ref<Array<AnyObject>>([
{
title: '全部',
lable: 2,
status: -1,
},
{
title: '批量',
lable: 3,
status: -1,
},
])
/*************************************************
* emit
*/
const emit = defineEmits<{
(e: 'updateIsSale', data: AnyObject): void
(e: 'updateTowFilter', data: AnyObject): void
}>()
/*************************************************
* 筛选1
*/
const filteActive = ref<number>(2)
function fliterFn(item: AnyObject, status: number | boolean) {
if (filteActive.value == item.lable) return
fliterFn_throttles(item, status)
}
const fliterFn_throttles = jx_throttles({
time: 2000,
success: (item: AnyObject, status: number | boolean) => {
filteActive.value = item.lable
filteActive2.value = item.lable
let data = {
status: status,
lable: item.lable,
name:item.name
}
emit('updateIsSale', data)
},
fail: () => {
toast('老板要点慢点哦')
},
})
/*************************************************
* 筛选2
*/
const filteActive2 = ref<number>(2)
function fliterFn2(lable: number, status: number) {
if (filteActive2.value == lable) return
filteActive2.value = lable
filteActive.value = lable
let data = {
status: status,
lable: lable,
}
emit('updateTowFilter', data)
}
watch(
() => props.updateStateOk,
(val) => {
if (val) {
filteActive2.value = 2
filteActive.value = 2
}
}
)
</script>
<style lang="scss" scoped>
.filter-root {
display: flex;
overflow-x: auto; /* 允许水平方向滚动 */
white-space: nowrap; /* 防止子元素换行 */
align-items: center;
// justify-content: space-around;
box-sizing: border-box;
width: 100%;
border-left: 1rpx solid rgb(223, 223, 223);
height: 90rpx;
background-color: #fff;
box-shadow: 10rpx 0rpx 10rpx rgb(207, 207, 207);
border-bottom: 1rpx solid rgb(224, 224, 224);
padding: 0 10rpx;
.filter-fill{
justify-content: space-around;
}
.item {
flex: 1;
height: 60rpx;
border-radius: 10rpx;
border: 2rpx solid $jx-primary;
color: $jx-primary;
padding: 0 10rpx;
line-height: 60rpx;
text-align: center;
transition: all 0.2s;
margin-left: 10rpx;
}
.item-filter{
width: fit-content;
}
.item-fill{
flex: 1;
}
.item:nth-child(1) {
margin: 0 !important;
}
.active {
background-color: $jx-primary;
color: #fff;
}
}
</style>

View File

@@ -0,0 +1,128 @@
<template>
<view class="search-root">
<view class="add-shopping" @tap="createGoods">
<jx-icon icon="jiahao" color="#4eb331"></jx-icon>
<text>新建</text>
</view>
<uni-search-bar
cancelButton="none"
clearButton="auto"
placeholder="请输入关键字 例如:土豆"
@confirm="confirm"
@input="input"
@clear="clear"
v-model="text"
/>
</view>
</template>
<script lang="ts" setup >
import toast from '@/utils/toast'
import { jx_trembling } from '@/utils/tools'
import { ref, watch } from 'vue'
/*************************************************
* props
*/
interface propsType {
isFilter: string | number
}
const props = defineProps<propsType>()
const text = ref<string>('')
let isInput = false
watch(
() => props.isFilter,
(val) => {
if (val == 'hot' || val == 'audit') {
isInput = true
} else {
isInput = false
}
}
)
/*************************************************
* emit
*/
const emit = defineEmits<{
(e: 'serachShopping', data: string): void
(e: 'clearInpu', data: string): void
(e: 'createGoods'): void
}>()
/*************************************************
* 确定搜索
*/
let watchTimer: any = null
function confirm(e: AnyObject) {
if (isInput) {
let watchTimer = setTimeout(() => {
text.value = ''
clearTimeout(watchTimer)
}, 500)
return toast('该分类暂不支持搜索')
}
emit('serachShopping', e.value)
}
/*************************************************
* 输入框加载
*/
function input(e: string) {
if (isInput) {
let watchTimer = setTimeout(() => {
text.value = ''
clearTimeout(watchTimer)
}, 500)
return toast('该分类暂不支持搜索')
}
trembling(e)
}
const trembling = jx_trembling((e: string) => {
emit('serachShopping', e)
}, 1000)
/*************************************************
* 清空输入框
*/
function clear(e: AnyObject) {
if (isInput) return
emit('clearInpu', e.value)
}
/*************************************************
* 新建商品
*/
function createGoods() {
emit('createGoods')
}
</script>
<style lang="scss">
.search-root {
box-sizing: border-box;
background-color: $jx-primary;
padding: 0 20rpx 2rpx 20rpx;
height: 92rpx;
display: flex;
align-items: center;
justify-content: space-between;
.add-shopping {
width: 80rpx;
height: 80rpx;
background-color: #fff;
font-size: 20rpx;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
border-radius: 50%;
color: $jx-primary;
line-height: 1;
padding: 0;
}
}
</style>