|
@@ -0,0 +1,1983 @@
|
|
|
+<template>
|
|
|
+ <el-container class="goods-edit">
|
|
|
+ <el-header>
|
|
|
+ <el-tabs class="sa-m-t-10" v-model="stepActive" @tab-click="isValidate">
|
|
|
+ <el-tab-pane :name="0">
|
|
|
+ <template #label>
|
|
|
+ <div class="sa-flex" :class="validateData['0'] ? 'is-error' : ''">
|
|
|
+ 基本信息
|
|
|
+ <el-icon v-if="validateData['0']" class="sa-m-l-5">
|
|
|
+ <warning-filled />
|
|
|
+ </el-icon>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane :name="1">
|
|
|
+ <template #label>
|
|
|
+ <div class="sa-flex" :class="validateData['1'] ? 'is-error' : ''">
|
|
|
+ 价格/库存
|
|
|
+ <el-icon v-if="validateData['1']" class="sa-m-l-5">
|
|
|
+ <warning-filled />
|
|
|
+ </el-icon>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane :name="2">
|
|
|
+ <template #label>
|
|
|
+ <div class="sa-flex" :class="validateData['2'] ? 'is-error' : ''">
|
|
|
+ 发货设置
|
|
|
+ <el-icon v-if="validateData['2']" class="sa-m-l-5">
|
|
|
+ <warning-filled />
|
|
|
+ </el-icon>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane :name="3">
|
|
|
+ <template #label>
|
|
|
+ <div class="sa-flex" :class="validateData['3'] ? 'is-error' : ''">
|
|
|
+ 商品参数
|
|
|
+ <el-icon v-if="validateData['3']" class="sa-m-l-5">
|
|
|
+ <warning-filled />
|
|
|
+ </el-icon>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-tab-pane>
|
|
|
+ <el-tab-pane :name="4">
|
|
|
+ <template #label>
|
|
|
+ <div class="sa-flex" :class="validateData['4'] ? 'is-error' : ''">
|
|
|
+ 商品详情
|
|
|
+ <el-icon v-if="validateData['4']" class="sa-m-l-5">
|
|
|
+ <warning-filled />
|
|
|
+ </el-icon>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </el-header>
|
|
|
+ <el-main class="sa-p-t-10">
|
|
|
+ <el-form :model="form.model" :rules="form.rules" ref="formRef0" label-width="100px">
|
|
|
+ <div v-show="stepActive == 0">
|
|
|
+ <div class="goodstype sa-flex sa-m-b-20" @click="goodsModality">
|
|
|
+ <img
|
|
|
+ v-if="!(modal.params.type == 'edit' && form.model.type == 'virtual')"
|
|
|
+ class="goods-type"
|
|
|
+ :class="form.model.type == 'normal' ? 'is-active' : ''"
|
|
|
+ src="/static/images/shop/goods/entity.png"
|
|
|
+ @click="onChangeGoodsType('normal')"
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ v-if="!(modal.params.type == 'edit' && form.model.type == 'normal')"
|
|
|
+ class="goods-type"
|
|
|
+ :class="form.model.type == 'virtual' ? 'is-active' : ''"
|
|
|
+ src="/static/images/shop/goods/virtual.png"
|
|
|
+ @click="onChangeGoodsType('virtual')"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <el-form-item label="商品标题" prop="title">
|
|
|
+ <el-input v-model="form.model.title" placeholder="请输入标题"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="品牌名称" prop="brand_name">
|
|
|
+ <el-input v-model="form.model.brand_name" placeholder="请输入品牌名称"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="副标题">
|
|
|
+ <el-input v-model="form.model.subtitle" placeholder="请输入副标题"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="商品主图" prop="image">
|
|
|
+ <sa-uploader
|
|
|
+ v-model="form.model.image"
|
|
|
+ fileType="image"
|
|
|
+ @success="onSuccess"
|
|
|
+ ></sa-uploader>
|
|
|
+ <div class="warning-title"> 作用于商城列表、分享图片;建议尺寸:750*750 px </div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="轮播图" prop="images">
|
|
|
+ <sa-uploader
|
|
|
+ v-model="form.model.images"
|
|
|
+ :multiple="true"
|
|
|
+ :fileType="['image', 'video']"
|
|
|
+ ></sa-uploader>
|
|
|
+ <div class="warning-title sa-m-l-8">
|
|
|
+ 作用于商品详情顶部轮播显示,<br />轮播图可以拖拽调整顺序
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="商品分类">
|
|
|
+ <div class="sa-w-360">
|
|
|
+ <el-popover
|
|
|
+ popper-class="category-tooltip sa-popper"
|
|
|
+ effect="light"
|
|
|
+ placement="top-start"
|
|
|
+ trigger="click"
|
|
|
+ >
|
|
|
+ <el-tabs v-model="tempCategory.tabActive">
|
|
|
+ <el-tab-pane
|
|
|
+ v-for="tab in category.select"
|
|
|
+ :key="tab"
|
|
|
+ :label="tab.name"
|
|
|
+ :name="tab.id + ''"
|
|
|
+ >
|
|
|
+ <el-cascader-panel
|
|
|
+ v-model="tempCategory.idsArr[tab.id]"
|
|
|
+ :ref="(el) => setCategoryRef(el, tab)"
|
|
|
+ :options="tab.children"
|
|
|
+ :props="{
|
|
|
+ multiple: true,
|
|
|
+ checkStrictly: true,
|
|
|
+ value: 'id',
|
|
|
+ label: 'name',
|
|
|
+ children: 'children',
|
|
|
+ emitPath: false,
|
|
|
+ }"
|
|
|
+ @change="onChangeCategoryIds"
|
|
|
+ ></el-cascader-panel>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ <template #reference>
|
|
|
+ <div class="category-tag-wrap">
|
|
|
+ <el-tag
|
|
|
+ v-for="(value, key) in tempCategory.label"
|
|
|
+ :key="key"
|
|
|
+ type="info"
|
|
|
+ closable
|
|
|
+ @close.stop="onDeleteCategoryIds(key)"
|
|
|
+ >{{ value }}</el-tag
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="category-tag-wrap-suffix"
|
|
|
+ :class="JSON.stringify(tempCategory.label) == '{}' ? '' : 'is-active'"
|
|
|
+ >
|
|
|
+ <el-icon class="arrow-down">
|
|
|
+ <arrow-down />
|
|
|
+ </el-icon>
|
|
|
+ <el-icon class="circle-close" @click.stop="onClearCategoryIds">
|
|
|
+ <circle-close />
|
|
|
+ </el-icon>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ <el-button
|
|
|
+ v-auth="'shop.admin.category.add'"
|
|
|
+ class="sa-m-l-12"
|
|
|
+ type="primary"
|
|
|
+ link
|
|
|
+ @click="onAddCategory"
|
|
|
+ >添加商品分类</el-button
|
|
|
+ >
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="商品排序">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.weigh"
|
|
|
+ placeholder="请输入商品排序"
|
|
|
+ class="sa-w-160"
|
|
|
+ type="number"
|
|
|
+ :min="0"
|
|
|
+ step-strictly
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="限购类型">
|
|
|
+ <el-radio-group v-model="form.model.limit_type">
|
|
|
+ <el-radio label="none">不限购</el-radio>
|
|
|
+ <el-radio label="daily">每日</el-radio>
|
|
|
+ <el-radio label="all">累计</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="限购数量" v-if="form.model.limit_type != 'none'">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.limit_num"
|
|
|
+ placeholder="请输入限购数量"
|
|
|
+ class="sa-w-160"
|
|
|
+ :min="0"
|
|
|
+ type="number"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="来源">
|
|
|
+ <el-radio-group v-model="form.model.source">
|
|
|
+ <el-radio label="self">自建</el-radio>
|
|
|
+ <el-radio label="linkedmall">LinkedMall</el-radio>
|
|
|
+ <el-radio label="zkh">震坤行</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="商品编码">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.out_item_code"
|
|
|
+ placeholder="请输入商品编码"
|
|
|
+ class="sa-w-360"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="SPU ID">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.out_code"
|
|
|
+ placeholder="请输入SPU ID"
|
|
|
+ class="sa-w-360"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="商品状态">
|
|
|
+ <el-radio-group v-model="form.model.status">
|
|
|
+ <el-radio label="up">上架</el-radio>
|
|
|
+ <el-radio label="hidden">隐藏</el-radio>
|
|
|
+ <el-radio label="down">下架</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ <el-form :model="form.model" :rules="form.rules" ref="formRef1" label-width="100px">
|
|
|
+ <div v-show="stepActive == 1">
|
|
|
+ <el-form-item label="商品规格">
|
|
|
+ <el-radio-group
|
|
|
+ v-model="form.model.is_sku"
|
|
|
+ :disabled="props.modal.params.type == 'edit'"
|
|
|
+ >
|
|
|
+ <el-radio :label="0">单规格</el-radio>
|
|
|
+ <el-radio :label="1">多规格</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ <div class="warning-title">
|
|
|
+ 如商品参与了拼团、秒杀、积分等活动,切换规格,可能导致活动规格不可用
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ <template v-if="form.model.is_sku == 1">
|
|
|
+ <!-- 操作 -->
|
|
|
+ <div class="sku-wrap">
|
|
|
+ <div class="sku" v-for="(s, k) in form.model.skus" :key="k">
|
|
|
+ <div class="sku-key sa-flex sa-row-between">
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div class="sa-m-r-16">规格名称</div>
|
|
|
+ <el-input
|
|
|
+ v-model="s.name"
|
|
|
+ placeholder="请输入规格名称"
|
|
|
+ class="sku-key-input"
|
|
|
+ ></el-input>
|
|
|
+ </div>
|
|
|
+ <el-icon @click="deleteMainSku(k)" class="sku-key-icon">
|
|
|
+ <CircleCloseFilled />
|
|
|
+ </el-icon>
|
|
|
+ </div>
|
|
|
+ <div class="sku-value sa-flex sa-flex-wrap">
|
|
|
+ <div class="sku-value-title sa-m-r-16 sa-m-b-16 sa-flex"> 规格值 </div>
|
|
|
+ <div v-for="(sc, c) in s.children" :key="c" class="sku-value-box sa-m-b-16">
|
|
|
+ <el-input
|
|
|
+ v-model="sc.name"
|
|
|
+ placeholder="请输入规格值"
|
|
|
+ class="sku-value-input"
|
|
|
+ ></el-input>
|
|
|
+ <el-icon @click="deleteChildrenSku(k, c)" class="sku-value-icon">
|
|
|
+ <CircleCloseFilled />
|
|
|
+ </el-icon>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ @click="addChildrenSku(k)"
|
|
|
+ class="sku-value-add sa-m-r-24 sa-m-b-16 sa-flex cursor-pointer"
|
|
|
+ >
|
|
|
+ 添加规格值
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="sku-tools sa-flex">
|
|
|
+ <el-button type="primary" class="add" @click="addMainSku">+ 添加规格</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 表格 -->
|
|
|
+ <div class="sku-table-wrap sa-m-b-20">
|
|
|
+ <table class="sku-table" rules="all">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <template v-for="(item, i) in form.model.skus" :key="i">
|
|
|
+ <th v-if="item.children.length">{{ item.name }}</th>
|
|
|
+ </template>
|
|
|
+ <th>图片</th>
|
|
|
+ <th>
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div class="th-title">价格(元)</div>
|
|
|
+ <el-popover
|
|
|
+ placement="top"
|
|
|
+ width="160"
|
|
|
+ v-model:visible="allEditPopover.price"
|
|
|
+ trigger="click"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <el-icon class="batch-icon">
|
|
|
+ <Edit />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ <el-input
|
|
|
+ v-model="allEditDatas"
|
|
|
+ placeholder="请输入价格"
|
|
|
+ size="small"
|
|
|
+ class="alledit-input"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ ></el-input>
|
|
|
+ <div class="sa-flex sa-row-right">
|
|
|
+ <el-button
|
|
|
+ class="is-link"
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ @click="allEditData('price', 'cancel')"
|
|
|
+ >取消</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click="allEditData('price', 'define')"
|
|
|
+ >确定</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </th>
|
|
|
+ <th>
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div class="th-title">划线价格</div>
|
|
|
+ <el-popover
|
|
|
+ placement="top"
|
|
|
+ width="160"
|
|
|
+ v-model:visible="allEditPopover.original_price"
|
|
|
+ trigger="click"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <el-icon class="batch-icon">
|
|
|
+ <Edit />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ <el-input
|
|
|
+ v-model="allEditDatas"
|
|
|
+ placeholder="请输入划线价格"
|
|
|
+ size="small"
|
|
|
+ class="alledit-input"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ ></el-input>
|
|
|
+ <div class="sa-flex sa-row-right">
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ class="is-link"
|
|
|
+ @click="allEditData('original_price', 'cancel')"
|
|
|
+ >取消</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click="allEditData('original_price', 'define')"
|
|
|
+ >确定</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </th>
|
|
|
+ <th>
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div class="th-title">成本价</div>
|
|
|
+ <el-popover
|
|
|
+ placement="top"
|
|
|
+ width="160"
|
|
|
+ v-model:visible="allEditPopover.cost_price"
|
|
|
+ trigger="click"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <el-icon class="batch-icon">
|
|
|
+ <Edit />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ <el-input
|
|
|
+ v-model="allEditDatas"
|
|
|
+ placeholder="请输入成本价"
|
|
|
+ size="small"
|
|
|
+ class="alledit-input"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ ></el-input>
|
|
|
+ <div class="sa-flex sa-row-right">
|
|
|
+ <el-button
|
|
|
+ class="is-link"
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ @click="allEditData('cost_price', 'cancel')"
|
|
|
+ >取消</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click="allEditData('cost_price', 'define')"
|
|
|
+ >确定</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </th>
|
|
|
+ <th>LM库存</th>
|
|
|
+ <th>库存(件)</th>
|
|
|
+ <th>库存预警(件)</th>
|
|
|
+ <th>
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div class="th-title">重量(kg)</div>
|
|
|
+ <el-popover
|
|
|
+ placement="top"
|
|
|
+ width="160"
|
|
|
+ v-model:visible="allEditPopover.weight"
|
|
|
+ trigger="click"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <el-icon class="batch-icon">
|
|
|
+ <Edit />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ <el-input
|
|
|
+ v-model="allEditDatas"
|
|
|
+ placeholder="请输入重量"
|
|
|
+ size="small"
|
|
|
+ class="alledit-input"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ ></el-input>
|
|
|
+ <div class="sa-flex sa-row-right">
|
|
|
+ <el-button
|
|
|
+ class="is-link"
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ @click="allEditData('weight', 'cancel')"
|
|
|
+ >取消</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click="allEditData('weight', 'define')"
|
|
|
+ >确定</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </th>
|
|
|
+ <th>
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div class="th-title">规格编码</div>
|
|
|
+ <el-popover
|
|
|
+ placement="top"
|
|
|
+ width="160"
|
|
|
+ v-model:visible="allEditPopover.sn"
|
|
|
+ trigger="click"
|
|
|
+ >
|
|
|
+ <template #reference>
|
|
|
+ <el-icon class="batch-icon">
|
|
|
+ <Edit />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ <el-input
|
|
|
+ v-model="allEditDatas"
|
|
|
+ placeholder="请输入规格编码"
|
|
|
+ size="small"
|
|
|
+ class="alledit-input"
|
|
|
+ type="number"
|
|
|
+ ></el-input>
|
|
|
+ <div class="sa-flex sa-row-right">
|
|
|
+ <el-button
|
|
|
+ class="is-link"
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ @click="allEditData('sn', 'cancel')"
|
|
|
+ >取消</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click="allEditData('sn', 'define')"
|
|
|
+ >确定</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </th>
|
|
|
+ <th>商品状态</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr v-for="(item, i) in form.model.sku_prices" :key="i">
|
|
|
+ <template v-for="(v, j) in item.goods_sku_text" :key="j">
|
|
|
+ <td>
|
|
|
+ <span class="th-center">{{ v }}</span>
|
|
|
+ </td>
|
|
|
+ </template>
|
|
|
+ <td class="image">
|
|
|
+ <sa-uploader v-model="item.image" fileType="image" size="28"></sa-uploader>
|
|
|
+ </td>
|
|
|
+ <td>
|
|
|
+ <el-input
|
|
|
+ v-model="item.price"
|
|
|
+ placeholder="请输入价格"
|
|
|
+ size="small"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ ></el-input>
|
|
|
+ </td>
|
|
|
+ <td>
|
|
|
+ <el-input
|
|
|
+ v-model="item.original_price"
|
|
|
+ placeholder="请输入划线价格"
|
|
|
+ size="small"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ ></el-input>
|
|
|
+ </td>
|
|
|
+ <td>
|
|
|
+ <el-input
|
|
|
+ v-model="item.cost_price"
|
|
|
+ placeholder="请输入成本价"
|
|
|
+ size="small"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ ></el-input>
|
|
|
+ </td>
|
|
|
+ <td class="stock">
|
|
|
+ <span>
|
|
|
+ {{ item.fuzzy_quantity || '暂无' }}
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
+ <td class="stock">
|
|
|
+ <el-input
|
|
|
+ v-model="item.stock"
|
|
|
+ placeholder="请输入库存"
|
|
|
+ size="small"
|
|
|
+ v-if="props.modal.params.type == 'add'"
|
|
|
+ type="number"
|
|
|
+ :step="1"
|
|
|
+ :min="0"
|
|
|
+ ></el-input>
|
|
|
+ <span v-if="props.modal.params.type == 'edit'">
|
|
|
+ {{ item.stock }}
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
+ <td class="stock_warning">
|
|
|
+ <div class="sa-flex">
|
|
|
+ <el-switch
|
|
|
+ v-model="item.stock_warning_switch"
|
|
|
+ @change="changeStockWarningSwitch(i)"
|
|
|
+ class="sku-stock-switch"
|
|
|
+ />
|
|
|
+ <span v-if="!item.stock_warning_switch">使用默认库存预警</span>
|
|
|
+ <el-input
|
|
|
+ v-model="item.stock_warning"
|
|
|
+ placeholder="请输入"
|
|
|
+ size="small"
|
|
|
+ v-if="item.stock_warning_switch"
|
|
|
+ type="number"
|
|
|
+ :step="1"
|
|
|
+ :min="0"
|
|
|
+ ></el-input>
|
|
|
+ </div>
|
|
|
+ </td>
|
|
|
+ <td>
|
|
|
+ <el-input
|
|
|
+ v-model="item.weight"
|
|
|
+ placeholder="请输入"
|
|
|
+ size="small"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ ></el-input>
|
|
|
+ </td>
|
|
|
+ <td class="sn">
|
|
|
+ <el-input v-model="item.sn" placeholder="请输入" size="small"></el-input>
|
|
|
+ </td>
|
|
|
+ <td>
|
|
|
+ <el-select v-model="item.status" placeholder="请选择" size="small">
|
|
|
+ <el-option label="上架" value="up"></el-option>
|
|
|
+ <el-option label="下架" value="down"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div v-if="form.model.is_sku == 0">
|
|
|
+ <el-form-item label="售卖价格" prop="price">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.price"
|
|
|
+ placeholder="请输入售卖价格"
|
|
|
+ class="sa-w-160"
|
|
|
+ type="number"
|
|
|
+ :min="0"
|
|
|
+ >
|
|
|
+ <template #append>元</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="划线价格">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.original_price"
|
|
|
+ placeholder="请输入划线价格"
|
|
|
+ class="sa-w-160"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ >
|
|
|
+ <template #append>元</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="成本价格">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.cost_price"
|
|
|
+ placeholder="请输入成本价格"
|
|
|
+ class="sa-w-160"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ >
|
|
|
+ <template #append>元</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="库存类型">
|
|
|
+ <el-radio-group v-model="form.model.stock_show_type">
|
|
|
+ <el-radio label="exact">
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div>精确显示</div>
|
|
|
+ <el-popover placement="right" title :width="244" trigger="hover">
|
|
|
+ <template #reference>
|
|
|
+ <div class="icon-warning">
|
|
|
+ <img src="/static/images/shop/category/warning.png" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="sale-hover-img">
|
|
|
+ <img src="/static/images/shop/goods/stock2.png" />
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </el-radio>
|
|
|
+ <el-radio label="sketchy">
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div>粗略显示</div>
|
|
|
+ <el-popover placement="right" title :width="244" trigger="hover">
|
|
|
+ <template #reference>
|
|
|
+ <div class="icon-warning">
|
|
|
+ <img src="/static/images/shop/category/warning.png" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="sale-hover-img">
|
|
|
+ <img src="/static/images/shop/goods/stock1.png" />
|
|
|
+ </div>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="商品库存">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.stock"
|
|
|
+ placeholder="请输入商品库存"
|
|
|
+ class="sa-w-160"
|
|
|
+ type="number"
|
|
|
+ :step="1"
|
|
|
+ :min="0"
|
|
|
+ :disabled="props.modal.params.type == 'edit'"
|
|
|
+ >
|
|
|
+ <template #append>件</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="库存预警">
|
|
|
+ <el-switch v-model="stockWarning" />
|
|
|
+ <div class="warning-title"> 库存预警在未开启的状态下,使用默认库存预警 </div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item v-if="stockWarning" label="预警数量">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.stock_warning"
|
|
|
+ placeholder="请输入库存预警数量"
|
|
|
+ class="sa-w-160"
|
|
|
+ >
|
|
|
+ <template #append>件</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ <el-form-item label="销量类型">
|
|
|
+ <el-radio-group v-model="form.model.sales_show_type">
|
|
|
+ <el-radio label="exact">
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div>精确显示</div>
|
|
|
+ <el-popover placement="right" :width="244" trigger="hover">
|
|
|
+ <img class="exact" src="/static/images/shop/goods/sales2.png" />
|
|
|
+ <template #reference>
|
|
|
+ <div class="icon-warning">
|
|
|
+ <img src="/static/images/shop/category/warning.png" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </el-radio>
|
|
|
+ <el-radio label="sketchy">
|
|
|
+ <div class="sa-flex">
|
|
|
+ <div>粗略显示</div>
|
|
|
+ <el-popover placement="right" :width="244" trigger="hover">
|
|
|
+ <img class="sketchy" src="/static/images/shop/goods/sales1.png" />
|
|
|
+ <template #reference>
|
|
|
+ <div class="icon-warning">
|
|
|
+ <img src="/static/images/shop/category/warning.png" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-popover>
|
|
|
+ </div>
|
|
|
+ </el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="虚拟销量">
|
|
|
+ <div class="sa-form-wrap">
|
|
|
+ <el-input
|
|
|
+ class="sa-w-360"
|
|
|
+ v-model="form.model.show_sales"
|
|
|
+ placeholder="请输入虚拟销量"
|
|
|
+ type="number"
|
|
|
+ :min="0"
|
|
|
+ >
|
|
|
+ </el-input>
|
|
|
+ <div class="warning"> 可以提高商品的销量排行榜,鼓励用户下单 </div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ <div v-if="form.model.is_sku == 0">
|
|
|
+ <el-form-item label="商品重量">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.weight"
|
|
|
+ placeholder="请输入商品重量"
|
|
|
+ class="sa-w-160"
|
|
|
+ type="number"
|
|
|
+ :step="0.01"
|
|
|
+ :min="0"
|
|
|
+ :precision="2"
|
|
|
+ >
|
|
|
+ <template #append>kg</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <!-- <el-form-item label="商品编号">
|
|
|
+ <el-input
|
|
|
+ v-model="form.model.sn"
|
|
|
+ placeholder="请输入商品编号"
|
|
|
+ class="sa-w-160"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item> -->
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ <el-form :model="form.model" :rules="form.rules" ref="formRef2" label-width="100px">
|
|
|
+ <div v-show="stepActive == 2">
|
|
|
+ <template v-if="form.model.type == 'normal'">
|
|
|
+ <el-form-item label="配送方式">
|
|
|
+ <el-radio-group v-model="form.model.dispatch_type">
|
|
|
+ <el-radio label="express">物流快递</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item v-if="form.model.dispatch_type" label="物流快递" prop="dispatch_id">
|
|
|
+ <el-select
|
|
|
+ class="sa-w-360"
|
|
|
+ v-model="form.model.dispatch_id"
|
|
|
+ placeholder="请选择物流快递"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in dispatch.select"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ <el-button
|
|
|
+ v-auth="'shop.admin.dispatch.dispatch.add'"
|
|
|
+ class="sa-m-l-12"
|
|
|
+ type="primary"
|
|
|
+ link
|
|
|
+ @click="onAddDispatch('express')"
|
|
|
+ >
|
|
|
+ 添加物流快递
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="货到付款">
|
|
|
+ <el-switch
|
|
|
+ v-model="form.model.is_offline"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
+ ></el-switch>
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+ <template v-if="form.model.type == 'virtual'">
|
|
|
+ <el-form-item label="配送方式">
|
|
|
+ <el-radio-group v-model="form.model.dispatch_type" @change="onChangeDispatchType">
|
|
|
+ <el-radio label="autosend">自动发货</el-radio>
|
|
|
+ <el-radio label="custom"
|
|
|
+ >手动发货
|
|
|
+ <el-popover popper-class="sa-popper" trigger="hover">
|
|
|
+ 在订单管理,手动对订单进行发货,发货时填写自定义发货内容
|
|
|
+ <template #reference>
|
|
|
+ <el-icon class="warning">
|
|
|
+ <warning />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ </el-popover>
|
|
|
+ </el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item
|
|
|
+ v-if="form.model.dispatch_type == 'autosend'"
|
|
|
+ label="自动发货"
|
|
|
+ prop="dispatch_id"
|
|
|
+ >
|
|
|
+ <el-select
|
|
|
+ class="sa-w-360"
|
|
|
+ v-model="form.model.dispatch_id"
|
|
|
+ placeholder="请选择自动发货"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in dispatch.select"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ <el-button
|
|
|
+ v-auth="'shop.admin.dispatch.dispatch.add'"
|
|
|
+ class="sa-m-l-12"
|
|
|
+ type="primary"
|
|
|
+ link
|
|
|
+ @click="onAddDispatch('autosend')"
|
|
|
+ >
|
|
|
+ 添加自动发货
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ <el-form :model="form.model" :rules="form.rules" ref="formRef3" label-width="100px">
|
|
|
+ <div v-show="stepActive == 3">
|
|
|
+ <el-form-item label="服务保障" prop="service_ids" class="server">
|
|
|
+ <el-select v-model="form.model.service_ids" placeholder="请选择服务保障" multiple>
|
|
|
+ <el-option
|
|
|
+ v-for="item in service.select"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ <el-button
|
|
|
+ v-auth="'shop.admin.goods.service.add'"
|
|
|
+ class="sa-m-l-12"
|
|
|
+ type="primary"
|
|
|
+ link
|
|
|
+ @click="createService"
|
|
|
+ >
|
|
|
+ 添加标签
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="参数详情">
|
|
|
+ <div class="sa-template-wrap">
|
|
|
+ <div class="title sa-flex">
|
|
|
+ <div class="key">参数名称</div>
|
|
|
+ <div class="value">内容</div>
|
|
|
+ <div class="oper">操作</div>
|
|
|
+ </div>
|
|
|
+ <sa-draggable
|
|
|
+ v-model="form.model.params"
|
|
|
+ :animation="300"
|
|
|
+ handle=".sortable-drag"
|
|
|
+ item-key="element"
|
|
|
+ >
|
|
|
+ <template #item="{ element, index }">
|
|
|
+ <div class="item">
|
|
|
+ <el-form-item
|
|
|
+ class="key"
|
|
|
+ :prop="'params.' + index + '.title'"
|
|
|
+ :rules="templateRules.title"
|
|
|
+ >
|
|
|
+ <el-input placeholder="请输入名称" v-model="element.title"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item
|
|
|
+ class="value"
|
|
|
+ :prop="'params.' + index + '.content'"
|
|
|
+ :rules="templateRules.content"
|
|
|
+ >
|
|
|
+ <el-input placeholder="请输入标识" v-model="element.content"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item class="oper">
|
|
|
+ <el-button @click="deleteTemplate(index)" type="danger" class="is-link" plain
|
|
|
+ >删除</el-button
|
|
|
+ >
|
|
|
+ <sa-svg class="sa-m-l-8 sortable-drag" name="sa-round"></sa-svg>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </sa-draggable>
|
|
|
+ <el-button @click="addTemplate()" class="sa-m-l-16" type="primary" plain icon="Plus"
|
|
|
+ >添加</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ <el-form :model="form.model" :rules="form.rules" ref="formRef4" label-width="100px">
|
|
|
+ <div v-show="stepActive == 4">
|
|
|
+ <el-form-item label="图文详情">
|
|
|
+ <div>
|
|
|
+ <sa-editor v-model:content="form.model.content"></sa-editor>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ </el-main>
|
|
|
+ <el-footer class="sa-footer--submit">
|
|
|
+ <el-button
|
|
|
+ v-if="props.modal.params.type == 'add' || props.modal.params.type == 'copy'"
|
|
|
+ v-auth="'shop.admin.goods.goods.add'"
|
|
|
+ v-throttle
|
|
|
+ type="primary"
|
|
|
+ @click="confirm"
|
|
|
+ >保存</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ v-if="props.modal.params.type == 'edit'"
|
|
|
+ v-auth="'shop.admin.goods.goods.edit'"
|
|
|
+ v-throttle
|
|
|
+ type="primary"
|
|
|
+ @click="confirm"
|
|
|
+ >更新</el-button
|
|
|
+ >
|
|
|
+ </el-footer>
|
|
|
+ </el-container>
|
|
|
+</template>
|
|
|
+<script setup>
|
|
|
+ import { onMounted, reactive, ref, unref, watch, nextTick, getCurrentInstance } from 'vue';
|
|
|
+ import { api } from '../goods.service';
|
|
|
+ import { api as categoryApi } from '@/app/shop/admin/category/category.service';
|
|
|
+ import { api as dispatchApi } from '@/app/shop/admin/dispatch/dispatch.service';
|
|
|
+ import { isArray, isEmpty, cloneDeep } from 'lodash';
|
|
|
+ import SaEditor from '@/sheep/components/sa-editor/sa-editor.vue';
|
|
|
+ import SaDraggable from 'vuedraggable';
|
|
|
+ import { useModal } from '@/sheep/hooks';
|
|
|
+ import CategoryEdit from '../../category/edit.vue';
|
|
|
+ import DispatchEdit from '../../dispatch/edit.vue';
|
|
|
+ import ServiceEdit from '../service/edit.vue';
|
|
|
+ import { checkAuth } from '@/sheep/directives/auth';
|
|
|
+
|
|
|
+ const { proxy } = getCurrentInstance();
|
|
|
+
|
|
|
+ const emit = defineEmits(['modalCallBack']);
|
|
|
+ const props = defineProps({
|
|
|
+ modal: {
|
|
|
+ type: Object,
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ const tagWrapper = ref(null);
|
|
|
+ const tagInput = ref(null);
|
|
|
+ const updateStyle = () => {
|
|
|
+ const inputInner = tagInput.value?.input;
|
|
|
+ const tagWrapperEl = tagWrapper.value;
|
|
|
+ if (tagWrapperEl) {
|
|
|
+ const inputInitialHeight = 32;
|
|
|
+ const { offsetHeight } = tagWrapperEl;
|
|
|
+ const height = !isEmpty(tempCategory.label)
|
|
|
+ ? `${Math.max(offsetHeight + 6, inputInitialHeight)}px`
|
|
|
+ : `${inputInitialHeight}px`;
|
|
|
+ inputInner.style.height = height;
|
|
|
+ updatePopperPosition();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const tooltipRef = ref();
|
|
|
+ const updatePopperPosition = () => {
|
|
|
+ nextTick(() => {
|
|
|
+ tooltipRef.value?.updatePopper();
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ // 添加 编辑 form
|
|
|
+ let formRef = ref(null);
|
|
|
+ const stockWarning = ref(false);
|
|
|
+ const form = reactive({
|
|
|
+ model: {
|
|
|
+ type: 'normal', // 商品类型
|
|
|
+ title: '',
|
|
|
+ brand_name: '',
|
|
|
+ subtitle: '',
|
|
|
+ category_ids: '',
|
|
|
+ category_ids_arr: [],
|
|
|
+ image: '',
|
|
|
+ images: [],
|
|
|
+ params: [],
|
|
|
+ content: '',
|
|
|
+ original_price: 0,
|
|
|
+ price: '',
|
|
|
+ cost_price: '',
|
|
|
+ is_sku: 0,
|
|
|
+ limit_type: 'none',
|
|
|
+ limit_num: 0,
|
|
|
+ likes: '',
|
|
|
+ views: 0,
|
|
|
+ sales: '',
|
|
|
+ stock: '',
|
|
|
+ stock_warning: '',
|
|
|
+ stock_warning_switch: false,
|
|
|
+ sales_show_type: 'exact',
|
|
|
+ stock_show_type: 'exact',
|
|
|
+ show_sales: 0,
|
|
|
+ service_ids: [],
|
|
|
+ dispatch_type: 'express',
|
|
|
+ dispatch_id: '',
|
|
|
+ is_offline: 0,
|
|
|
+ status: 'up',
|
|
|
+ weigh: 0,
|
|
|
+ weight: '',
|
|
|
+ source: 'self', // 来源,默认为自建
|
|
|
+ out_code: '', // 外部编码
|
|
|
+ out_item_code: '', //
|
|
|
+ skus: [
|
|
|
+ {
|
|
|
+ id: 0,
|
|
|
+ name: '',
|
|
|
+ goods_id: 0,
|
|
|
+ parent_id: 0,
|
|
|
+ weigh: 0,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ id: 0,
|
|
|
+ name: '',
|
|
|
+ goods_id: 0,
|
|
|
+ parent_id: 0,
|
|
|
+ weigh: 0,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ sku_prices: [],
|
|
|
+ },
|
|
|
+ rules: {
|
|
|
+ image: [{ required: true, message: '请选择商品主图', trigger: 'blur' }],
|
|
|
+ images: [{ required: true, message: '请选择轮播图', trigger: 'blur' }],
|
|
|
+ title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
|
|
|
+ category_ids: [{ required: true, message: '请输入商品分类', trigger: 'blur' }],
|
|
|
+ price: [{ required: true, message: '请输入售卖价格', trigger: 'blur' }],
|
|
|
+ dispatch_id: [{ required: true, message: '请选择发货模板', trigger: 'blur' }],
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const loading = ref(false);
|
|
|
+ //步骤条
|
|
|
+ const stepActive = ref(0);
|
|
|
+ const goback = () => {
|
|
|
+ stepActive.value--;
|
|
|
+ nextTick(() => updateStyle());
|
|
|
+ };
|
|
|
+ const next = () => {
|
|
|
+ unref(formRef).validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ stepActive.value++;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ const validateData = ref({
|
|
|
+ 0: 0,
|
|
|
+ 1: 0,
|
|
|
+ 2: 0,
|
|
|
+ 3: 0,
|
|
|
+ 4: 0,
|
|
|
+ });
|
|
|
+ function isValidate() {
|
|
|
+ nextTick(async () => {
|
|
|
+ for (var key in validateData.value) {
|
|
|
+ await proxy.$refs[`formRef${key}`].validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ validateData.value[key] = 0;
|
|
|
+ } else {
|
|
|
+ validateData.value[key] = 1;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ //商品形式
|
|
|
+ const goodsModality = () => {
|
|
|
+ let modality = true;
|
|
|
+ };
|
|
|
+ // 获取详情
|
|
|
+ async function getDetail(id) {
|
|
|
+ loading.value = true;
|
|
|
+ const { error, data } = await api.goods.detail(id);
|
|
|
+ if (error === 0) {
|
|
|
+ form.model = data;
|
|
|
+ form.model.params = isArray(form.model.params) ? form.model.params : [];
|
|
|
+ form.model.sku_prices = isArray(form.model.sku_prices) ? form.model.sku_prices : [];
|
|
|
+ form.model.price = Number(data.price);
|
|
|
+ if (form.model.dispatch_id) {
|
|
|
+ dispatchCheck.value = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 商品分类
|
|
|
+ initCategoryIds();
|
|
|
+
|
|
|
+ if (form.model.is_sku == 0) {
|
|
|
+ if (form.model.stock_warning > 0) {
|
|
|
+ stockWarning.value = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (form.model.is_sku == 1) {
|
|
|
+ getInit();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!form.model.skus) {
|
|
|
+ form.model.skus = [];
|
|
|
+ getInit();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let categoryRef = {};
|
|
|
+ const setCategoryRef = (el, tab) => {
|
|
|
+ if (el) {
|
|
|
+ categoryRef[tab.id + '-' + tab.name] = el;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const tempCategory = reactive({
|
|
|
+ tabActive: '',
|
|
|
+ idsArr: {},
|
|
|
+ label: {},
|
|
|
+ });
|
|
|
+ function initCategoryIds() {
|
|
|
+ tempCategory.idsArr = {};
|
|
|
+ form.model.category_ids_arr.forEach((item) => {
|
|
|
+ if (tempCategory.idsArr[item[0]]) {
|
|
|
+ tempCategory.idsArr[item[0]].push(item.pop());
|
|
|
+ } else {
|
|
|
+ tempCategory.idsArr[item[0]] = [];
|
|
|
+ tempCategory.idsArr[item[0]].push(item.pop());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ onChangeCategoryIds();
|
|
|
+ }
|
|
|
+ function onChangeCategoryIds() {
|
|
|
+ nextTick(() => {
|
|
|
+ tempCategory.label = {};
|
|
|
+ for (var key in categoryRef) {
|
|
|
+ let keyArr = key.split('-');
|
|
|
+ if (categoryRef[key].checkedNodes.length > 0) {
|
|
|
+ categoryRef[key].checkedNodes.forEach((row) => {
|
|
|
+ tempCategory.label[row.value] = keyArr[1] + '/' + row.pathLabels.join('/');
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ function onDeleteCategoryIds(id) {
|
|
|
+ delete tempCategory.label[id];
|
|
|
+ let idx = -1;
|
|
|
+ for (var key in tempCategory.idsArr) {
|
|
|
+ tempCategory.idsArr[key].forEach((item, index) => {
|
|
|
+ if (item == id) {
|
|
|
+ idx = index;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (idx != -1) {
|
|
|
+ tempCategory.idsArr[key].splice(idx, 1);
|
|
|
+ idx = -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ function onClearCategoryIds() {
|
|
|
+ tempCategory.idsArr = {};
|
|
|
+ tempCategory.label = {};
|
|
|
+ }
|
|
|
+ const category = reactive({
|
|
|
+ select: [],
|
|
|
+ });
|
|
|
+ async function getCategorySelect() {
|
|
|
+ ({ data: category.select } = await categoryApi.select());
|
|
|
+ tempCategory.tabActive = category.select.length ? category.select[0].id + '' : '';
|
|
|
+ }
|
|
|
+ //新建分类
|
|
|
+ function onAddCategory() {
|
|
|
+ useModal(
|
|
|
+ CategoryEdit,
|
|
|
+ { title: '新建', type: 'add' },
|
|
|
+ {
|
|
|
+ confirm: () => {
|
|
|
+ getCategorySelect();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ const isEditInit = ref(false);
|
|
|
+ function getInit() {
|
|
|
+ let tempIdArr = {};
|
|
|
+ for (let i in form.model.skus) {
|
|
|
+ // 为每个 规格增加当前页面自增计数器,比较唯一用
|
|
|
+ form.model.skus[i]['temp_id'] = countId.value++;
|
|
|
+ for (let j in form.model.skus[i]['children']) {
|
|
|
+ // 为每个 规格项增加当前页面自增计数器,比较唯一用
|
|
|
+ form.model.skus[i]['children'][j]['temp_id'] = countId.value++;
|
|
|
+ // 记录规格项真实 id 对应的 临时 id
|
|
|
+ tempIdArr[form.model.skus[i]['children'][j]['id']] =
|
|
|
+ form.model.skus[i]['children'][j]['temp_id'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (var i = 0; i < form.model.sku_prices.length; i++) {
|
|
|
+ let tempSkuPrice = form.model.sku_prices[i];
|
|
|
+ tempSkuPrice['temp_id'] = i + 1;
|
|
|
+ // 将真实 id 数组,循环,找到对应的临时 id 组合成数组
|
|
|
+ tempSkuPrice['goods_sku_temp_ids'] = [];
|
|
|
+ let goods_sku_id_arr = tempSkuPrice['goods_sku_ids'].split(',');
|
|
|
+ for (let ids of goods_sku_id_arr) {
|
|
|
+ tempSkuPrice['goods_sku_temp_ids'].push(tempIdArr[ids]);
|
|
|
+ }
|
|
|
+ form.model.sku_prices[i] = tempSkuPrice;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (props.modal.params.type == 'copy') {
|
|
|
+ for (let i in form.model.skus) {
|
|
|
+ // 为每个 规格增加当前页面自增计数器,比较唯一用
|
|
|
+ form.model.skus[i].id = 0;
|
|
|
+ for (let j in form.model.skus[i]['children']) {
|
|
|
+ form.model.skus[i]['children'][j].id = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (form.model.sku_prices.length > 0) {
|
|
|
+ form.model.sku_prices.forEach((si) => {
|
|
|
+ si.stock_warning_switch = false;
|
|
|
+ if (si.stock_warning || si.stock_warning == 0) {
|
|
|
+ si.stock_warning_switch = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ loading.value = false;
|
|
|
+ setTimeout(() => {
|
|
|
+ isEditInit.value = true;
|
|
|
+ }, 200);
|
|
|
+ }
|
|
|
+ //添加主规格
|
|
|
+ const skuModal = ref('');
|
|
|
+ const countId = ref(1);
|
|
|
+ function addMainSku() {
|
|
|
+ form.model.skus.push({
|
|
|
+ id: 0,
|
|
|
+ temp_id: countId.value++,
|
|
|
+ name: skuModal.value,
|
|
|
+ pid: 0,
|
|
|
+ children: [],
|
|
|
+ });
|
|
|
+ skuModal.value = '';
|
|
|
+ buildSkuPriceTable();
|
|
|
+ }
|
|
|
+ function deleteMainSku(k) {
|
|
|
+ let data = form.model.skus[k];
|
|
|
+
|
|
|
+ // 删除主规格
|
|
|
+ form.model.skus.splice(k, 1);
|
|
|
+
|
|
|
+ // 如果当前删除的主规格存在子规格,则清空 skuPrice, 不存在子规格则不清空
|
|
|
+ if (data.children.length > 0) {
|
|
|
+ form.model.sku_prices = []; // 规格大变化,清空skuPrice
|
|
|
+ isResetSku.value = 1; // 重置规格
|
|
|
+ }
|
|
|
+ buildSkuPriceTable();
|
|
|
+ }
|
|
|
+ //添加子规格
|
|
|
+ const isResetSku = ref(0);
|
|
|
+ const childrenModal = [];
|
|
|
+ function addChildrenSku(k) {
|
|
|
+ let isExist = false;
|
|
|
+ form.model.skus[k].children.forEach((e) => {
|
|
|
+ if (e.name == childrenModal[k] && e.name != '') {
|
|
|
+ isExist = true;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (isExist) {
|
|
|
+ alert('子规格已存在');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ form.model.skus[k].children.push({
|
|
|
+ id: 0,
|
|
|
+ temp_id: countId.value++,
|
|
|
+ name: childrenModal[k],
|
|
|
+ pid: form.model.skus[k].id,
|
|
|
+ });
|
|
|
+ childrenModal[k] = '';
|
|
|
+
|
|
|
+ // 如果是添加的第一个子规格,清空 skuPrice
|
|
|
+ if (form.model.skus[k].children.length == 1) {
|
|
|
+ form.model.sku_prices = []; // 规格大变化,清空skuPrice
|
|
|
+ isResetSku.value = 1; // 重置规格
|
|
|
+ }
|
|
|
+ buildSkuPriceTable();
|
|
|
+ }
|
|
|
+ function deleteChildrenSku(k, i) {
|
|
|
+ let data = form.model.skus[k].children[i];
|
|
|
+ form.model.skus[k].children.splice(i, 1);
|
|
|
+
|
|
|
+ // 查询 skuPrice 中包含被删除的的子规格的项,然后移除
|
|
|
+ let deleteArr = [];
|
|
|
+ form.model.sku_prices.forEach((item, index) => {
|
|
|
+ item.goods_sku_text.forEach((e, i) => {
|
|
|
+ if (e == data.name) {
|
|
|
+ deleteArr.push(index);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ deleteArr.sort(function (a, b) {
|
|
|
+ return b - a;
|
|
|
+ });
|
|
|
+ // 移除有相关子规格的项
|
|
|
+ deleteArr.forEach((i, e) => {
|
|
|
+ form.model.sku_prices.splice(i, 1);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 当前规格项,所有子规格都被删除,清空 skuPrice
|
|
|
+ if (form.model.skus[k].children.length <= 0) {
|
|
|
+ form.model.sku_prices = []; // 规格大变化,清空skuPrice
|
|
|
+ isResetSku.value = 1; // 重置规格
|
|
|
+ }
|
|
|
+ buildSkuPriceTable();
|
|
|
+ }
|
|
|
+ watch(
|
|
|
+ () => form.model.skus,
|
|
|
+ () => {
|
|
|
+ if (isEditInit.value && form.model.is_sku) {
|
|
|
+ buildSkuPriceTable();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { deep: true },
|
|
|
+ );
|
|
|
+ //组成新的规格
|
|
|
+ function buildSkuPriceTable() {
|
|
|
+ let arr = [];
|
|
|
+ //遍历sku子规格生成新数组,然后执行递归笛卡尔积
|
|
|
+ form.model.skus.forEach((s1, k1) => {
|
|
|
+ let children = s1.children;
|
|
|
+ let childrenIdArray = [];
|
|
|
+ if (children.length > 0) {
|
|
|
+ children.forEach((s2, k2) => {
|
|
|
+ childrenIdArray.push(s2.temp_id);
|
|
|
+ });
|
|
|
+ // 如果 children 子规格数量为 0,则不渲染当前规格, (相当于没有这个主规格)
|
|
|
+ arr.push(childrenIdArray);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ recursionSku(arr, 0, []);
|
|
|
+ }
|
|
|
+ //递归找笛卡尔规格集合
|
|
|
+ function recursionSku(arr, k, temp) {
|
|
|
+ if (k == arr.length && k != 0) {
|
|
|
+ let tempDetail = [];
|
|
|
+ let tempDetailIds = [];
|
|
|
+ temp.forEach((item, index) => {
|
|
|
+ for (let sku of form.model.skus) {
|
|
|
+ for (let child of sku.children) {
|
|
|
+ if (item == child.temp_id) {
|
|
|
+ tempDetail.push(child.name);
|
|
|
+ tempDetailIds.push(child.temp_id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ let flag = false; // 默认添加新的
|
|
|
+ for (let i = 0; i < form.model.sku_prices.length; i++) {
|
|
|
+ if (form.model.sku_prices[i].goods_sku_temp_ids.join(',') == tempDetailIds.join(',')) {
|
|
|
+ flag = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (flag === false) {
|
|
|
+ form.model.sku_prices.push({
|
|
|
+ id: 0,
|
|
|
+ temp_id: form.model.sku_prices.length + 1,
|
|
|
+ goods_sku_ids: '',
|
|
|
+ goods_id: 0,
|
|
|
+ weigh: 0,
|
|
|
+ image: '',
|
|
|
+ stock: 0,
|
|
|
+ stock_warning: null,
|
|
|
+ stock_warning_switch: false,
|
|
|
+ price: 0,
|
|
|
+ sn: '',
|
|
|
+ weight: 0,
|
|
|
+ status: 'up',
|
|
|
+ goods_sku_text: tempDetail,
|
|
|
+ goods_sku_temp_ids: tempDetailIds,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ form.model.sku_prices[flag].goods_sku_text = tempDetail;
|
|
|
+ form.model.sku_prices[flag].goods_sku_temp_ids = tempDetailIds;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (arr.length) {
|
|
|
+ for (let i = 0; i < arr[k].length; i++) {
|
|
|
+ temp[k] = arr[k][i];
|
|
|
+ recursionSku(arr, k + 1, temp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取库存预警
|
|
|
+ function changeStockWarningSwitch(e) {
|
|
|
+ form.model.sku_prices[e].stock_warning = form.model.sku_prices[e].stock_warning_switch
|
|
|
+ ? 0
|
|
|
+ : null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取配送方式
|
|
|
+ const dispatchCheck = ref(true);
|
|
|
+ const dispatch = reactive({
|
|
|
+ select: [],
|
|
|
+ });
|
|
|
+ async function getDispatchSelect() {
|
|
|
+ ({ data: dispatch.select } = await dispatchApi.select({
|
|
|
+ type: form.model.dispatch_type,
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ function onAddDispatch(dispatch_type) {
|
|
|
+ useModal(
|
|
|
+ DispatchEdit,
|
|
|
+ { title: '新建', type: 'add', dispatchType: dispatch_type },
|
|
|
+ {
|
|
|
+ confirm: () => {
|
|
|
+ getDispatchSelect();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ );
|
|
|
+ }
|
|
|
+ function onChangeDispatchType(val) {
|
|
|
+ form.model.dispatch_id = val == 'custom' ? 0 : '';
|
|
|
+ getDispatchSelect();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取服务保障
|
|
|
+ const service = reactive({
|
|
|
+ select: [],
|
|
|
+ });
|
|
|
+ async function getServiceSelect() {
|
|
|
+ ({ data: service.select } = await api.service.select());
|
|
|
+ }
|
|
|
+ function createService() {
|
|
|
+ useModal(
|
|
|
+ ServiceEdit,
|
|
|
+ { title: '新建', type: 'add' },
|
|
|
+ {
|
|
|
+ confirm: () => {
|
|
|
+ getServiceSelect();
|
|
|
+ },
|
|
|
+ },
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ const allEditDatas = ref('');
|
|
|
+ const allstock_warning_switch = ref(false);
|
|
|
+ const stock_warning_switch = ref(false);
|
|
|
+ const allEditPopover = reactive({
|
|
|
+ price: false,
|
|
|
+ original_price: false,
|
|
|
+ cost_price: false,
|
|
|
+ stock: false,
|
|
|
+ stock_warning: false,
|
|
|
+ weight: false,
|
|
|
+ sn: false,
|
|
|
+ });
|
|
|
+ const templateRules = {
|
|
|
+ title: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
|
|
+ content: [{ required: true, message: '请输入内容', trigger: 'blur' }],
|
|
|
+ };
|
|
|
+ function addTemplate() {
|
|
|
+ form.model.params.push({
|
|
|
+ title: '',
|
|
|
+ content: '',
|
|
|
+ });
|
|
|
+ }
|
|
|
+ function deleteTemplate(index) {
|
|
|
+ form.model.params.splice(index, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ //批量操作
|
|
|
+ //保存
|
|
|
+ function allEditData(type, opt) {
|
|
|
+ switch (opt) {
|
|
|
+ case 'define':
|
|
|
+ form.model.sku_prices.forEach((i) => {
|
|
|
+ if (type == 'stock_warning') {
|
|
|
+ if (allstock_warning_switch.value) {
|
|
|
+ i.stock_warning_switch.value = true;
|
|
|
+ if (allEditDatas.value) {
|
|
|
+ i[type] = allEditDatas.value;
|
|
|
+ } else {
|
|
|
+ i[type] = 0;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ i.stock_warning_switch.value = false;
|
|
|
+ if (i.stock_warning_switch.value) {
|
|
|
+ i[type] = allEditDatas.value;
|
|
|
+ } else {
|
|
|
+ i[type] = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ i[type] = allEditDatas.value;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ allEditDatas.value = '';
|
|
|
+ allEditPopover[type] = false;
|
|
|
+ allstock_warning_switch.value = false;
|
|
|
+ break;
|
|
|
+ case 'cancel':
|
|
|
+ allEditDatas.value = '';
|
|
|
+ allEditPopover[type] = false;
|
|
|
+ allstock_warning_switch.value = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function onChangeGoodsType(type) {
|
|
|
+ form.model.type = type;
|
|
|
+ form.model.dispatch_type = type == 'normal' ? 'express' : 'autosend';
|
|
|
+ form.model.dispatch_id = '';
|
|
|
+ getDispatchSelect();
|
|
|
+ }
|
|
|
+
|
|
|
+ function onSuccess(data) {
|
|
|
+ form.model.image_wh = {
|
|
|
+ w: data.image_width,
|
|
|
+ h: data.image_height,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ // 表单关闭时提交
|
|
|
+ function confirm() {
|
|
|
+ isValidate();
|
|
|
+ setTimeout(async () => {
|
|
|
+ if (validateData.value[0] == 0 && validateData.value[1] == 0 && validateData.value[2] == 0) {
|
|
|
+ let submitForm = cloneDeep(form.model);
|
|
|
+
|
|
|
+ // 处理category_ids
|
|
|
+ let idsArr = [];
|
|
|
+ for (var key in tempCategory.idsArr) {
|
|
|
+ idsArr.push(...tempCategory.idsArr[key]);
|
|
|
+ }
|
|
|
+ submitForm.category_ids = idsArr.join(',');
|
|
|
+
|
|
|
+ if (submitForm.is_sku == 1) {
|
|
|
+ delete submitForm.stock;
|
|
|
+ delete submitForm.cost_price;
|
|
|
+ delete submitForm.original_price;
|
|
|
+ delete submitForm.price;
|
|
|
+ delete submitForm.stock_warning;
|
|
|
+ delete submitForm.sn;
|
|
|
+ delete submitForm.weight;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (props.modal.params.type == 'copy') {
|
|
|
+ delete submitForm.id;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 虚拟商品is_offline=0
|
|
|
+ if (submitForm.type == 'virtual') {
|
|
|
+ submitForm.is_offline = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ const { error } =
|
|
|
+ props.modal.params.type == 'add' || props.modal.params.type == 'copy'
|
|
|
+ ? await api.goods.add(submitForm)
|
|
|
+ : await api.goods.edit(props.modal.params.id, submitForm);
|
|
|
+ if (error == 0) {
|
|
|
+ emit('modalCallBack', {
|
|
|
+ event: 'confirm',
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ async function init() {
|
|
|
+ await getServiceSelect();
|
|
|
+ await getCategorySelect();
|
|
|
+ if (props.modal.params.type == 'edit' || props.modal.params.type == 'copy') {
|
|
|
+ await getDetail(props.modal.params.id);
|
|
|
+ } else {
|
|
|
+ getInit();
|
|
|
+ }
|
|
|
+ getDispatchSelect();
|
|
|
+ }
|
|
|
+ onMounted(() => {
|
|
|
+ init();
|
|
|
+ updateStyle();
|
|
|
+ });
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .goods-edit {
|
|
|
+ .el-header {
|
|
|
+ --el-header-height: fit-content;
|
|
|
+ }
|
|
|
+ .goods-type {
|
|
|
+ width: 140px;
|
|
|
+ height: 56px;
|
|
|
+ border: 1px solid rgb(230, 230, 230);
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-left: 16px;
|
|
|
+ cursor: pointer;
|
|
|
+ &.is-active {
|
|
|
+ border: 1px solid var(--el-color-primary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .is-error {
|
|
|
+ color: #ff4d4f;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .goods-edit {
|
|
|
+ .oper {
|
|
|
+ :deep() {
|
|
|
+ .el-form-item__content {
|
|
|
+ height: 32px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .header {
|
|
|
+ width: 100%;
|
|
|
+ height: 40px;
|
|
|
+ color: #434343;
|
|
|
+ padding-left: 16px;
|
|
|
+ background: var(--sa-table-striped);
|
|
|
+ margin: 24px 0 16px 0;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ //商品形式
|
|
|
+ .goodstype {
|
|
|
+ width: 140px;
|
|
|
+ height: 56px;
|
|
|
+ border-radius: 4px;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+ .badge {
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ line-height: 16px;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 50%;
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 14px;
|
|
|
+ position: absolute;
|
|
|
+ top: -8px;
|
|
|
+ right: -8px;
|
|
|
+ }
|
|
|
+ //提示文本
|
|
|
+ .warning-title {
|
|
|
+ color: #faad14;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 16px;
|
|
|
+ margin-left: 16px;
|
|
|
+ }
|
|
|
+ .add-category {
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ //警告图标
|
|
|
+ .icon-warning {
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ display: flex;
|
|
|
+ margin-left: 8px;
|
|
|
+ }
|
|
|
+ //精确图片
|
|
|
+ .sales-hover-img {
|
|
|
+ width: 220px;
|
|
|
+ height: 98px;
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+ .stock-hover-img {
|
|
|
+ width: 220px;
|
|
|
+ height: 74px;
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+ //批量操作
|
|
|
+ .batch {
|
|
|
+ height: 40px;
|
|
|
+ padding: 0 16px;
|
|
|
+ border: 1px solid var(--sa-border);
|
|
|
+ border-top: none;
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--sa-subtitle);
|
|
|
+ .batch-title {
|
|
|
+ margin-left: 12px;
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .batch-cancle {
|
|
|
+ margin-left: 8px;
|
|
|
+ color: var(--sa-subfont);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep() {
|
|
|
+ //步骤条
|
|
|
+ .el-step__head {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ .el-step.is-simple:not(:last-of-type) .el-step__title {
|
|
|
+ max-width: 100%;
|
|
|
+ }
|
|
|
+ .el-step__title.is-process {
|
|
|
+ font-weight: 500;
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ }
|
|
|
+ .el-step__title.is-wait {
|
|
|
+ font-weight: 500;
|
|
|
+ color: var(--sa-font);
|
|
|
+ }
|
|
|
+ .el-step.is-simple .el-step__arrow::before {
|
|
|
+ transform: rotate(-45deg) translateY(-3px);
|
|
|
+ height: 9px;
|
|
|
+ }
|
|
|
+ .el-step.is-simple .el-step__arrow::after {
|
|
|
+ transform: rotate(45deg) translateY(3px);
|
|
|
+ height: 9px;
|
|
|
+ }
|
|
|
+ .el-steps--simple {
|
|
|
+ background: var(--sa-table-header-bg);
|
|
|
+ }
|
|
|
+ .server {
|
|
|
+ .el-form-item__content {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ .el-button {
|
|
|
+ border-radius: 0 4px 4px 0;
|
|
|
+ background: var(--sa-table-header-bg);
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-select__tags {
|
|
|
+ padding-left: 12px;
|
|
|
+ .el-tag {
|
|
|
+ background: var(--sa-table-header-bg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ .success {
|
|
|
+ color: red;
|
|
|
+ }
|
|
|
+
|
|
|
+ .sku-wrap {
|
|
|
+ width: 100%;
|
|
|
+ border: 1px solid #d9d9d9;
|
|
|
+ padding: 8px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ .sku {
|
|
|
+ width: 100%;
|
|
|
+ min-height: 100px;
|
|
|
+ .sku-key {
|
|
|
+ width: 100%;
|
|
|
+ height: 40px;
|
|
|
+ color: var(--sa-subtitle);
|
|
|
+ padding: 0 16px;
|
|
|
+ background: var(--sa-table-header-bg);
|
|
|
+ font-size: 14px;
|
|
|
+ .sku-key-input {
|
|
|
+ width: 120px;
|
|
|
+ }
|
|
|
+ .sku-key-icon {
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .sku-value {
|
|
|
+ padding: 12px 0 0 30px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: var(--sa-subtitle);
|
|
|
+ .sku-value-title {
|
|
|
+ height: 32px;
|
|
|
+ }
|
|
|
+ .sku-value-box {
|
|
|
+ position: relative;
|
|
|
+ margin-right: 24px;
|
|
|
+ .sku-value-input {
|
|
|
+ width: 104px;
|
|
|
+ }
|
|
|
+ .sku-value-icon {
|
|
|
+ position: absolute;
|
|
|
+ right: -8px;
|
|
|
+ top: -8px;
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .sku-value-add {
|
|
|
+ width: 104px;
|
|
|
+ height: 32px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .sku-tools {
|
|
|
+ width: 100%;
|
|
|
+ height: 40px;
|
|
|
+ color: #434343;
|
|
|
+ padding-left: 16px;
|
|
|
+ background: var(--sa-table-header-bg);
|
|
|
+ font-size: 12px;
|
|
|
+ .add {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .alledit-input {
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .sku-table-wrap {
|
|
|
+ width: 100%;
|
|
|
+ overflow: auto;
|
|
|
+ margin-top: 16px;
|
|
|
+ .sku-table {
|
|
|
+ width: 100%;
|
|
|
+ border: 1px solid var(--sa-border);
|
|
|
+ tbody {
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ th {
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--subtitle);
|
|
|
+ height: 32px;
|
|
|
+ line-height: 1;
|
|
|
+ padding-left: 12px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ text-align: left;
|
|
|
+ .sku-table-header-title {
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+ .th-title {
|
|
|
+ font-size: 12px;
|
|
|
+ color: var(--subtitle);
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ td {
|
|
|
+ min-width: 88px;
|
|
|
+ padding: 0 10px;
|
|
|
+ height: 40px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ &.image {
|
|
|
+ min-width: 48px;
|
|
|
+ }
|
|
|
+ &.stock {
|
|
|
+ min-width: 138px;
|
|
|
+ }
|
|
|
+ &.stock_warning {
|
|
|
+ min-width: 168px;
|
|
|
+ .sku-stock-switch {
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ &.sn {
|
|
|
+ min-width: 116px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .batch-icon {
|
|
|
+ width: 12px;
|
|
|
+ height: 12px;
|
|
|
+ margin-left: 10px;
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ }
|
|
|
+</style>
|
|
|
+<style lang="scss">
|
|
|
+ .popper-category {
|
|
|
+ // width: 350px;
|
|
|
+ padding: 10px !important;
|
|
|
+ .el-cascader-panel {
|
|
|
+ overflow: auto;
|
|
|
+ }
|
|
|
+ .el-tooltip__trigger {
|
|
|
+ position: relative;
|
|
|
+ max-width: 360px;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .category-content {
|
|
|
+ position: relative;
|
|
|
+ max-width: 360px;
|
|
|
+ width: 100%;
|
|
|
+ .category-tag {
|
|
|
+ position: absolute;
|
|
|
+ z-index: 10;
|
|
|
+ left: 0;
|
|
|
+ right: 76px;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ line-height: normal;
|
|
|
+ text-align: left;
|
|
|
+ box-sizing: border-box;
|
|
|
+ .el-tag {
|
|
|
+ margin: 2px 0 2px 6px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-tag-wrap {
|
|
|
+ flex: 1;
|
|
|
+ min-height: 32px;
|
|
|
+ padding-right: 12px;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid var(--sa-border);
|
|
|
+ cursor: pointer;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-tag-wrap .el-tag {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ max-width: 100%;
|
|
|
+ margin: 2px 0 2px 6px;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-tag-wrap-suffix {
|
|
|
+ width: 12px;
|
|
|
+ height: 100%;
|
|
|
+ position: absolute;
|
|
|
+ right: 6px;
|
|
|
+ top: 0;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-tag-wrap-suffix .circle-close {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-tag-wrap-suffix.is-active:hover .circle-close {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-tag-wrap-suffix.is-active:hover .arrow-down {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+</style>
|