| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- <template>
- <el-drawer :title="titleMap[mode]" :append-to-body="true" v-model="visible" :size="800" destroy-on-close :close-on-click-modal="false" @closed="$emit('closed')" :with-header="false">
- <el-container class="flex-column" v-loading="loading">
- <div class="drawer-detail-main">
- <div class="drawer-detail-header">
- <div class="drawer-detail-header-body">
- <div class="drawer-detail-header-left">{{ titleMap[mode] }}</div>
- <div class="drawer-detail-header-left">
- <el-button type="default" icon="el-icon-close" @click="visible=false"></el-button>
- </div>
- </div>
- </div>
- </div>
- <el-main>
- <el-form ref="dialogForm" :model="formData" :rules="rules" label-width="100px" label-position="top">
- <fieldset>
- <legend><el-tag>基础信息</el-tag></legend>
- <el-form-item label="SKU名称" prop="name">
- <el-input v-model="formData.name" clearable maxlength="40" show-word-limit placeholder="请输入"></el-input>
- <div class="el-form-item-msg"></div>
- </el-form-item>
- <el-form-item label="商品原价" prop="line_price">
- <el-input v-model="formData.line_price" clearable placeholder="请输入" type="number">
- <template #append>元</template>
- </el-input>
- <div class="el-form-item-msg"></div>
- </el-form-item>
- <el-form-item label="顾客支付价" prop="price">
- <el-input v-model="formData.price" readonly clearable placeholder="请输入" type="number">
- <template #append>元</template>
- </el-input>
- <div class="el-form-item-msg"></div>
- </el-form-item>
- <el-form-item label="商品编号" prop="sku_id">
- <el-input v-model="formData.sku_id" clearable placeholder="请输入">
- <template #append>
- <el-button @click="createSkuId">重新获取</el-button>
- </template>
- </el-input>
- <div class="el-form-item-msg"></div>
- </el-form-item>
- <el-form-item label="规格图片" prop="image">
- <sc-upload v-model="formData.image" title="规格图片" :cropper="true" :compress="1" :aspectRatio="1/1"></sc-upload>
- <div class="el-form-item-msg"></div>
- </el-form-item>
- </fieldset>
- <fieldset>
- <legend><el-tag>商品搭配</el-tag></legend>
- <el-button type="primary" size="small" @click="addSpecs" v-if="specs.length<5">添加分组</el-button>
- <div class="specs" v-for="(item,indx) in specs" :key="indx">
- <div class="specs-header">
- <div class="specs-left">
- <el-input v-model="item.name" placeholder="请输入商品组名称" maxlength="10" show-word-limit clearable style="width: 50%;"></el-input>
- </div>
- <div class="specs-right">
- <el-select v-model="item.num" placeholder="请选择">
- <el-option :value="0" label="全部可选"></el-option>
- <el-option :value="len" :label="item.list.length+'选'+len" v-for="len in item.list.length" v-if="item.list.length > 1"></el-option>
- </el-select>
- </div>
- </div>
- <div class="specs-tips">商品组名称中不可出现“任选N”“X选N”字样,当商品组的可选范围是“几选1”或“全部可选”时,不可配置重复选</div>
- <div class="specs-body">
- <div class="body-item" v-for="(its,ind) in item.list" :key="ind">
- <div class="item-left">
- <el-row :gutter="10">
- <el-col :span="12" class="mb10">
- <el-input placeholder="请输入单品名称 " v-model="its.name">
- <template #prepend>名称</template>
- </el-input>
- </el-col>
- <el-col :span="12" class="mb10">
- <el-input placeholder="单价" v-model="its.price" type="number">
- <template #prepend>单价</template>
- <template #append>元</template>
- </el-input>
- </el-col>
- <el-col :span="12" class="mb10">
- <el-input placeholder="请输入重量 " v-model="its.weight" type="number">
- <template #prepend>重量</template>
- <template #append>
- <el-select v-model="its.weight_unit">
- <el-option value="kg" label="kg(千克)"></el-option>
- <el-option value="g" label="g(克)"></el-option>
- <el-option value="L" label="L(升)"></el-option>
- <el-option value="ml" label="ml(毫升)"></el-option>
- <el-option value="m" label="m(米)"></el-option>
- <el-option value="m²" label="m²(平方米)"></el-option>
- <el-option value="m³" label="m³(立方米)"></el-option>
- </el-select>
- </template>
- </el-input>
- </el-col>
- <el-col :span="12" class="mb10">
- <el-input placeholder="数量" v-model="its.number" type="number">
- <template #prepend>数量</template>
- <template #append>份</template>
- </el-input>
- </el-col>
- </el-row>
- </div>
- <div class="item-dels">
- <el-button type="danger" @click="removeItem(indx,ind)" circle icon="el-icon-delete" size="small"></el-button>
- </div>
- </div>
- </div>
- <div class="specs-footer">
- <el-button type="primary" @click="addItem(indx)" size="small">增加单品</el-button>
- <el-button type="danger" @click="removeSpec(indx)" size="small">删除组</el-button>
- </div>
- </div>
- </fieldset>
- </el-form>
- </el-main>
- <el-footer style="text-align: right;">
- <el-button @click="visible=false" >取 消</el-button>
- <el-button v-if="mode!='show'" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
- </el-footer>
- </el-container>
- </el-drawer>
- </template>
- <script>
- export default {
-
- data(){
- return {
- loading: false,
- mode:"add",
- titleMap:{
- add:"新增商品",
- edit:"SKU详情"
- },
- visible: false,
- isSaveing: false,
- specs:[{"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]}],
- formData:{},
- skuIndex:0,
- rules:{
- sku_id: [
- {required: true, message: '请输入'}
- ],
- name: [
- {required: true, message: '请输入'}
- ],
- line_price: [
- {required: true, message: '请输入'}
- ],
- price: [
- {required: true, message: '请输入'}
- ],
- }
- }
- },
- methods:{
- createSkuId(){
- this.formData.sku_id = this.generate()
- },
- generate() {
- // 1. 获取当前毫秒时间戳(13位)
- let timestamp = Date.now();
- // 避免同一毫秒内重复(若时间戳相同,sequence递增)
- if (timestamp === this.lastTimestamp) {
- this.sequence++;
- } else {
- this.sequence = 0;
- this.lastTimestamp = timestamp;
- }
-
- // 2. 随机数部分:生成 4 位随机数(保证总长度灵活调整)
- const randomPart = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
-
- // 3. 组合:时间戳(13位) + 序列号(最多2位,可调) + 随机数(4位) → 总长度可变
- // 目标18位,所以需要控制各部分长度
- // 这里设计:时间戳后6位 + 序列号(2位) + 随机数(4位) + 补足剩余长度
- const timestampPart = timestamp.toString().slice(-6); // 取时间戳后6位
- const seqPart = this.sequence.toString().padStart(2, '0'); // 序列号占2位(0-99)
-
- // 组合得到12位,还需要6位随机数(总18位)
- let base = timestampPart + seqPart + randomPart; // 6+2+4=12位
- const remainingLength = 18 - base.length;
- const extraRandom = Math.floor(Math.random() * Math.pow(10, remainingLength)).toString().padStart(remainingLength, '0');
-
- return base + extraRandom; // 最终18位字符串
- },
- open(mode = 'add'){
- this.mode = mode;
- this.visible = true;
- return this
- },
- //表单注入数据
- setData(index,data){
- this.formData = JSON.parse(JSON.stringify(data));
- this.specs = this.formData.specs;
- this.skuIndex = index;
- },
- addSpecs(){
- if (this.specs.length >= 5) {
- return this.$message.error("最多只能添加三组规格")
- }
- this.specs.push({"name":"","num":0,"list":[ {"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1} ]});
- },
- addItem(index){
- if (this.specs[index].list.length >= 20) {
- return this.$message.error("最多只能添加20个")
- }
- this.specs[index].list.push({"name":"","price":1,"weight":"1","weight_unit":'kg',"number":1})
- },
- removeSpec(index){
- this.specs.splice(index,1)
- },
- removeItem(index,sub){
- this.specs[index].list.splice(sub,1)
- },
- async submit(){
- var validate = await this.$refs.dialogForm.validate().catch(()=>{});
- if(!validate){ return false }
- this.visible = false;
- this.$emit("success",{"index":this.skuIndex,"data":this.formData});
- this.formData = {};
- }
- }
- }
- </script>
- <style>
- .specs{margin-top: 15px;background-color: #f8f8f8;}
- .specs-header{
- display: flex;
- background-color: #ddd;
- padding: 10px;
- }
- .specs-tips{
- padding: 0 10px 10px 10px;
- background-color: #ddd;
- }
- .specs-header .specs-left{
- display: flex;
- align-items: center;
- flex: 1;
- gap: 10px;
- }
- .specs-header .specs-right{
- display: flex;
- margin-left: auto;
- margin-right: 0;
- }
- .specs-body{display: flex;align-items: center;gap: 10px;padding: 10px;flex-direction: row;flex-wrap: wrap;}
- .specs-body .body-item{padding: 5px;display: flex;align-items: center;}
- .specs-body .body-item .item-dels{margin-left: 10px;}
- .mb10{margin-bottom: 10px;}
- .specs-footer{background-color: #ddd;padding: 10px;}
- .sku-table{margin-top: 10px;}
- </style>
|