|
@@ -31,48 +31,84 @@
|
|
</el-row>
|
|
</el-row>
|
|
<!-- 列表 -->
|
|
<!-- 列表 -->
|
|
<Page uri="/mapi/core/goods/list" :request-params="queryParams" ref="pagination">
|
|
<Page uri="/mapi/core/goods/list" :request-params="queryParams" ref="pagination">
|
|
- <el-table-column label="ID" align="center" prop="id" />
|
|
|
|
- <el-table-column label="商品编号" align="center" prop="goodsCode" />
|
|
|
|
- <el-table-column label="商品名称" align="center" prop="goodsName" />
|
|
|
|
- <el-table-column label="图片" align="center" prop="goodsImg" width="100">
|
|
|
|
|
|
+ <el-table-column label="商品信息" align="left" min-width="400">
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
- <el-image style="width: 80px; height: 80px" :src="scope.row.goodsImg" :preview-src-list="[scope.row.goodsImg]"> </el-image>
|
|
|
|
- </template>
|
|
|
|
- </el-table-column>
|
|
|
|
- <el-table-column label="品牌" align="center" prop="brandName" />
|
|
|
|
- <el-table-column label="商品分类" align="center" prop="goodsCategoryId">
|
|
|
|
- <template slot-scope="scope">
|
|
|
|
- <span v-if="scope.row.goodsCategoryId == item.id" v-for="item in categoryList" :key="item.id"> {{ item.categoryName }}</span>
|
|
|
|
|
|
+ <div class="goods-info">
|
|
|
|
+ <el-image
|
|
|
|
+ style="width: 80px; height: 80px; margin-right: 10px;"
|
|
|
|
+ :src="scope.row.goodsImg"
|
|
|
|
+ :preview-src-list="[scope.row.goodsImg]">
|
|
|
|
+ </el-image>
|
|
|
|
+ <div class="goods-detail">
|
|
|
|
+ <div class="goods-name">{{scope.row.goodsName}}</div>
|
|
|
|
+ <div class="goods-code">商品编号:{{scope.row.goodsCode}}</div>
|
|
|
|
+ <div class="goods-category">
|
|
|
|
+ <el-tag size="mini" type="info">{{scope.row.brandName}}</el-tag>
|
|
|
|
+ <el-tag size="mini" type="info" v-if="scope.row.goodsCategoryId" style="margin-left: 5px;">
|
|
|
|
+ <span v-if="scope.row.goodsCategoryId == item.id" v-for="item in categoryList" :key="item.id">
|
|
|
|
+ {{item.categoryName}}
|
|
|
|
+ </span>
|
|
|
|
+ </el-tag>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <el-table-column label="促销标识" align="center" prop="isSell">
|
|
|
|
|
|
+
|
|
|
|
+ <el-table-column label="价格/库存" align="center" width="200">
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
- <el-tag v-if="scope.row.isSell == dict.value" v-for="dict in dict.type.sys_yes_no" :label="dict.value" :key="dict.code"> {{ dict.label }}</el-tag>
|
|
|
|
|
|
+ <div v-if="scope.row.skuList && scope.row.skuList.length > 0">
|
|
|
|
+ <div>销售价:¥{{getMinMaxPrice(scope.row.skuList, 'salePrice')}}</div>
|
|
|
|
+ <div>批发价:¥{{getMinMaxPrice(scope.row.skuList, 'wholesalePrice')}}</div>
|
|
|
|
+ <div>总库存:{{getTotalStock(scope.row.skuList)}}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div v-else>
|
|
|
|
+ <div>暂无价格信息</div>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <el-table-column label="规格数量" align="center" prop="goodsItemNum">
|
|
|
|
|
|
+
|
|
|
|
+ <el-table-column label="规格" align="center" width="120">
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
- <el-button type="text" @click="handleSkuUpdate(scope.row)">{{ scope.row.goodsItemNum }}种规格</el-button>
|
|
|
|
|
|
+ <el-button type="text" @click="openSkuDialog(scope.row)">
|
|
|
|
+ <span>{{scope.row.goodsItemNum}}种规格</span>
|
|
|
|
+ <i class="el-icon-arrow-right"></i>
|
|
|
|
+ </el-button>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <el-table-column label="余额支付" align="center" prop="isBalancePay">
|
|
|
|
|
|
+
|
|
|
|
+ <el-table-column label="支付方式" align="center" width="150">
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
- <el-tag v-if="scope.row.isBalancePay == dict.value" v-for="dict in dict.type.sys_yes_no" :label="dict.value" :key="dict.code"> {{ dict.label }}</el-tag>
|
|
|
|
|
|
+ <div>
|
|
|
|
+ <el-tag v-if="scope.row.isBalancePay === 'Y'" size="mini" type="success">余额支付</el-tag>
|
|
|
|
+ <el-tag v-else size="mini" type="info">不支持余额</el-tag>
|
|
|
|
+ </div>
|
|
|
|
+ <div style="margin-top: 5px;">
|
|
|
|
+ <el-tag v-if="scope.row.isSell === 'Y'" size="mini" type="warning">促销商品</el-tag>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <!-- <el-table-column label="金额(元)" align="center" prop="cashMoney" />-->
|
|
|
|
- <el-table-column label="排序值" align="center" prop="sort" />
|
|
|
|
- <el-table-column label="启用状态" align="center" prop="status">
|
|
|
|
|
|
+
|
|
|
|
+ <el-table-column label="排序/状态" align="center" width="120">
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
- <el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
|
|
|
|
|
|
+ <div>排序:{{scope.row.sort}}</div>
|
|
|
|
+ <div style="margin-top: 5px;">
|
|
|
|
+ <el-switch
|
|
|
|
+ v-model="scope.row.status"
|
|
|
|
+ active-value="0"
|
|
|
|
+ inactive-value="1"
|
|
|
|
+ @change="handleStatusChange(scope.row)">
|
|
|
|
+ </el-switch>
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
|
|
|
|
|
+
|
|
|
|
+ <el-table-column label="操作" align="center" width="200" fixed="right">
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
<el-button type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['goods:commonGoods:edit']" v-if="userInfoVO.userType == '00'">修改</el-button>
|
|
<el-button type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['goods:commonGoods:edit']" v-if="userInfoVO.userType == '00'">修改</el-button>
|
|
<el-button type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['goods:commonGoods:remove']" v-if="userInfoVO.userType == '00'">删除</el-button>
|
|
<el-button type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['goods:commonGoods:remove']" v-if="userInfoVO.userType == '00'">删除</el-button>
|
|
- <el-button type="text" icon="el-icon-s-shop" @click="handleSkuUpdate(scope.row)" v-hasPermi="['goods:commonGoods:list']">查看规格</el-button>
|
|
|
|
- <el-button type="text" icon="el-icon-view" v-if="goodsType != 1" @click="gotoComment(scope.row)">查看评论</el-button>
|
|
|
|
|
|
+ <el-button type="text" icon="el-icon-s-shop" @click="openSkuDialog(scope.row)" v-hasPermi="['goods:commonGoods:list']">规格</el-button>
|
|
|
|
+ <el-button type="text" icon="el-icon-view" v-if="goodsType != 1" @click="gotoComment(scope.row)">评论</el-button>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
</Page>
|
|
</Page>
|
|
@@ -175,7 +211,7 @@
|
|
class="input-new-tag"
|
|
class="input-new-tag"
|
|
v-if="spec.inputVisible"
|
|
v-if="spec.inputVisible"
|
|
v-model="spec.inputValue"
|
|
v-model="spec.inputValue"
|
|
- :ref="'saveTagInput' + index"
|
|
|
|
|
|
+ ref="tagInput"
|
|
size="small"
|
|
size="small"
|
|
@keyup.enter.native="handleInputConfirm(spec, index)"
|
|
@keyup.enter.native="handleInputConfirm(spec, index)"
|
|
@blur="handleInputConfirm(spec, index)">
|
|
@blur="handleInputConfirm(spec, index)">
|
|
@@ -281,6 +317,8 @@
|
|
<el-button @click="cancel">取 消</el-button>
|
|
<el-button @click="cancel">取 消</el-button>
|
|
</div>
|
|
</div>
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
+ <!-- 添加规格弹窗组件 -->
|
|
|
|
+ <goods-sku-dialog ref="skuDialog"></goods-sku-dialog>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -289,9 +327,13 @@ import { listGoods, getGoods, delGoods, addGoods, updateGoods, updateGoodsStatus
|
|
import { listCategory } from '@/api/core/category'
|
|
import { listCategory } from '@/api/core/category'
|
|
import { listBrand } from '@/api/core/brand'
|
|
import { listBrand } from '@/api/core/brand'
|
|
import { status } from 'nprogress'
|
|
import { status } from 'nprogress'
|
|
|
|
+import GoodsSkuDialog from '@/components/GoodsSkuDialog'
|
|
|
|
|
|
export default {
|
|
export default {
|
|
name: 'appGoods',
|
|
name: 'appGoods',
|
|
|
|
+ components: {
|
|
|
|
+ GoodsSkuDialog
|
|
|
|
+ },
|
|
dicts: ['goods_type', 'sys_yes_no'],
|
|
dicts: ['goods_type', 'sys_yes_no'],
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
@@ -643,7 +685,10 @@ export default {
|
|
},
|
|
},
|
|
/** 设置物料 */
|
|
/** 设置物料 */
|
|
handleSkuUpdate(row) {
|
|
handleSkuUpdate(row) {
|
|
- this.$tab.openPage(row.goodsName + '的物料', '/goods/setSku/' + row.id)
|
|
|
|
|
|
+ this.openSkuDialog(row)
|
|
|
|
+ },
|
|
|
|
+ openSkuDialog(row) {
|
|
|
|
+ this.$refs.skuDialog.show(row.id)
|
|
},
|
|
},
|
|
handleRemove(file, fileList) {
|
|
handleRemove(file, fileList) {
|
|
console.log(fileList)
|
|
console.log(fileList)
|
|
@@ -741,10 +786,28 @@ export default {
|
|
})
|
|
})
|
|
},
|
|
},
|
|
showInput(spec, index) {
|
|
showInput(spec, index) {
|
|
- spec.inputVisible = true
|
|
|
|
- this.$nextTick(_ => {
|
|
|
|
- this.$refs['saveTagInput' + index][0].$refs.input.focus()
|
|
|
|
- })
|
|
|
|
|
|
+ // 先重置其他所有输入框的状态
|
|
|
|
+ this.form.specList.forEach(item => {
|
|
|
|
+ this.$set(item, 'inputVisible', false);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 设置当前输入框可见
|
|
|
|
+ this.$set(spec, 'inputVisible', true);
|
|
|
|
+
|
|
|
|
+ // 强制更新视图
|
|
|
|
+ this.$forceUpdate();
|
|
|
|
+
|
|
|
|
+ // 等待 DOM 更新后设置焦点
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ if (this.$refs.tagInput && this.$refs.tagInput.length > 0) {
|
|
|
|
+ const inputs = this.$refs.tagInput;
|
|
|
|
+ // 找到最后一个输入框(应该是刚刚显示的那个)
|
|
|
|
+ const input = Array.isArray(inputs) ? inputs[inputs.length - 1] : inputs;
|
|
|
|
+ if (input && input.$el.querySelector('input')) {
|
|
|
|
+ input.$el.querySelector('input').focus();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
},
|
|
},
|
|
handleInputConfirm(spec, index) {
|
|
handleInputConfirm(spec, index) {
|
|
let inputValue = spec.inputValue
|
|
let inputValue = spec.inputValue
|
|
@@ -813,6 +876,18 @@ export default {
|
|
specValue: '',
|
|
specValue: '',
|
|
image: ''
|
|
image: ''
|
|
})
|
|
})
|
|
|
|
+ },
|
|
|
|
+ getMinMaxPrice(skuList, priceType) {
|
|
|
|
+ if (!skuList || skuList.length === 0) return '0.00';
|
|
|
|
+ const prices = skuList.map(sku => sku[priceType] || 0);
|
|
|
|
+ const min = Math.min(...prices);
|
|
|
|
+ const max = Math.max(...prices);
|
|
|
|
+ return min === max ? min.toFixed(2) : `${min.toFixed(2)} ~ ${max.toFixed(2)}`;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ getTotalStock(skuList) {
|
|
|
|
+ if (!skuList || skuList.length === 0) return 0;
|
|
|
|
+ return skuList.reduce((total, sku) => total + (sku.stock || 0), 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -842,4 +917,37 @@ export default {
|
|
margin-left: 10px;
|
|
margin-left: 10px;
|
|
vertical-align: bottom;
|
|
vertical-align: bottom;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+.goods-info {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: flex-start;
|
|
|
|
+ padding: 10px 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.goods-detail {
|
|
|
|
+ flex: 1;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.goods-name {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ font-weight: bold;
|
|
|
|
+ color: #303133;
|
|
|
|
+ margin-bottom: 5px;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
+ display: -webkit-box;
|
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.goods-code {
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ color: #909399;
|
|
|
|
+ margin-bottom: 5px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.goods-category {
|
|
|
|
+ margin-top: 5px;
|
|
|
|
+}
|
|
</style>
|
|
</style>
|