mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-08-06 19:07:25 +08:00
manager 升级到vue3
This commit is contained in:
@@ -1,253 +1,289 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keydown.enter.native="handleSearch"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input
|
||||
type="text"
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="商品编号" prop="id">
|
||||
<Input
|
||||
type="text"
|
||||
</el-form-item>
|
||||
<el-form-item label="商品编号" prop="id">
|
||||
<el-input
|
||||
v-model="searchForm.id"
|
||||
placeholder="请输入商品编号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="店铺名称" prop="id">
|
||||
<Input
|
||||
type="text"
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺名称" prop="storeName">
|
||||
<el-input
|
||||
v-model="searchForm.storeName"
|
||||
placeholder="请输入店铺名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="销售模式" prop="status">
|
||||
<Select
|
||||
</el-form-item>
|
||||
<el-form-item label="销售模式" prop="salesModel">
|
||||
<el-select
|
||||
v-model="searchForm.salesModel"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option value="RETAIL">零售</Option>
|
||||
<Option value="WHOLESALE">批发</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="商品类型" prop="status">
|
||||
<Select
|
||||
<el-option label="零售" value="RETAIL" />
|
||||
<el-option label="批发" value="WHOLESALE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品类型" prop="goodsType">
|
||||
<el-select
|
||||
v-model="searchForm.goodsType"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option value="PHYSICAL_GOODS">实物商品</Option>
|
||||
<Option value="VIRTUAL_GOODS">虚拟商品</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Form-item label="商品分组" prop="groupId">
|
||||
<Select
|
||||
<el-option label="实物商品" value="PHYSICAL_GOODS" />
|
||||
<el-option label="虚拟商品" value="VIRTUAL_GOODS" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品分组" prop="groupId">
|
||||
<el-select
|
||||
v-model="searchForm.groupId"
|
||||
placeholder="请选择商品分组"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 240px"
|
||||
>
|
||||
<Option v-for="item in goodsGroupList" :value="item.id" :key="item.id">{{ item.groupName }}</Option>
|
||||
</Select>
|
||||
</Form-item>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
class="search-btn"
|
||||
type="primary"
|
||||
icon="ios-search"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<el-option
|
||||
v-for="item in goodsGroupList"
|
||||
:key="item.id"
|
||||
:label="item.groupName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<div class="goods-tab">
|
||||
<Tabs v-model="currentStatus" @on-click="goodsStatusClick">
|
||||
<TabPane v-for="(item,index) in goodsStatusWithCount" :key="index" :label="item.title" :name="item.value">
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<el-card>
|
||||
<div class="goods-tab">
|
||||
<el-tabs v-model="currentStatus" @tab-click="onStatusTabClick">
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in goodsStatusWithCount"
|
||||
:key="index"
|
||||
:label="item.title"
|
||||
:name="item.value"
|
||||
/>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<!-- 批量操作按钮 -->
|
||||
<div class="batch-operations" style="margin: 10px 0;">
|
||||
<Button
|
||||
<div class="batch-operations" style="margin: 10px 0">
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="selectedRows.length === 0"
|
||||
style="margin-right: 10px"
|
||||
@click="openSetGoodsGroup"
|
||||
style="margin-right: 10px;"
|
||||
>
|
||||
批量设置分组
|
||||
</Button>
|
||||
<Button
|
||||
</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
:disabled="selectedRows.length === 0"
|
||||
style="margin-right: 10px"
|
||||
@click="batchUpper"
|
||||
style="margin-right: 10px;"
|
||||
>
|
||||
批量上架
|
||||
</Button>
|
||||
<Button
|
||||
</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
:disabled="selectedRows.length === 0"
|
||||
style="margin-right: 10px"
|
||||
@click="batchLower"
|
||||
style="margin-right: 10px;"
|
||||
>
|
||||
批量下架
|
||||
</Button>
|
||||
<Button
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="currentStatus === 'TOBEAUDITED'"
|
||||
type="primary"
|
||||
:disabled="selectedRows.length === 0"
|
||||
@click="batchAudit"
|
||||
>
|
||||
批量审核
|
||||
</Button>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
@on-select="onSelect"
|
||||
@on-select-all="onSelectAll"
|
||||
@on-selection-change="onSelectionChange"
|
||||
row-key="id"
|
||||
@selection-change="onSelectionChange"
|
||||
>
|
||||
<!-- 商品图片格式化 -->
|
||||
<template slot="imageSlot" slot-scope="{ row }">
|
||||
<div style="margin-top: 5px;">
|
||||
<el-table-column type="selection" width="100" align="center" />
|
||||
<el-table-column prop="id" label="商品ID" width="200" show-overflow-tooltip />
|
||||
<el-table-column label="商品图片" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<img
|
||||
v-if="row && row.original"
|
||||
:src="row.original"
|
||||
style="height: 50px; width: 50px; object-fit: cover;"
|
||||
style="height: 50px; width: 50px; object-fit: cover"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" min-width="200" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<a class="link-text" @click="linkTo(row.id, row.skuId)">{{ row.goodsName }}</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="价格" width="200">
|
||||
<template #default="{ row }">
|
||||
<span :style="{ color: $mainColor }">{{ $filters.unitPrice(row.price, '¥') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="buyCount" label="销量" width="150" />
|
||||
<el-table-column prop="quantity" label="库存" width="150" />
|
||||
<el-table-column label="销售模式" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ salesModelText(row.salesModel) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品类型" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ goodsTypeText(row.goodsType) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ marketEnableText(row.marketEnable) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" width="150">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ authFlagText(row.authFlag) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="storeName" label="店铺名称" width="200" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row.authFlag === 'TOBEAUDITED'">
|
||||
<a class="link-text" @click="openAuditModal(row)">审核</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="showDetail(row)">查看</a>
|
||||
</template>
|
||||
<template v-else-if="row.marketEnable === 'DOWN'">
|
||||
<a class="link-text" @click="upper(row)">上架</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="showDetail(row)">查看</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a class="link-text" @click="edit(row)">下架</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="showDetail(row)">查看</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 商品栏目格式化 -->
|
||||
<template slot="goodsSlot" slot-scope="{ row }">
|
||||
<div style="margin: 5px 0px; padding: 10px 0px;">
|
||||
<div class="div-zoom">
|
||||
<a @click="linkTo(row.id, row.skuId)">{{ row.goodsName }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal
|
||||
title="下架操作"
|
||||
v-model="modalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="underForm" :model="underForm" :label-width="100">
|
||||
<FormItem label="下架原因" prop="reason">
|
||||
<Input v-model="underForm.reason" clearable style="width: 100%" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="lower"
|
||||
>提交</Button
|
||||
>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal
|
||||
title="商品审核"
|
||||
v-model="auditModalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="auditForm" :model="goodsAuditForm" :label-width="100">
|
||||
<FormItem label="审核结果" prop="auth_flag">
|
||||
<RadioGroup v-model="goodsAuditForm.auth_flag">
|
||||
<Radio :label="1">审核通过</Radio>
|
||||
<Radio :label="2">审核拒绝</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<!-- <FormItem label="审核备注" prop="reason" v-if="goodsAuditForm.auth_flag === 2">
|
||||
<Input v-model="goodsAuditForm.reason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
|
||||
</FormItem> -->
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="auditModalVisible = false">取消</Button>
|
||||
<Button type="primary" @click="confirmAudit">提交审核</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<!-- 批量审核弹框 -->
|
||||
<Modal
|
||||
title="批量商品审核"
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="modalVisible" title="下架操作" width="500px" :close-on-click-modal="false">
|
||||
<el-form ref="underForm" :model="underForm" label-width="100px">
|
||||
<el-form-item label="下架原因" prop="reason">
|
||||
<el-input v-model="underForm.reason" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="lower">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="auditModalVisible" title="商品审核" width="500px" :close-on-click-modal="false">
|
||||
<el-form ref="auditForm" :model="goodsAuditForm" label-width="100px">
|
||||
<el-form-item label="审核结果" prop="auth_flag">
|
||||
<el-radio-group v-model="goodsAuditForm.auth_flag">
|
||||
<el-radio :value="1">审核通过</el-radio>
|
||||
<el-radio :value="2">审核拒绝</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="auditModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="confirmAudit">提交审核</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
v-model="batchAuditModalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
title="批量商品审核"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<Form ref="batchAuditForm" :model="batchAuditForm" :label-width="100">
|
||||
<FormItem label="审核结果" prop="auth_flag">
|
||||
<RadioGroup v-model="batchAuditForm.auth_flag">
|
||||
<Radio :label="1">审核通过</Radio>
|
||||
<Radio :label="2">审核拒绝</Radio>
|
||||
</RadioGroup>
|
||||
</FormItem>
|
||||
<FormItem label="审核备注" prop="reason" v-if="batchAuditForm.auth_flag === 2">
|
||||
<Input v-model="batchAuditForm.reason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
|
||||
</FormItem>
|
||||
<FormItem label="选中商品">
|
||||
<div style="max-height: 200px; overflow-y: auto;">
|
||||
<Tag v-for="item in selectedRows" :key="item.id" style="margin: 2px;">{{item.goodsName}}</Tag>
|
||||
<el-form ref="batchAuditForm" :model="batchAuditForm" label-width="100px">
|
||||
<el-form-item label="审核结果" prop="auth_flag">
|
||||
<el-radio-group v-model="batchAuditForm.auth_flag">
|
||||
<el-radio :value="1">审核通过</el-radio>
|
||||
<el-radio :value="2">审核拒绝</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="batchAuditForm.auth_flag === 2" label="审核备注" prop="reason">
|
||||
<el-input v-model="batchAuditForm.reason" type="textarea" :rows="3" placeholder="请输入拒绝原因" />
|
||||
</el-form-item>
|
||||
<el-form-item label="选中商品">
|
||||
<div style="max-height: 200px; overflow-y: auto">
|
||||
<el-tag v-for="item in selectedRows" :key="item.id" style="margin: 2px">{{ item.goodsName }}</el-tag>
|
||||
</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="batchAuditModalVisible = false">取消</Button>
|
||||
<Button type="primary" @click="submitBatchAudit">提交审核</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal v-model="goodsGroupFlag" title="批量设置商品分组" width="420">
|
||||
<Form ref="goodsGroupForm" :model="goodsGroupForm" :rules="goodsGroupRule" :label-width="90">
|
||||
<FormItem label="商品分组" prop="groupId">
|
||||
<Select v-model="goodsGroupForm.groupId" clearable filterable style="width: 240px">
|
||||
<Option v-for="item in goodsGroupList" :value="item.id" :key="item.id">{{ item.groupName }}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="goodsGroupFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="goodsGroupLoading" @click="submitSetGoodsGroup">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="batchAuditModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitBatchAudit">提交审核</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="goodsGroupFlag" title="批量设置商品分组" width="420px">
|
||||
<el-form ref="goodsGroupForm" :model="goodsGroupForm" :rules="goodsGroupRule" label-width="90px">
|
||||
<el-form-item label="商品分组" prop="groupId">
|
||||
<el-select v-model="goodsGroupForm.groupId" clearable filterable style="width: 240px">
|
||||
<el-option
|
||||
v-for="item in goodsGroupList"
|
||||
:key="item.id"
|
||||
:label="item.groupName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="goodsGroupFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="goodsGroupLoading" @click="submitSetGoodsGroup">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -261,11 +297,7 @@ import {
|
||||
getGoodsGroupByPage,
|
||||
addGoodsGroupItems
|
||||
} from "@/api/goods";
|
||||
import vueQr from "vue-qr";
|
||||
export default {
|
||||
components: {
|
||||
"vue-qr": vueQr,
|
||||
},
|
||||
name: "goods",
|
||||
data() {
|
||||
return {
|
||||
@@ -291,259 +323,10 @@ export default {
|
||||
auditModalVisible: false, // 审核弹框显示状态
|
||||
currentAuditGoods: null, // 当前审核的商品
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
columns: [
|
||||
{
|
||||
type: 'selection',
|
||||
width: 60,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: "商品ID",
|
||||
key: "id",
|
||||
width: 180,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品图片",
|
||||
key: "original",
|
||||
width: 180,
|
||||
slot: "imageSlot",
|
||||
},
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 180,
|
||||
slot: "goodsSlot",
|
||||
},
|
||||
{
|
||||
title: "价格",
|
||||
key: "price",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "销量",
|
||||
key: "buyCount",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("span", params.row.buyCount || 0);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h("span", params.row.quantity || 0);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "销售模式",
|
||||
key: "salesModel",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
if (params.row.salesModel === "RETAIL") {
|
||||
return h("Tag", { props: { color: "orange" } }, "零售");
|
||||
} else if (params.row.salesModel === "WHOLESALE") {
|
||||
return h("Tag", { props: { color: "magenta" } }, "批发");
|
||||
} else {
|
||||
return h("Tag", { props: { color: "volcano" } }, "其他类型");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "商品类型",
|
||||
key: "goodsType",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.goodsType === "PHYSICAL_GOODS") {
|
||||
return h("Tag", { props: { color: "green" } }, "实物商品");
|
||||
} else if (params.row.goodsType === "VIRTUAL_GOODS") {
|
||||
return h("Tag", { props: { color: "volcano" } }, "虚拟商品");
|
||||
} else {
|
||||
return h("Tag", { props: { color: "geekblue" } }, "电子卡券");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "marketEnable",
|
||||
width: 120,
|
||||
render: (h, params) => {
|
||||
if (params.row.marketEnable == "DOWN") {
|
||||
return h("Tag", { props: { color: "volcano" } }, "下架");
|
||||
} else if (params.row.marketEnable == "UPPER") {
|
||||
return h("Tag", { props: { color: "green" } }, "上架");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "审核状态",
|
||||
key: "authFlag",
|
||||
width: 180,
|
||||
render: (h, params) => {
|
||||
if (params.row.authFlag == "TOBEAUDITED") {
|
||||
return h("Tag", { props: { color: "volcano" } }, "待审核");
|
||||
} else if (params.row.authFlag == "PASS") {
|
||||
return h("Tag", { props: { color: "green" } }, "通过");
|
||||
} else if (params.row.authFlag == "REFUSE") {
|
||||
return h("Tag", { props: { color: "red" } }, "拒绝");
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
width: 180, // 使用minWidth替代width
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
// 如果是待审核状态,显示审核按钮
|
||||
if (params.row.authFlag === "TOBEAUDITED") {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.openAuditModal(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"审核"
|
||||
),
|
||||
h("span", {
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2"
|
||||
}
|
||||
}, "|"),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showDetail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
}
|
||||
// 原有的上架/下架逻辑
|
||||
else if (params.row.marketEnable == "DOWN") {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.upper(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"上架"
|
||||
),
|
||||
h("span", {
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2"
|
||||
}
|
||||
}, "|"),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showDetail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.edit(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"下架"
|
||||
),
|
||||
h("span", {
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2"
|
||||
}
|
||||
}, "|"),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showDetail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
currentStatus: '',
|
||||
currentStatus: "ALL",
|
||||
goodsNumerData: {},
|
||||
goodsAuditForm: {
|
||||
// 商品编辑表单
|
||||
auth_flag: 1,
|
||||
},
|
||||
selectedRows: [], // 选中的行数据
|
||||
selectAll: false, // 全选状态
|
||||
batchAuditModalVisible: false, // 批量审核弹框显示状态
|
||||
@@ -565,7 +348,7 @@ export default {
|
||||
computed: {
|
||||
goodsStatusWithCount() {
|
||||
return [
|
||||
{title: '全部', value: ''},
|
||||
{title: '全部', value: 'ALL'},
|
||||
{title: `出售中${this.goodsNumerData.upperGoodsNum ? '(' + this.goodsNumerData.upperGoodsNum + ')' : ''}`, value: 'UPPER'},
|
||||
{title: `仓库中${this.goodsNumerData.downGoodsNum ? '(' + this.goodsNumerData.downGoodsNum + ')' : ''}`, value: 'DOWN'},
|
||||
{title: `待审核${this.goodsNumerData.auditGoodsNum ? '(' + this.goodsNumerData.auditGoodsNum + ')' : ''}`, value: 'TOBEAUDITED'},
|
||||
@@ -574,6 +357,33 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clearTableSelection() {
|
||||
this.$refs.table?.clearSelection?.();
|
||||
},
|
||||
onStatusTabClick(tab) {
|
||||
this.goodsStatusClick(tab.paneName);
|
||||
},
|
||||
salesModelText(v) {
|
||||
if (v === "RETAIL") return "零售";
|
||||
if (v === "WHOLESALE") return "批发";
|
||||
return "其他类型";
|
||||
},
|
||||
goodsTypeText(v) {
|
||||
if (v === "PHYSICAL_GOODS") return "实物商品";
|
||||
if (v === "VIRTUAL_GOODS") return "虚拟商品";
|
||||
return "电子卡券";
|
||||
},
|
||||
marketEnableText(v) {
|
||||
if (v === "DOWN") return "下架";
|
||||
if (v === "UPPER") return "上架";
|
||||
return "";
|
||||
},
|
||||
authFlagText(v) {
|
||||
if (v === "TOBEAUDITED") return "待审核";
|
||||
if (v === "PASS") return "通过";
|
||||
if (v === "REFUSE") return "拒绝";
|
||||
return "";
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
@@ -667,31 +477,23 @@ export default {
|
||||
|
||||
//查看商品详情
|
||||
showDetail(v) {
|
||||
let id = v.id;
|
||||
this.$options.filters.customRouterPush({
|
||||
this.$filters.customRouterPush({
|
||||
name: "goods-detail",
|
||||
query: { id: id },
|
||||
})
|
||||
query: { id: v.id },
|
||||
});
|
||||
},
|
||||
|
||||
// 商品状态筛选
|
||||
goodsStatusClick(item) {
|
||||
// 根据选择的状态设置搜索条件
|
||||
if (item === 0) {
|
||||
// 全部:清除状态筛选
|
||||
goodsStatusClick(name) {
|
||||
if (name === "ALL" || name === "" || name === undefined || name === null) {
|
||||
delete this.searchForm.goodsStatus;
|
||||
this.currentStatus = "ALL";
|
||||
} else {
|
||||
// 其他状态正常赋值
|
||||
this.searchForm.goodsStatus = item;
|
||||
this.searchForm.goodsStatus = name;
|
||||
this.currentStatus = name;
|
||||
}
|
||||
this.currentStatus = item;
|
||||
|
||||
// tab切换时清除选中内容
|
||||
this.selectedRows = [];
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.selectAll(false);
|
||||
}
|
||||
|
||||
this.clearTableSelection();
|
||||
this.getDataList();
|
||||
},
|
||||
examine(v, authFlag) {
|
||||
@@ -762,15 +564,6 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
// 选择框事件处理
|
||||
onSelect(selection, row) {
|
||||
// 单行选择时触发
|
||||
},
|
||||
|
||||
onSelectAll(selection) {
|
||||
// 全选时触发
|
||||
},
|
||||
|
||||
onSelectionChange(selection) {
|
||||
this.selectedRows = selection;
|
||||
},
|
||||
@@ -939,9 +732,7 @@ export default {
|
||||
this.goodsGroupFlag = false;
|
||||
this.selectedRows = [];
|
||||
this.selectAll = false;
|
||||
if (this.$refs.table && this.$refs.table.selectAll) {
|
||||
this.$refs.table.selectAll(false);
|
||||
}
|
||||
this.clearTableSelection();
|
||||
this.getDataList();
|
||||
} else if (res && res.message) {
|
||||
this.$Message.error(res.message);
|
||||
@@ -961,7 +752,7 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
// Tab组件样式
|
||||
.goods-tab {
|
||||
::v-deep .ivu-tabs-tab {
|
||||
:deep(.el-tabs__item) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +1,93 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
@keydown.enter.native="handleSearch"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input
|
||||
type="text"
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="商品编号" prop="id">
|
||||
<Input
|
||||
type="text"
|
||||
</el-form-item>
|
||||
<el-form-item label="商品编号" prop="id">
|
||||
<el-input
|
||||
v-model="searchForm.id"
|
||||
placeholder="请输入商品编号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" class="search-btn" type="primary" icon="ios-search"
|
||||
>搜索</Button
|
||||
>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
class="mt_10"
|
||||
>
|
||||
<!-- 商品栏目格式化 -->
|
||||
<template slot="goodsSlot" slot-scope="scope">
|
||||
<div style="margin-top: 5px; height: 80px; display: flex">
|
||||
<div style="">
|
||||
<img
|
||||
:src="scope.row.original"
|
||||
style="height: 60px; margin-top: 3px; width: 60px"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<div style="margin-left: 13px">
|
||||
<div class="div-zoom">
|
||||
<a>{{ scope.row.goodsName }}</a>
|
||||
<el-card>
|
||||
<el-table v-loading="loading" :data="data" ref="table" class="mt_10" style="width: 100%">
|
||||
<el-table-column label="商品名称" min-width="200" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" style="margin-top: 5px; height: 80px; display: flex; align-items: flex-start">
|
||||
<img
|
||||
v-if="row.original"
|
||||
:src="row.original"
|
||||
style="height: 60px; width: 60px; object-fit: cover; margin-top: 3px"
|
||||
alt=""
|
||||
/>
|
||||
<div style="margin-left: 13px">
|
||||
<div class="div-zoom">
|
||||
<a class="link-text">{{ row.goodsName }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="id" label="商品编号" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="价格" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row" :style="{ color: $mainColor }">{{ $filters.unitPrice(row.price, "¥") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" min-width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="authFlagTagType(row.authFlag)">{{ authFlagText(row.authFlag) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="storeName" label="店铺名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="examine(row, 1)">通过</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="examine(row, 2)">拒绝</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="showDetail(row)">查看</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -81,214 +95,82 @@
|
||||
import { authGoods, getAuthGoodsListData } from "@/api/goods";
|
||||
|
||||
export default {
|
||||
name: "goods",
|
||||
components: {},
|
||||
name: "goodsApply",
|
||||
data() {
|
||||
return {
|
||||
id: "", //要操作的id
|
||||
loading: true, // 表单加载状态
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "create_time", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
},
|
||||
goodsAuditForm: {
|
||||
// 商品编辑表单
|
||||
auth_flag: 1,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 180,
|
||||
slot: "goodsSlot",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品编号",
|
||||
key: "id",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "价格",
|
||||
key: "price",
|
||||
minWidth: 130,
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "审核状态",
|
||||
key: "authFlag",
|
||||
minWidth: 130,
|
||||
render: (h, params) => {
|
||||
if (params.row.authFlag == "TOBEAUDITED") {
|
||||
return h("div", [
|
||||
h("Badge", {
|
||||
props: {
|
||||
status: "error",
|
||||
text: "待审核",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
} else if (params.row.authFlag == "PASS") {
|
||||
return h("div", [
|
||||
h("Badge", {
|
||||
props: {
|
||||
status: "success",
|
||||
text: "审核通过",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
} else if (params.row.authFlag == "REFUSE") {
|
||||
return h("div", [
|
||||
h("Badge", {
|
||||
props: {
|
||||
status: "error",
|
||||
text: "审核拒绝",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
title: "店铺名称",
|
||||
key: "storeName",
|
||||
minWidth: 100,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 200,
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
marginRight: "5px",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.examine(params.row, 1);
|
||||
},
|
||||
},
|
||||
},
|
||||
"通过"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
marginRight: "5px",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.examine(params.row, 2);
|
||||
},
|
||||
},
|
||||
},
|
||||
"拒绝"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none"
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.showDetail(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
authFlagText(v) {
|
||||
const map = {
|
||||
TOBEAUDITED: "待审核",
|
||||
PASS: "审核通过",
|
||||
REFUSE: "审核拒绝",
|
||||
};
|
||||
return map[v] || v || "-";
|
||||
},
|
||||
authFlagTagType(v) {
|
||||
const map = {
|
||||
TOBEAUDITED: "warning",
|
||||
PASS: "success",
|
||||
REFUSE: "danger",
|
||||
};
|
||||
return map[v] || "info";
|
||||
},
|
||||
init() {
|
||||
// 初始化数据
|
||||
this.getDataList();
|
||||
},
|
||||
changePage(v) {
|
||||
// 改变页码
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
changePageSize(v) {
|
||||
// 改变每页数量
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
handleSearch() {
|
||||
// 搜索
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
getDataList() {
|
||||
// 获取列表数据
|
||||
this.loading = true;
|
||||
// 带多条件搜索参数获取表单数据
|
||||
this.searchForm.authFlag = 0;
|
||||
getAuthGoodsListData(this.searchForm).then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
});
|
||||
getAuthGoodsListData(this.searchForm)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
this.data = res.result.records;
|
||||
this.total = res.result.total;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
examine(v, authFlag) {
|
||||
// 审核商品
|
||||
let examine = "通过";
|
||||
this.goodsAuditForm.authFlag = "PASS";
|
||||
if (authFlag != 1) {
|
||||
examine = "拒绝";
|
||||
this.goodsAuditForm.authFlag = "REFUSE";
|
||||
}
|
||||
const examine = authFlag === 1 ? "通过" : "拒绝";
|
||||
this.goodsAuditForm.authFlag = authFlag === 1 ? "PASS" : "REFUSE";
|
||||
this.$Modal.confirm({
|
||||
title: "确认审核",
|
||||
content: "您确认要审核" + examine + " " + v.goodsName + " ?",
|
||||
content: `您确认要审核${examine} ${v.goodsName} ?`,
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
let formData = new FormData();
|
||||
formData.append('goodsIds', v.id);
|
||||
formData.append('authFlag', this.goodsAuditForm.authFlag);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("goodsIds", v.id);
|
||||
formData.append("authFlag", this.goodsAuditForm.authFlag);
|
||||
authGoods(formData).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -299,13 +181,11 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
//查看商品详情
|
||||
showDetail(v) {
|
||||
let id = v.id;
|
||||
this.$options.filters.customRouterPush({
|
||||
this.$filters.customRouterPush({
|
||||
name: "goods-detail",
|
||||
query: { id: id },
|
||||
})
|
||||
query: { id: v.id },
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
@@ -313,3 +193,20 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.op-split {
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
.div-zoom {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,247 +1,159 @@
|
||||
<template>
|
||||
<div>
|
||||
<Form :label-width="120">
|
||||
<Card>
|
||||
<el-form label-width="120px">
|
||||
<el-card>
|
||||
<div class="base-info-item">
|
||||
<h4>基本信息</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="商品分类">
|
||||
<el-form-item label="商品分类">
|
||||
<span v-for="(item, index) in goods.categoryName" :key="index">
|
||||
{{ item }}
|
||||
<i v-if="index !== goods.categoryName.length - 1">></i>
|
||||
</span>
|
||||
</FormItem>
|
||||
<FormItem label="商品名称">
|
||||
{{ goods.goodsName }}
|
||||
</FormItem>
|
||||
|
||||
<FormItem label="商品卖点">
|
||||
{{ goods.sellingPoint }}
|
||||
</FormItem>
|
||||
<FormItem label="商品参数">
|
||||
<div v-if="goods.goodsParamsDTOList && goods.goodsParamsDTOList.length" v-for="(item,index) in goods.goodsParamsDTOList" :key="index">
|
||||
<div style="margin-bottom: 10px; display: flex; align-items: center;" >
|
||||
{{ item.groupName }} : <tag v-for="(child,i) in item.goodsParamsItemDTOList" :key="i">
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称">{{ goods.goodsName }}</el-form-item>
|
||||
<el-form-item label="商品卖点">{{ goods.sellingPoint }}</el-form-item>
|
||||
<el-form-item label="商品参数">
|
||||
<div
|
||||
v-if="goods.goodsParamsDTOList && goods.goodsParamsDTOList.length"
|
||||
v-for="(item, index) in goods.goodsParamsDTOList"
|
||||
:key="index"
|
||||
style="margin-bottom: 10px; display: flex; align-items: center"
|
||||
>
|
||||
{{ item.groupName }} :
|
||||
<el-tag v-for="(child, i) in item.goodsParamsItemDTOList" :key="i" style="margin-left: 4px">
|
||||
{{ child.paramName }} - {{ child.paramValue }}
|
||||
</tag>
|
||||
</div>
|
||||
</div>
|
||||
</FormItem>
|
||||
</el-tag>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<h4>商品交易信息</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="计量单位"> {{ goods.goodsUnit }}</FormItem>
|
||||
<FormItem label="销售模式">
|
||||
<el-form-item label="计量单位">{{ goods.goodsUnit }}</el-form-item>
|
||||
<el-form-item label="销售模式">
|
||||
{{ goods.salesModel === "RETAIL" ? "零售型" : "批发型" }}
|
||||
</FormItem>
|
||||
<FormItem label="销售规则" v-if="goods.salesModel !== 'RETAIL'">
|
||||
<Table
|
||||
border
|
||||
:columns="wholesalePreviewColumns"
|
||||
:data="wholesaleData"
|
||||
>
|
||||
</Table>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="goods.salesModel !== 'RETAIL'" label="销售规则">
|
||||
<el-table border :data="wholesaleData" style="width: 100%">
|
||||
<el-table-column label="销售规则" width="300">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">
|
||||
当商品购买数量 ≥{{ row.num }} 时,售价为 ¥{{ row.price }} /{{ goods.goodsUnit }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<h4>商品规格及图片</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="商品编号"> {{ goods.id }}</FormItem>
|
||||
<FormItem label="商品价格">
|
||||
<priceColorScheme :value="goods.price" :color="$mainColor"></priceColorScheme>
|
||||
|
||||
</FormItem>
|
||||
<FormItem label="商品图片">
|
||||
<el-form-item label="商品编号">{{ goods.id }}</el-form-item>
|
||||
<el-form-item label="商品价格">
|
||||
<priceColorScheme :value="goods.price" :color="$mainColor" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品图片">
|
||||
<div
|
||||
class="demo-upload-list"
|
||||
v-for="(item, __index) in goods.goodsGalleryList"
|
||||
:key="__index"
|
||||
class="demo-upload-list"
|
||||
>
|
||||
<img :src="item" />
|
||||
<div class="demo-upload-list-cover">
|
||||
<Icon
|
||||
type="ios-eye-outline"
|
||||
@click.native="handleViewGoodsPicture(item)"
|
||||
></Icon>
|
||||
<el-icon class="preview-icon" @click="handleViewGoodsPicture(item)"><View /></el-icon>
|
||||
</div>
|
||||
<Modal title="View Image" v-model="goodsPictureVisible">
|
||||
<img
|
||||
:src="previewGoodsPicture"
|
||||
v-if="goodsPictureVisible"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="商品视频">
|
||||
<video
|
||||
v-if="goods.goodsVideo"
|
||||
controls
|
||||
class="player"
|
||||
:src="goods.goodsVideo"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="商品规格">
|
||||
<Table :columns="skuColumn" :data="skuData">
|
||||
<template slot="showImage" slot-scope="scope">
|
||||
<div style="margin-top: 5px; display: flex">
|
||||
<div>
|
||||
<el-dialog v-model="goodsPictureVisible" title="View Image" width="600px">
|
||||
<img v-if="goodsPictureVisible" :src="previewGoodsPicture" style="width: 100%" />
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品视频">
|
||||
<video v-if="goods.goodsVideo" controls class="player" :src="goods.goodsVideo" />
|
||||
</el-form-item>
|
||||
<el-form-item label="商品规格">
|
||||
<el-table :data="skuData" style="width: 100%">
|
||||
<el-table-column prop="specs" label="规格" />
|
||||
<el-table-column prop="sn" label="编号" />
|
||||
<el-table-column prop="weight" label="重量(kg)" />
|
||||
<el-table-column
|
||||
v-for="(item, index) in wholesaleData"
|
||||
:key="'wp' + index"
|
||||
:label="'购买量 ≥ ' + item.num"
|
||||
>
|
||||
<template #default>
|
||||
<el-input v-if="wholesaleData[index]" v-model="wholesaleData[index].price" disabled>
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="goods.salesModel !== 'WHOLESALE'" label="价格">
|
||||
<template #default="{ row }">
|
||||
<priceColorScheme v-if="row" :value="row.price" :color="$mainColor" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="goods.salesModel !== 'WHOLESALE'" prop="quantity" label="库存" />
|
||||
<el-table-column label="图片">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" style="margin-top: 5px; display: flex">
|
||||
<img
|
||||
v-for="(item,index) in scope.row.image"
|
||||
v-for="(item, index) in row.image"
|
||||
:key="index"
|
||||
:src="item"
|
||||
style="height: 60px; margin:10px; width: 60px"
|
||||
style="height: 60px; margin: 10px; width: 60px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="wholePrice0">
|
||||
<Input
|
||||
v-if="wholesaleData[0]"
|
||||
clearable
|
||||
disabled
|
||||
v-model="wholesaleData[0].price"
|
||||
>
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="wholePrice1">
|
||||
<Input
|
||||
v-if="wholesaleData[1]"
|
||||
clearable
|
||||
disabled
|
||||
v-model="wholesaleData[1].price"
|
||||
>
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
<template slot-scope="{ row }" slot="wholePrice2">
|
||||
<Input
|
||||
v-if="wholesaleData[2]"
|
||||
clearable
|
||||
disabled
|
||||
v-model="wholesaleData[2].price"
|
||||
>
|
||||
<span slot="append">元</span>
|
||||
</Input>
|
||||
</template>
|
||||
</Table>
|
||||
</FormItem>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<h4>商品详情描述</h4>
|
||||
<div class="form-item-view">
|
||||
<FormItem label="商品描述">
|
||||
<el-form-item label="商品描述">
|
||||
<div v-html="goods.intro"></div>
|
||||
</FormItem>
|
||||
<FormItem label="移动端描述">
|
||||
</el-form-item>
|
||||
<el-form-item label="移动端描述">
|
||||
<div v-html="goods.mobileIntro"></div>
|
||||
</FormItem>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Form>
|
||||
</el-card>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { View } from "@element-plus/icons-vue";
|
||||
import { getGoodsDetail } from "@/api/goods";
|
||||
|
||||
export default {
|
||||
name: "goodsDetail",
|
||||
components: { View },
|
||||
data() {
|
||||
return {
|
||||
goods: {}, // 商品信息
|
||||
previewGoodsPicture: "", // 预览图片
|
||||
goodsPictureVisible: false, // 预览图片模态框
|
||||
wholesalePreviewColumns: [
|
||||
{
|
||||
title: "销售规则",
|
||||
width: 300,
|
||||
render: (h, params) => {
|
||||
let guide =
|
||||
"当商品购买数量 ≥" +
|
||||
params.row.num +
|
||||
" 时,售价为 ¥" +
|
||||
params.row.price +
|
||||
" /" +
|
||||
this.goods.goodsUnit;
|
||||
return h("div", guide);
|
||||
},
|
||||
},
|
||||
],
|
||||
goods: {},
|
||||
previewGoodsPicture: "",
|
||||
goodsPictureVisible: false,
|
||||
wholesaleData: [],
|
||||
skuColumn: [
|
||||
// 规格表头
|
||||
{
|
||||
title: "规格",
|
||||
key: "specs",
|
||||
},
|
||||
{
|
||||
title: "编号",
|
||||
key: "sn",
|
||||
},
|
||||
{
|
||||
title: "重量(kg)",
|
||||
key: "weight",
|
||||
},
|
||||
],
|
||||
skuData: [], // sku数据
|
||||
skuData: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.initGoods(this.$route.query.id);
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据,获取商品详情
|
||||
initGoods(id) {
|
||||
getGoodsDetail(id).then((res) => {
|
||||
this.goods = res.result;
|
||||
let that = this;
|
||||
res.result.skuList.forEach(function (sku, index, array) {
|
||||
that.skuData.push({
|
||||
specs: sku.goodsName,
|
||||
sn: sku.sn,
|
||||
weight: sku.weight,
|
||||
cost: sku.cost,
|
||||
price:sku.price,
|
||||
image: sku.goodsGalleryList,
|
||||
quantity:sku.quantity
|
||||
});
|
||||
});
|
||||
if (res.result.salesModel === "WHOLESALE" && res.result.wholesaleList) {
|
||||
res.result.wholesaleList.forEach((item, index) => {
|
||||
this.skuColumn.push({
|
||||
title: "购买量 ≥ " + item.num,
|
||||
slot: "wholePrice" + index,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.skuColumn.push(
|
||||
// {
|
||||
// title: "成本",
|
||||
// key: "cost",
|
||||
// render: (h, params) => {
|
||||
// console.log(params)
|
||||
// return h("priceColorScheme", {props:{value:params.row.cost,color:this.$mainColor}} );
|
||||
// },
|
||||
// },
|
||||
{
|
||||
title: "价格",
|
||||
key: "price",
|
||||
render: (h, params) => {
|
||||
return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} );
|
||||
},
|
||||
},{
|
||||
title: "库存",
|
||||
key: "quantity",
|
||||
}
|
||||
);
|
||||
}
|
||||
this.skuColumn.push({
|
||||
title: "图片",
|
||||
slot: "showImage",
|
||||
});
|
||||
this.wholesaleData = res.result.wholesaleList;
|
||||
this.skuData = res.result.skuList.map((sku) => ({
|
||||
specs: sku.goodsName,
|
||||
sn: sku.sn,
|
||||
weight: sku.weight,
|
||||
cost: sku.cost,
|
||||
price: sku.price,
|
||||
image: sku.goodsGalleryList,
|
||||
quantity: sku.quantity,
|
||||
}));
|
||||
this.wholesaleData = res.result.wholesaleList || [];
|
||||
});
|
||||
},
|
||||
// 预览商品图片
|
||||
handleViewGoodsPicture(url) {
|
||||
this.previewGoodsPicture = url;
|
||||
this.goodsPictureVisible = true;
|
||||
@@ -251,7 +163,6 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" soped>
|
||||
/*平铺*/
|
||||
div.base-info-item {
|
||||
h4 {
|
||||
margin-bottom: 10px;
|
||||
@@ -300,13 +211,10 @@ div.base-info-item {
|
||||
.demo-upload-list:hover .demo-upload-list-cover {
|
||||
display: block;
|
||||
}
|
||||
.demo-upload-list-cover i {
|
||||
.preview-icon {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
}
|
||||
.ivu-table table {
|
||||
width: 100% !important;
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,74 +1,148 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="searchForm" @submit.native.prevent @keydown.enter.native="handleSearch" :model="searchForm" inline :label-width="70"
|
||||
class="search-form">
|
||||
<Form-item label="品牌名称">
|
||||
<Input type="text" v-model="searchForm.name" placeholder="请输入品牌名称" clearable style="width: 240px"/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button @click="add" type="primary">添加</Button>
|
||||
</Row>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
|
||||
@on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]" size="small"
|
||||
show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal :title="modalTitle" v-model="modalVisible" :mask-closable="false" :width="500">
|
||||
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
|
||||
<FormItem label="品牌名称" prop="name">
|
||||
<Input v-model="form.name" clearable style="width: 100%"/>
|
||||
</FormItem>
|
||||
<FormItem label="品牌图标" prop="logo">
|
||||
<div style="display: flex; align-items: center; gap: 12px;">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="品牌名称">
|
||||
<el-input
|
||||
v-model="searchForm.name"
|
||||
placeholder="请输入品牌名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" @click="add">添加</el-button>
|
||||
</div>
|
||||
|
||||
<el-table ref="table" v-loading="loading" border :data="data" style="width: 100%">
|
||||
<el-table-column prop="name" label="品牌名称" width="200" />
|
||||
<el-table-column label="品牌图标" align="left" >
|
||||
<template #default="{ row }">
|
||||
<img
|
||||
v-if="row"
|
||||
:src="row.logo || ''"
|
||||
alt="加载图片失败"
|
||||
style="cursor: pointer; width: 80px; height: 60px; margin: 10px 0; object-fit: contain"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="left" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
:model-value="row.deleteFlag == 0"
|
||||
inline-prompt
|
||||
active-text="启用"
|
||||
inactive-text="禁用"
|
||||
@change="(val) => handleStatusSwitchChange(row, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="170" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="230" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<template v-if="row">
|
||||
<a class="link-text" @click="edit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="openCategoryModal(row)">关联分类</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="delBrand(row.id)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
|
||||
<el-form-item label="品牌名称" prop="name">
|
||||
<el-input v-model="form.name" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="品牌图标" prop="logo">
|
||||
<div style="display: flex; align-items: center; gap: 12px">
|
||||
<img
|
||||
:src="form.logo || defaultPic"
|
||||
alt="品牌图标"
|
||||
style="width: 80px; height: 60px; object-fit: contain; border: 1px solid #dcdee2; border-radius: 4px; background: #fff;"
|
||||
style="width: 80px; height: 60px; object-fit: contain; border: 1px solid #dcdee2; border-radius: 4px; background: #fff"
|
||||
/>
|
||||
<Button type="text" @click="openLogoPicker">修改</Button>
|
||||
<el-button type="primary" link @click="openLogoPicker">修改</el-button>
|
||||
</div>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<Modal width="1200px" v-model="picModelFlag" footer-hide>
|
||||
<ossManage @callback="callbackSelected" :isComponent="true" :initialize="picModelFlag" ref="ossManage" />
|
||||
</Modal>
|
||||
<el-dialog v-model="picModelFlag" width="1200px" :show-close="true">
|
||||
<ossManage
|
||||
ref="ossManage"
|
||||
:is-component="true"
|
||||
:initialize="picModelFlag"
|
||||
@callback="callbackSelected"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<Modal
|
||||
:title="categoryModalTitle"
|
||||
<el-dialog
|
||||
v-model="categoryModalVisible"
|
||||
:mask-closable="false"
|
||||
:width="700"
|
||||
:title="categoryModalTitle"
|
||||
width="700px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div style="position: relative; max-height: 520px; overflow: auto;">
|
||||
<Spin size="large" fix v-if="categoryTreeLoading"></Spin>
|
||||
<Tree
|
||||
<div v-loading="categoryTreeLoading" style="position: relative; max-height: 520px; overflow: auto">
|
||||
<el-tree
|
||||
ref="categoryTree"
|
||||
:key="categoryTreeKey"
|
||||
:data="categoryTreeData"
|
||||
:props="{ label: 'title', children: 'children' }"
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
@on-check-change="onCategoryTreeCheckChange"
|
||||
></Tree>
|
||||
default-expand-all
|
||||
:default-checked-keys="selectedCategoryIds"
|
||||
@check="onCategoryTreeCheckChange"
|
||||
/>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="categoryModalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="categorySubmitLoading" @click="submitBrandCategory"
|
||||
>提交</Button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="categoryModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="categorySubmitLoading" @click="submitBrandCategory">
|
||||
提交
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -84,22 +158,21 @@ import {
|
||||
saveBrandCategory,
|
||||
} from "@/api/goods";
|
||||
import ossManage from "@/views/sys/oss-manage/ossManage";
|
||||
|
||||
import {regular} from "@/utils";
|
||||
import { regular } from "@/utils";
|
||||
|
||||
export default {
|
||||
name: "brand",
|
||||
components: {
|
||||
ossManage
|
||||
ossManage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defaultPic: require("@/assets/default.png"),
|
||||
loading: true, // 表单加载状态
|
||||
modalType: 0, // 添加或编辑标识
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
picModelFlag: false, // 图片选择器
|
||||
loading: true,
|
||||
modalType: 0,
|
||||
modalVisible: false,
|
||||
modalTitle: "",
|
||||
picModelFlag: false,
|
||||
categoryModalVisible: false,
|
||||
categoryModalTitle: "关联分类",
|
||||
categoryTreeLoading: false,
|
||||
@@ -109,173 +182,23 @@ export default {
|
||||
currentBrandId: "",
|
||||
selectedCategoryIds: [],
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
sort: "create_time", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
sort: "create_time",
|
||||
order: "desc",
|
||||
},
|
||||
form: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
name: "",
|
||||
logo: "",
|
||||
deleteFlag: "",
|
||||
},
|
||||
// 表单验证规则
|
||||
formValidate: {
|
||||
name: [
|
||||
regular.REQUIRED,
|
||||
regular.VARCHAR20
|
||||
],
|
||||
logo: [
|
||||
regular.REQUIRED,
|
||||
regular.URL200
|
||||
],
|
||||
name: [regular.REQUIRED, regular.VARCHAR20],
|
||||
logo: [regular.REQUIRED, regular.URL200],
|
||||
},
|
||||
submitLoading: false, // 添加或编辑提交状态
|
||||
columns: [
|
||||
{
|
||||
title: "品牌名称",
|
||||
key: "name",
|
||||
width: 200,
|
||||
resizable: true,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "品牌图标",
|
||||
key: "logo",
|
||||
align: "left",
|
||||
render: (h, params) => {
|
||||
return h("img", {
|
||||
attrs: {
|
||||
src: params.row.logo || '',
|
||||
alt: "加载图片失败",
|
||||
},
|
||||
style: {
|
||||
cursor: "pointer",
|
||||
width: "80px",
|
||||
height: "60px",
|
||||
margin: "10px 0",
|
||||
"object-fit": "contain",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "deleteFlag",
|
||||
align: "left",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"i-switch",
|
||||
{
|
||||
props: {
|
||||
value: params.row.deleteFlag == 0,
|
||||
size: "large",
|
||||
},
|
||||
on: {
|
||||
"on-change": (checked) => {
|
||||
this.handleStatusSwitchChange(params.row, checked);
|
||||
},
|
||||
},
|
||||
},
|
||||
[
|
||||
h("span", { slot: "open" }, "启用"),
|
||||
h("span", { slot: "close" }, "禁用"),
|
||||
]
|
||||
);
|
||||
},
|
||||
filters: [
|
||||
{
|
||||
label: "启用",
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: "禁用",
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
filterMultiple: false,
|
||||
filterMethod(value, row) {
|
||||
if (value == 0) {
|
||||
return row.deleteFlag == 0;
|
||||
} else if (value == 1) {
|
||||
return row.deleteFlag == 1;
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 210,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.edit(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"编辑"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.openCategoryModal(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"关联分类"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.delBrand(params.row.id);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
submitLoading: false,
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -287,18 +210,13 @@ export default {
|
||||
this.picModelFlag = false;
|
||||
this.form.logo = val.url;
|
||||
},
|
||||
buildCategoryTreeNodes(list, selectedSet) {
|
||||
buildCategoryTreeNodes(list) {
|
||||
if (!Array.isArray(list) || list.length === 0) return [];
|
||||
return list.map((item) => {
|
||||
const children = this.buildCategoryTreeNodes(item.children || [], selectedSet);
|
||||
return {
|
||||
id: item.id,
|
||||
title: item.name,
|
||||
expand: true,
|
||||
checked: selectedSet.has(item.id),
|
||||
children,
|
||||
};
|
||||
});
|
||||
return list.map((item) => ({
|
||||
id: item.id,
|
||||
title: item.name,
|
||||
children: this.buildCategoryTreeNodes(item.children || []),
|
||||
}));
|
||||
},
|
||||
async openCategoryModal(row) {
|
||||
this.currentBrandId = row.id;
|
||||
@@ -319,22 +237,16 @@ export default {
|
||||
.filter(Boolean)
|
||||
: [];
|
||||
this.selectedCategoryIds = selectedIds;
|
||||
const selectedSet = new Set(selectedIds);
|
||||
this.categoryTreeData = treeRes && treeRes.success
|
||||
? this.buildCategoryTreeNodes(treeRes.result || [], selectedSet)
|
||||
: [];
|
||||
this.categoryTreeData =
|
||||
treeRes && treeRes.success
|
||||
? this.buildCategoryTreeNodes(treeRes.result || [])
|
||||
: [];
|
||||
} finally {
|
||||
this.categoryTreeLoading = false;
|
||||
}
|
||||
},
|
||||
onCategoryTreeCheckChange(checkedNodes) {
|
||||
if (!Array.isArray(checkedNodes)) {
|
||||
this.selectedCategoryIds = [];
|
||||
return;
|
||||
}
|
||||
this.selectedCategoryIds = checkedNodes
|
||||
.map((node) => node && node.id)
|
||||
.filter(Boolean);
|
||||
onCategoryTreeCheckChange(_data, checkedInfo) {
|
||||
this.selectedCategoryIds = checkedInfo?.checkedKeys || [];
|
||||
},
|
||||
submitBrandCategory() {
|
||||
if (!this.currentBrandId) return;
|
||||
@@ -342,16 +254,17 @@ export default {
|
||||
saveBrandCategory(
|
||||
this.currentBrandId,
|
||||
(this.selectedCategoryIds || []).map((id) => String(id))
|
||||
).then((res) => {
|
||||
this.categorySubmitLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.categoryModalVisible = false;
|
||||
return;
|
||||
}
|
||||
}).catch(() => {
|
||||
this.categorySubmitLoading = false;
|
||||
});
|
||||
)
|
||||
.then((res) => {
|
||||
this.categorySubmitLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.categoryModalVisible = false;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.categorySubmitLoading = false;
|
||||
});
|
||||
},
|
||||
handleStatusSwitchChange(row, checked) {
|
||||
const disable = !checked;
|
||||
@@ -373,36 +286,29 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
// 删除品牌
|
||||
async delBrand(id) {
|
||||
let res = await delBrand(id);
|
||||
|
||||
const res = await delBrand(id);
|
||||
if (res.success) {
|
||||
this.$Message.success("品牌删除成功!");
|
||||
this.getDataList();
|
||||
}
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
// 获取数据
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
getManagerBrandPage(this.searchForm).then((res) => {
|
||||
@@ -413,13 +319,11 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 提交表单
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete this.form.id;
|
||||
addBrand(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
@@ -430,7 +334,6 @@ export default {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
updateBrand(this.form).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
@@ -443,28 +346,24 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 添加
|
||||
add() {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加";
|
||||
this.$refs.form.resetFields();
|
||||
this.$refs.form?.resetFields();
|
||||
delete this.form.id;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
|
||||
// 编辑
|
||||
edit(v) {
|
||||
this.modalType = 1;
|
||||
this.modalTitle = "编辑";
|
||||
this.$refs.form.resetFields();
|
||||
// 转换null为""
|
||||
for (let attr in v) {
|
||||
this.$refs.form?.resetFields();
|
||||
for (const attr in v) {
|
||||
if (v[attr] === null) {
|
||||
v[attr] = "";
|
||||
}
|
||||
}
|
||||
let str = JSON.stringify(v);
|
||||
let data = JSON.parse(str);
|
||||
const str = JSON.stringify(v);
|
||||
const data = JSON.parse(str);
|
||||
this.form = data;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
@@ -474,3 +373,6 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
@@ -1,165 +1,163 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<el-card>
|
||||
<div class="mb_10">
|
||||
<Button @click="addParent" icon="md-add">添加一级分类</Button>
|
||||
<el-button type="primary" @click="addParent">添加一级分类</el-button>
|
||||
</div>
|
||||
<Table
|
||||
update-show-children
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
class="table"
|
||||
:load-data="handleLoadData"
|
||||
row-key="id"
|
||||
:loading="loading"
|
||||
:data="tableData"
|
||||
:columns="columns"
|
||||
row-key="id"
|
||||
border
|
||||
:tree-props="{ children: 'children' }"
|
||||
style="width: 100%"
|
||||
>
|
||||
<template slot="action" slot-scope="scope">
|
||||
<div class="ops">
|
||||
<a class="ops-link" @click="edit(scope.row)">编辑</a>
|
||||
<a class="ops-link" @click="remove(scope.row)">删除</a>
|
||||
<a v-show="scope.row.level != 2" class="ops-link" @click="addChildren(scope.row)">添加子分类</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template slot="commissionRate" slot-scope="scope">
|
||||
<priceColorScheme v-if="scope.row.commissionRate > 0" unit="" :color="$mainColor" :value="scope.row.commissionRate">%</priceColorScheme>
|
||||
<priceColorScheme v-else :value="scope.row.commissionRate" unit="" >%</priceColorScheme>
|
||||
<!-- {{ scope.row.commissionRate }}% -->
|
||||
</template>
|
||||
|
||||
<template slot="deleteFlag" slot-scope="{ row }">
|
||||
<i-switch
|
||||
size="large"
|
||||
v-model="row.deleteFlag"
|
||||
:true-value="false"
|
||||
:false-value="true"
|
||||
:loading="row._statusLoading"
|
||||
@on-change="onStatusSwitchChange(row, $event)"
|
||||
>
|
||||
<span slot="open">开启</span>
|
||||
<span slot="close">关闭</span>
|
||||
</i-switch>
|
||||
</template>
|
||||
</Table>
|
||||
|
||||
<Modal
|
||||
:title="modalTitle"
|
||||
v-model="modalVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
>
|
||||
<Form ref="form" :model="formAdd" :label-width="100" :rules="formValidate">
|
||||
<div v-if="showParent">
|
||||
<FormItem label="上级分类" prop="parentId">
|
||||
{{ parentTitle }}
|
||||
<Input
|
||||
v-model="formAdd.parentId"
|
||||
clearable
|
||||
style="width: 100%; display: none"
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
<FormItem label="层级" prop="level" style="display: none">
|
||||
<Input v-model="formAdd.level" clearable style="width: 100%" />
|
||||
</FormItem>
|
||||
<FormItem label="分类名称" prop="name">
|
||||
<Input v-model="formAdd.name" clearable style="width: 100%" />
|
||||
</FormItem>
|
||||
<FormItem label="分类图标" prop="image" v-if="formAdd.level !== 1">
|
||||
<upload-pic-input
|
||||
v-model="formAdd.image"
|
||||
style="width: 100%"
|
||||
></upload-pic-input>
|
||||
</FormItem>
|
||||
<FormItem label="排序值" prop="sortOrder" style="width: 345px">
|
||||
<InputNumber v-model="formAdd.sortOrder"></InputNumber>
|
||||
</FormItem>
|
||||
<FormItem label="佣金比例(%)" prop="commissionRate" style="width: 345px">
|
||||
<InputNumber :max="100" :min="0" v-model="formAdd.commissionRate"></InputNumber>
|
||||
</FormItem>
|
||||
<FormItem label="是否启用" prop="deleteFlag">
|
||||
<i-switch
|
||||
size="large"
|
||||
v-model="formAdd.deleteFlag"
|
||||
:true-value="false"
|
||||
:false-value="true"
|
||||
<el-table-column prop="name" label="分类名称" min-width="200" />
|
||||
<el-table-column label="状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
v-model="row.deleteFlag"
|
||||
:active-value="false"
|
||||
:inactive-value="true"
|
||||
inline-prompt
|
||||
active-text="开启"
|
||||
inactive-text="关闭"
|
||||
:loading="!!row._statusLoading"
|
||||
@change="(val) => onStatusSwitchChange(row, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="佣金" width="120">
|
||||
<template #default="{ row }">
|
||||
<span
|
||||
v-if="row"
|
||||
:style="row.commissionRate > 0 ? { color: $mainColor } : {}"
|
||||
>
|
||||
<span slot="open">启用</span>
|
||||
<span slot="close">禁用</span>
|
||||
</i-switch>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="Submit">提交</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
{{ row.commissionRate }}%
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" min-width="220" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops">
|
||||
<a class="link-text" @click="edit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
<template v-if="row.level != 2">
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="addChildren(row)">添加子分类</a>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<Modal
|
||||
:title="modalBrandTitle"
|
||||
<el-dialog
|
||||
v-model="modalVisible"
|
||||
:title="modalTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form ref="form" :model="formAdd" label-width="100px" :rules="formValidate">
|
||||
<el-form-item v-if="showParent" label="上级分类" prop="parentId">
|
||||
{{ parentTitle }}
|
||||
<el-input v-model="formAdd.parentId" style="display: none" />
|
||||
</el-form-item>
|
||||
<el-form-item label="层级" prop="level" style="display: none">
|
||||
<el-input v-model="formAdd.level" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类名称" prop="name">
|
||||
<el-input v-model="formAdd.name" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formAdd.level !== 1" label="分类图标" prop="image">
|
||||
<upload-pic-input v-model="formAdd.image" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排序值" prop="sortOrder">
|
||||
<el-input-number v-model="formAdd.sortOrder" style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="佣金比例(%)" prop="commissionRate">
|
||||
<el-input-number v-model="formAdd.commissionRate" :min="0" :max="100" style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否启用" prop="deleteFlag">
|
||||
<el-switch
|
||||
v-model="formAdd.deleteFlag"
|
||||
:active-value="false"
|
||||
:inactive-value="true"
|
||||
inline-prompt
|
||||
active-text="启用"
|
||||
inactive-text="禁用"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="Submit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
v-model="modalBrandVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
:title="modalBrandTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<Form ref="brandForm" :model="brandForm" :label-width="100">
|
||||
<Select v-model="brandForm.categoryBrands" filterable multiple>
|
||||
<Option v-for="item in brandWay" :value="item.id" :key="item.id">{{
|
||||
item.name
|
||||
}}</Option>
|
||||
</Select>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalBrandVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="saveCategoryBrand"
|
||||
>提交</Button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
<el-form ref="brandForm" :model="brandForm" label-width="100px">
|
||||
<el-select v-model="brandForm.categoryBrands" filterable multiple style="width: 100%">
|
||||
<el-option v-for="item in brandWay" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalBrandVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="saveCategoryBrand">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<Modal
|
||||
:title="modalSpecTitle"
|
||||
<el-dialog
|
||||
v-model="modalSpecVisible"
|
||||
:mask-closable="false"
|
||||
:width="500"
|
||||
:title="modalSpecTitle"
|
||||
width="500px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<Form ref="specForm" :model="specForm" :label-width="100">
|
||||
<Select v-model="specForm.categorySpecs" multiple>
|
||||
<Option
|
||||
<el-form ref="specForm" :model="specForm" label-width="100px">
|
||||
<el-select v-model="specForm.categorySpecs" multiple style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in specifications"
|
||||
:value="item.id"
|
||||
:key="item.id"
|
||||
:label="item.specName"
|
||||
>
|
||||
</Option>
|
||||
</Select>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="modalSpecVisible = false">取消</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="saveCategorySpec"
|
||||
>提交</Button
|
||||
>
|
||||
</div>
|
||||
</Modal>
|
||||
</Card>
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="modalSpecVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="saveCategorySpec">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
delCategory,
|
||||
disableCategory,
|
||||
getBrandListData,
|
||||
getCategoryBrandListData,
|
||||
getCategorySpecListData,
|
||||
getCategoryTree,
|
||||
getSpecificationList,
|
||||
insertCategory,
|
||||
saveCategoryBrand,
|
||||
saveCategorySpec,
|
||||
updateCategory,
|
||||
delCategory,
|
||||
disableCategory,
|
||||
getBrandListData,
|
||||
getCategoryBrandListData,
|
||||
getCategorySpecListData,
|
||||
getCategoryTree,
|
||||
getSpecificationList,
|
||||
insertCategory,
|
||||
saveCategoryBrand,
|
||||
saveCategorySpec,
|
||||
updateCategory,
|
||||
} from "@/api/goods";
|
||||
|
||||
import uploadPicInput from "@/components/lili/upload-pic-input";
|
||||
import { regular } from "@/utils";
|
||||
|
||||
export default {
|
||||
name: "goods-category",
|
||||
components: {
|
||||
@@ -167,69 +165,44 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
recordLevel:[], // 记录当前层级
|
||||
submitLoading: false, //加载状态
|
||||
categoryList: [], // 分类列表
|
||||
loading: false, // 加载状态
|
||||
brands: [], //品牌集合
|
||||
specifications: [], //规格集合
|
||||
categoryId: "", // 分类id
|
||||
categorySpecs: [], //已经选择的规格
|
||||
modalType: 0, // 添加或编辑标识
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalBrandVisible: false, //品牌关联编辑显示
|
||||
modalSpecVisible: false, //品牌关联编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
showParent: false, // 是否展示上级菜单
|
||||
parentTitle: "", // 父级菜单名称
|
||||
modalBrandTitle: "", // 品牌弹窗标题
|
||||
modalSpecTitle: "", // 规格弹窗标题
|
||||
submitLoading: false,
|
||||
categoryList: [],
|
||||
loading: false,
|
||||
brands: [],
|
||||
specifications: [],
|
||||
categoryId: "",
|
||||
categorySpecs: [],
|
||||
modalType: 0,
|
||||
modalVisible: false,
|
||||
modalBrandVisible: false,
|
||||
modalSpecVisible: false,
|
||||
modalTitle: "",
|
||||
showParent: false,
|
||||
parentTitle: "",
|
||||
modalBrandTitle: "",
|
||||
modalSpecTitle: "",
|
||||
formAdd: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
parentId: "",
|
||||
name: "",
|
||||
image: "",
|
||||
sortOrder: 0,
|
||||
deleteFlag: 0,
|
||||
deleteFlag: false,
|
||||
commissionRate: 0,
|
||||
level: 0,
|
||||
},
|
||||
brandForm: {
|
||||
categoryBrands: [],
|
||||
},
|
||||
brandWay: "", //请求绑定品牌的信息
|
||||
specForm: {}, // 规格数据
|
||||
// 表单验证规则
|
||||
brandWay: [],
|
||||
specForm: {
|
||||
categorySpecs: [],
|
||||
},
|
||||
formValidate: {
|
||||
commissionRate: [regular.REQUIRED, regular.INTEGER],
|
||||
name: [regular.REQUIRED, regular.VARCHAR20],
|
||||
sortOrder: [regular.REQUIRED, regular.INTEGER],
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "分类名称",
|
||||
key: "name",
|
||||
tree: true,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
slot: "deleteFlag",
|
||||
},
|
||||
{
|
||||
title: "佣金",
|
||||
key: "commissionRate",
|
||||
|
||||
slot: "commissionRate",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
|
||||
slot: "action",
|
||||
},
|
||||
],
|
||||
tableData: [], // 表格数据
|
||||
checkedCategoryChildren: "", //选中的分类子级
|
||||
tableData: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -250,48 +223,38 @@ export default {
|
||||
const isClosing = nextDeleteFlag === true;
|
||||
this.$Modal.confirm({
|
||||
title: isClosing ? "确认关闭" : "确认开启",
|
||||
content:
|
||||
"您是否要" +
|
||||
(isClosing ? "关闭" : "开启") +
|
||||
"当前分类 " +
|
||||
row.name +
|
||||
" 及其子分类?",
|
||||
content: `您是否要${isClosing ? "关闭" : "开启"}当前分类 ${row.name} 及其子分类?`,
|
||||
loading: true,
|
||||
okText: "是",
|
||||
cancelText: "否",
|
||||
onOk: () => {
|
||||
this.$set(row, "_statusLoading", true);
|
||||
disableCategory(row.id, { enableOperations: isClosing ? true : 0 }).then(
|
||||
(res) => {
|
||||
this.$Modal.remove();
|
||||
this.$set(row, "_statusLoading", false);
|
||||
if (res && res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList(0);
|
||||
return;
|
||||
}
|
||||
row.deleteFlag = previousDeleteFlag;
|
||||
row._statusLoading = true;
|
||||
disableCategory(row.id, { enableOperations: isClosing ? true : 0 }).then((res) => {
|
||||
this.$Modal.remove();
|
||||
row._statusLoading = false;
|
||||
if (res && res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList();
|
||||
return;
|
||||
}
|
||||
);
|
||||
row.deleteFlag = previousDeleteFlag;
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
row.deleteFlag = previousDeleteFlag;
|
||||
},
|
||||
});
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
this.getBrandList();
|
||||
this.getSpecList();
|
||||
},
|
||||
//获取所有品牌
|
||||
getBrandList() {
|
||||
getBrandListData().then((res) => {
|
||||
this.brandWay = res;
|
||||
});
|
||||
},
|
||||
//获取所有规格
|
||||
getSpecList() {
|
||||
getSpecificationList().then((res) => {
|
||||
if (res.length != 0) {
|
||||
@@ -299,7 +262,6 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
//弹出品牌关联框
|
||||
brandOperation(v) {
|
||||
getCategoryBrandListData(v.id).then((res) => {
|
||||
this.categoryId = v.id;
|
||||
@@ -308,7 +270,6 @@ export default {
|
||||
this.modalBrandVisible = true;
|
||||
});
|
||||
},
|
||||
//弹出规格关联框
|
||||
specOperation(v) {
|
||||
getCategorySpecListData(v.id).then((res) => {
|
||||
this.categoryId = v.id;
|
||||
@@ -317,7 +278,6 @@ export default {
|
||||
this.modalSpecVisible = true;
|
||||
});
|
||||
},
|
||||
//保存分类规格绑定
|
||||
saveCategorySpec() {
|
||||
saveCategorySpec(this.categoryId, this.specForm).then((res) => {
|
||||
this.submitLoading = false;
|
||||
@@ -327,7 +287,6 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
//保存分类品牌绑定
|
||||
saveCategoryBrand() {
|
||||
saveCategoryBrand(this.categoryId, this.brandForm).then((res) => {
|
||||
this.submitLoading = false;
|
||||
@@ -337,19 +296,17 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 添加子分类
|
||||
addChildren(v) {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加子分类";
|
||||
this.parentTitle = v.name;
|
||||
this.formAdd.level = eval(v.level + "+1");
|
||||
this.formAdd.level = Number(v.level) + 1;
|
||||
this.formAdd.commissionRate = v.commissionRate;
|
||||
this.showParent = true;
|
||||
delete this.formAdd.id;
|
||||
this.formAdd.parentId = v.id;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 编辑分类
|
||||
edit(v) {
|
||||
this.modalType = 1;
|
||||
this.modalTitle = "编辑";
|
||||
@@ -364,57 +321,51 @@ export default {
|
||||
this.showParent = false;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 添加一级分类
|
||||
addParent() {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加一级分类";
|
||||
this.parentTitle = "顶级分类";
|
||||
this.showParent = true;
|
||||
this.$refs.form.resetFields();
|
||||
this.$refs.form?.resetFields();
|
||||
delete this.formAdd.id;
|
||||
this.formAdd.parentId = 0;
|
||||
this.formAdd.level = 0;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 提交
|
||||
Submit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete this.formAdd.id;
|
||||
insertCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
updateCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!valid) return;
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
delete this.formAdd.id;
|
||||
insertCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("添加成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
updateCategory(this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.success) {
|
||||
this.$Message.success("修改成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
this.$refs.form.resetFields();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 删除分类
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "您确认要删除 " + v.name + " ?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
// 删除
|
||||
delCategory(v.id).then((res) => {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
@@ -425,80 +376,22 @@ export default {
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
// 异步手动加载分类名称
|
||||
handleLoadData(item, callback) {
|
||||
this.recordLevel[item.level] = item.id;
|
||||
if (item.level == 0) {
|
||||
let categoryList = JSON.parse(JSON.stringify(this.categoryList));
|
||||
categoryList.forEach((val) => {
|
||||
if (val.id == item.id) {
|
||||
val.children.map((child) => {
|
||||
child._loading = false;
|
||||
child.children = [];
|
||||
});
|
||||
this.normalizeCategoryTree(val.children);
|
||||
// 模拟加载
|
||||
setTimeout(() => {
|
||||
callback(val.children);
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.deepCategoryChildren(item.id, this.categoryList);
|
||||
this.normalizeCategoryTree(this.checkedCategoryChildren);
|
||||
setTimeout(() => {
|
||||
callback(this.checkedCategoryChildren);
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
|
||||
// 通过递归children来实现手动加载数据
|
||||
deepCategoryChildren(id, list) {
|
||||
if (id != "0" && list.length != 0) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let item = list[i];
|
||||
if (item.id == id) {
|
||||
this.checkedCategoryChildren = item.children;
|
||||
return;
|
||||
} else {
|
||||
this.deepCategoryChildren(id, item.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取分类数据
|
||||
getAllList() {
|
||||
this.loading = true;
|
||||
getCategoryTree().then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
localStorage.setItem("category", JSON.stringify(res.result));
|
||||
this.normalizeCategoryTree(res.result);
|
||||
this.categoryList = JSON.parse(JSON.stringify(res.result));
|
||||
this.tableData = res.result.map((item) => {
|
||||
if(this.recordLevel[0] && item.id === this.recordLevel[0]) {
|
||||
item._showChildren = true
|
||||
// 继续判断第二层
|
||||
if(this.recordLevel[1] && item.children){
|
||||
item.children.map((child)=>{
|
||||
if(this.recordLevel[1] && child.id === this.recordLevel[1]){
|
||||
child._showChildren = true
|
||||
}
|
||||
})
|
||||
}
|
||||
}else{
|
||||
if (item.children.length !== 0) {
|
||||
item.children = [];
|
||||
item._loading = false;
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
});
|
||||
getCategoryTree()
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
if (res.success) {
|
||||
localStorage.setItem("category", JSON.stringify(res.result));
|
||||
this.normalizeCategoryTree(res.result);
|
||||
this.categoryList = JSON.parse(JSON.stringify(res.result));
|
||||
this.tableData = JSON.parse(JSON.stringify(res.result));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 启用分类
|
||||
enable(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认启用",
|
||||
@@ -511,16 +404,15 @@ export default {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
}
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
},
|
||||
});
|
||||
},
|
||||
// 禁用分类
|
||||
disable(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认禁用",
|
||||
@@ -533,12 +425,12 @@ export default {
|
||||
this.$Modal.remove();
|
||||
if (res.success) {
|
||||
this.$Message.success("操作成功");
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
}
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
this.getAllList(0);
|
||||
this.getAllList();
|
||||
},
|
||||
});
|
||||
},
|
||||
@@ -548,31 +440,15 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .ivu-table-wrapper {
|
||||
:deep(.el-table__body-wrapper) {
|
||||
overflow: auto;
|
||||
}
|
||||
.table {
|
||||
min-height: 100vh;
|
||||
height: auto;
|
||||
min-height: 60vh;
|
||||
}
|
||||
.ops-link {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ops {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.ops-link + .ops-link {
|
||||
margin-left: 16px;
|
||||
position: relative;
|
||||
}
|
||||
.ops-link + .ops-link::before {
|
||||
content: "|";
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
color: #dcdee2;
|
||||
.mb_10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,73 +1,92 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form ref="form" :model="form" :label-width="100" :rules="formValidate">
|
||||
<FormItem label="参数名称" prop="paramName">
|
||||
<Input v-model="form.paramName" clearable style="width: 520px" />
|
||||
</FormItem>
|
||||
<FormItem label="是否必填" prop="required">
|
||||
<RadioGroup v-model="form.required">
|
||||
<Radio :label="0">否</Radio>
|
||||
<Radio :label="1">是</Radio>
|
||||
</RadioGroup>
|
||||
<span style="margin-left: 10px; color: #999; font-size: 12px"
|
||||
>商品发布时参数是否必填</span
|
||||
>
|
||||
</FormItem>
|
||||
<FormItem label="是否索引" prop="isIndex">
|
||||
<RadioGroup v-model="form.isIndex">
|
||||
<Radio :label="0">否</Radio>
|
||||
<Radio :label="1">是</Radio>
|
||||
</RadioGroup>
|
||||
<span style="margin-left: 10px; color: #999; font-size: 12px"
|
||||
>开启索引后,用户将可以通过该参数筛选商品,索引开关不影响商详页的参数展示</span
|
||||
>
|
||||
</FormItem>
|
||||
<FormItem label="排序" prop="sort">
|
||||
<InputNumber :min="0" type="number" v-model="form.sort" style="width: 520px" />
|
||||
</FormItem>
|
||||
<FormItem label="参数值" prop="options">
|
||||
<Table :columns="optionColumns" :data="form.options" border size="small" style="width: 520px" />
|
||||
<el-card>
|
||||
<el-form ref="form" :model="form" label-width="100px" :rules="formValidate">
|
||||
<el-form-item label="参数名称" prop="paramName">
|
||||
<el-input v-model="form.paramName" clearable style="width: 520px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否必填" prop="required">
|
||||
<el-radio-group v-model="form.required">
|
||||
<el-radio :value="0">否</el-radio>
|
||||
<el-radio :value="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
<span style="margin-left: 10px; color: #999; font-size: 12px">商品发布时参数是否必填</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否索引" prop="isIndex">
|
||||
<el-radio-group v-model="form.isIndex">
|
||||
<el-radio :value="0">否</el-radio>
|
||||
<el-radio :value="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
<span style="margin-left: 10px; color: #999; font-size: 12px">
|
||||
开启索引后,用户将可以通过该参数筛选商品,索引开关不影响商详页的参数展示
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number :min="0" v-model="form.sort" style="width: 520px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="参数值" prop="options">
|
||||
<el-table :data="form.options" border size="small" style="width: 520px">
|
||||
<el-table-column label="参数值" min-width="420">
|
||||
<template #default="{ row, $index }">
|
||||
<el-input
|
||||
v-if="row"
|
||||
v-model="form.options[$index].value"
|
||||
clearable
|
||||
@blur="touchOptionsValidate"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90" align="center">
|
||||
<template #default="{ row, $index }">
|
||||
<a v-if="row" class="link-text" @click="removeOptionRow($index)">
|
||||
删除
|
||||
</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div style="margin-top: 10px">
|
||||
<Button type="primary" @click="addOptionRow">新增</Button>
|
||||
<el-button type="primary" @click="addOptionRow">新增</el-button>
|
||||
</div>
|
||||
</FormItem>
|
||||
<FormItem label="关联分类">
|
||||
<Button type="default" @click="openCategoryModal">选择分类</Button>
|
||||
<span v-if="selectedCategoryNamesText" style="margin-left: 10px; color: #999; font-size: 12px"
|
||||
>{{ selectedCategoryNamesText }}</span
|
||||
>
|
||||
<span v-else style="margin-left: 10px; color: #999; font-size: 12px"
|
||||
>已选择{{ selectedCategoryIds.length }}个分类</span
|
||||
>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button type="default" @click="back">返回</Button>
|
||||
<Button type="primary" :loading="submitLoading" @click="handleSubmit">保存</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Card>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联分类">
|
||||
<el-button @click="openCategoryModal">选择分类</el-button>
|
||||
<span v-if="selectedCategoryNamesText" style="margin-left: 10px; color: #999; font-size: 12px">
|
||||
{{ selectedCategoryNamesText }}</span>
|
||||
<span v-else style="margin-left: 10px; color: #999; font-size: 12px">
|
||||
已选择{{ selectedCategoryIds.length }}个分类
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="back">返回</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<Modal
|
||||
:title="categoryModalTitle"
|
||||
<el-dialog
|
||||
v-model="categoryModalVisible"
|
||||
:mask-closable="false"
|
||||
:width="700"
|
||||
:title="categoryModalTitle"
|
||||
width="700px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div style="position: relative; max-height: 520px; overflow: auto;">
|
||||
<Spin size="large" fix v-if="categoryTreeLoading"></Spin>
|
||||
<Tree
|
||||
<div v-loading="categoryTreeLoading" style="position: relative; max-height: 520px; overflow: auto">
|
||||
<el-tree
|
||||
ref="categoryTree"
|
||||
:key="categoryTreeKey"
|
||||
:data="categoryTreeData"
|
||||
:props="{ label: 'title', children: 'children' }"
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
@on-check-change="onCategoryTreeCheckChange"
|
||||
></Tree>
|
||||
default-expand-all
|
||||
:default-checked-keys="selectedCategoryIds"
|
||||
@check="onCategoryTreeCheckChange"
|
||||
/>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button type="text" @click="categoryModalVisible = false">取消</Button>
|
||||
<Button type="primary" style="margin-left: 8px" @click="categoryModalVisible = false">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<template #footer>
|
||||
<el-button @click="categoryModalVisible = false">取消</el-button>
|
||||
<el-button type="primary" style="margin-left: 8px" @click="categoryModalVisible = false">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -190,51 +209,6 @@ export default {
|
||||
isIndex: 0,
|
||||
sort: 0,
|
||||
},
|
||||
optionColumns: [
|
||||
{
|
||||
title: "参数值",
|
||||
key: "value",
|
||||
minWidth: 420,
|
||||
render: (h, params) => {
|
||||
return h("Input", {
|
||||
props: {
|
||||
value: params.row.value,
|
||||
clearable: true,
|
||||
},
|
||||
on: {
|
||||
input: (val) => {
|
||||
if (!Array.isArray(this.form.options)) this.form.options = [];
|
||||
if (!this.form.options[params.index]) return;
|
||||
this.form.options[params.index].value = val;
|
||||
},
|
||||
"on-blur": () => {
|
||||
this.touchOptionsValidate();
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 90,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"Button",
|
||||
{
|
||||
props: {
|
||||
type: "error",
|
||||
size: "small",
|
||||
},
|
||||
on: {
|
||||
click: () => this.removeOptionRow(params.index),
|
||||
},
|
||||
},
|
||||
"删除",
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
formValidate: {
|
||||
paramName: [regular.REQUIRED, regular.VARCHAR5],
|
||||
options: [{ required: true, validator: validateOptions, trigger: "change" }],
|
||||
@@ -253,8 +227,8 @@ export default {
|
||||
const selectedSet = new Set(toStringArray(this.selectedCategoryIds));
|
||||
const isSelected = (node) => {
|
||||
if (!node) return false;
|
||||
const id = node.id !== undefined && node.id !== null ? String(node.id) : "";
|
||||
if (id && selectedSet.has(id)) return true;
|
||||
const nodeId = node.id !== undefined && node.id !== null ? String(node.id) : "";
|
||||
if (nodeId && selectedSet.has(nodeId)) return true;
|
||||
const children = Array.isArray(node.children) ? node.children : [];
|
||||
if (children.length === 0) return false;
|
||||
return children.every(isSelected);
|
||||
@@ -276,11 +250,11 @@ export default {
|
||||
watch: {
|
||||
"form.required"(val) {
|
||||
const n = normalize01(val, 0);
|
||||
if (val !== n) this.$set(this.form, "required", n);
|
||||
if (val !== n) this.form.required = n;
|
||||
},
|
||||
"form.isIndex"(val) {
|
||||
const n = normalize01(val, 0);
|
||||
if (val !== n) this.$set(this.form, "isIndex", n);
|
||||
if (val !== n) this.form.isIndex = n;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
@@ -302,18 +276,13 @@ export default {
|
||||
this.form.options.splice(index, 1);
|
||||
this.touchOptionsValidate();
|
||||
},
|
||||
buildCategoryTreeNodes(list, selectedSet) {
|
||||
buildCategoryTreeNodes(list) {
|
||||
if (!Array.isArray(list) || list.length === 0) return [];
|
||||
return list.map((item) => {
|
||||
const children = this.buildCategoryTreeNodes(item.children || [], selectedSet);
|
||||
return {
|
||||
id: item.id,
|
||||
title: item.name,
|
||||
expand: true,
|
||||
checked: selectedSet.has(String(item.id)),
|
||||
children,
|
||||
};
|
||||
});
|
||||
return list.map((item) => ({
|
||||
id: item.id,
|
||||
title: item.name,
|
||||
children: this.buildCategoryTreeNodes(item.children || []),
|
||||
}));
|
||||
},
|
||||
async loadDetail(parameterId) {
|
||||
if (!parameterId) return;
|
||||
@@ -337,7 +306,6 @@ export default {
|
||||
this.categoryTreeLoading = true;
|
||||
this.categoryTreeKey += 1;
|
||||
try {
|
||||
const selectedSet = new Set(toStringArray(this.selectedCategoryIds));
|
||||
if (!Array.isArray(this.categoryTreeSource) || this.categoryTreeSource.length === 0) {
|
||||
const treeRes = await getCategoryTree();
|
||||
this.categoryTreeSource = treeRes && treeRes.success ? treeRes.result || [] : [];
|
||||
@@ -345,17 +313,13 @@ export default {
|
||||
buildCategoryIdNameMap(this.categoryTreeSource, map);
|
||||
this.categoryIdNameMap = map;
|
||||
}
|
||||
this.categoryTreeData = this.buildCategoryTreeNodes(this.categoryTreeSource || [], selectedSet);
|
||||
this.categoryTreeData = this.buildCategoryTreeNodes(this.categoryTreeSource || []);
|
||||
} finally {
|
||||
this.categoryTreeLoading = false;
|
||||
}
|
||||
},
|
||||
onCategoryTreeCheckChange(checkedNodes) {
|
||||
if (!Array.isArray(checkedNodes)) {
|
||||
this.selectedCategoryIds = [];
|
||||
return;
|
||||
}
|
||||
this.selectedCategoryIds = toStringArray(checkedNodes.map((node) => node && node.id).filter(Boolean));
|
||||
onCategoryTreeCheckChange(_data, checkedInfo) {
|
||||
this.selectedCategoryIds = toStringArray(checkedInfo?.checkedKeys || []);
|
||||
},
|
||||
initForm() {
|
||||
if (this.id) {
|
||||
|
||||
@@ -1,55 +1,72 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
@submit.native.prevent
|
||||
@keydown.enter.native="handleSearch"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="参数名称">
|
||||
<Input
|
||||
type="text"
|
||||
<el-form-item label="参数名称">
|
||||
<el-input
|
||||
v-model="searchForm.paramName"
|
||||
placeholder="请输入参数名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary">搜索</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button @click="goAdd" type="primary">添加</Button>
|
||||
</Row>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table"></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<el-card>
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" @click="goAdd">添加</el-button>
|
||||
</div>
|
||||
<el-table v-loading="loading" border :data="data" ref="table" style="width: 100%">
|
||||
<el-table-column prop="paramName" label="参数名称" width="300" />
|
||||
<el-table-column prop="options" label="参数值" min-width="260" show-overflow-tooltip />
|
||||
<el-table-column label="必填" width="300" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ isTruthyFlag(row.required) ? "是" : "否" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="可索引" width="300" align="center">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ isTruthyFlag(row.isIndex) ? "是" : "否" }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row">
|
||||
<a class="link-text" @click="goEdit(row)">编辑</a>
|
||||
<span class="op-split">|</span>|<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
deleteParams,
|
||||
getGoodsParamsPage,
|
||||
} from "@/api/goods";
|
||||
import { deleteParams, getGoodsParamsPage } from "@/api/goods";
|
||||
|
||||
export default {
|
||||
name: "categoryParams",
|
||||
@@ -66,90 +83,12 @@ export default {
|
||||
paramName: "",
|
||||
},
|
||||
data: [],
|
||||
columns: [
|
||||
{
|
||||
title: "参数名称",
|
||||
key: "paramName",
|
||||
width: 300,
|
||||
resizable: true,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: "参数值",
|
||||
key: "options",
|
||||
minWidth: 260,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "必填",
|
||||
key: "required",
|
||||
width: 300,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const val = params.row.required;
|
||||
const on = val === 1 || val === "1" || val === true;
|
||||
return h("span", on ? "是" : "否");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "可索引",
|
||||
key: "isIndex",
|
||||
width: 300,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
const val = params.row.isIndex;
|
||||
const on = val === 1 || val === "1" || val === true;
|
||||
return h("span", on ? "是" : "否");
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 300,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h("div", [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.goEdit(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"编辑"
|
||||
),
|
||||
h("span", { style: { margin: "0 8px", color: "#dcdee2" } }, "|"),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.remove(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isTruthyFlag(val) {
|
||||
return val === 1 || val === "1" || val === true;
|
||||
},
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
@@ -209,4 +148,10 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss"></style>
|
||||
<style lang="scss">
|
||||
.link-text {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,103 +1,171 @@
|
||||
<template>
|
||||
<div>
|
||||
<Card>
|
||||
<Row>
|
||||
<Form ref="searchForm" :model="searchForm" @keydown.enter.native="handleSearch" @submit.native.prevent inline :label-width="70" class="search-form">
|
||||
<Form-item label="会员名称" prop="memberName">
|
||||
<Input type="text" v-model="searchForm.memberName" placeholder="请输入会员名称" clearable style="width: 240px"/>
|
||||
</Form-item>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input type="text" v-model="searchForm.goodsName" placeholder="请输入商品名称" clearable style="width: 240px"/>
|
||||
</Form-item>
|
||||
<Button @click="handleSearch" type="primary" class="search-btn" icon="ios-search">搜索</Button>
|
||||
</Form>
|
||||
</Row>
|
||||
</Card>
|
||||
<Card>
|
||||
<Table :loading="loading" border :columns="columns" :data="data" ref="table" class="mt_10">
|
||||
<!-- 页面展示 -->
|
||||
<template slot="shopDisableSlot" slot-scope="scope">
|
||||
<i-switch size="large" true-value="OPEN" false-value="CLOSE" v-model="scope.row.status"
|
||||
@on-change="changeSwitch(scope.row)">
|
||||
<span slot="open">展示</span>
|
||||
<span slot="close">隐藏</span>
|
||||
</i-switch>
|
||||
</template>
|
||||
</Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
|
||||
@on-page-size-change="changePageSize" :page-size-opts="[20, 50, 100]"
|
||||
size="small" show-total show-elevator show-sizer></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<!-- 评价详情 -->
|
||||
<Modal v-model="infoFlag" width="800" :title="infoTitle">
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<el-form-item label="会员名称" prop="memberName">
|
||||
<el-input
|
||||
v-model="searchForm.memberName"
|
||||
placeholder="请输入会员名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card>
|
||||
<el-table ref="table" v-loading="loading" border :data="data" class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="goodsName" label="商品名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="memberName" label="会员名称" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="content" label="评论内容" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column label="是否置顶" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="row.top ? 'danger' : 'info'">
|
||||
{{ row.top ? "已置顶" : "未置顶" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="评价" width="90">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="gradeTagType(row.grade)">{{ gradeText(row.grade) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="评价时间" width="170" />
|
||||
<el-table-column label="页面展示" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-switch
|
||||
v-if="row"
|
||||
v-model="row.status"
|
||||
active-value="OPEN"
|
||||
inactive-value="CLOSE"
|
||||
inline-prompt
|
||||
active-text="展示"
|
||||
inactive-text="隐藏"
|
||||
@change="changeSwitch(row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="220" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops">
|
||||
<a class="link-text" @click="info(row)">查看</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="updateTop(row)">{{ row.top ? "取消置顶" : "置顶评论" }}</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="infoFlag" :title="infoTitle" width="800px">
|
||||
<div class="info-list" style="overflow: hidden">
|
||||
<div class="left-container">
|
||||
<div class="product">
|
||||
<img class="img" :src=infoData.goodsImage>
|
||||
<img class="img" :src="infoData.goodsImage" />
|
||||
</div>
|
||||
<div class="show">
|
||||
<label>页面展示:</label>
|
||||
<i-switch size="large" true-value="OPEN" false-value="CLOSE" v-model="infoData.status"
|
||||
@on-change="changeSwitchView" style="margin-top: 3px">
|
||||
<span slot="open">展示</span>
|
||||
<span slot="close">隐藏</span>
|
||||
</i-switch>
|
||||
<el-switch
|
||||
v-model="infoData.status"
|
||||
active-value="OPEN"
|
||||
inactive-value="CLOSE"
|
||||
inline-prompt
|
||||
active-text="展示"
|
||||
inactive-text="隐藏"
|
||||
style="margin-top: 3px"
|
||||
@change="changeSwitchView"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-container">
|
||||
<div class="border-b">{{ infoData.goodsName }}</div>
|
||||
<div class="border-b">
|
||||
<div class="div-height"> 店铺名称:{{ infoData.storeName }}</div>
|
||||
<div class="div-height"> 订单号:{{ infoData.orderNo }}</div>
|
||||
<div class="div-height">店铺名称:{{ infoData.storeName }}</div>
|
||||
<div class="div-height">订单号:{{ infoData.orderNo }}</div>
|
||||
</div>
|
||||
|
||||
<div class="border-b">
|
||||
<List>
|
||||
|
||||
<ListItem>
|
||||
<ListItemMeta :avatar="infoData.memberProfile" :title="infoData.memberName"
|
||||
:description="infoData.content"/>
|
||||
</ListItem>
|
||||
<div class="score-content">
|
||||
<span>物流评分:{{infoData.deliveryScore}}</span>
|
||||
<span>服务评分:{{infoData.serviceScore}}</span>
|
||||
<span>描述评分:{{infoData.descriptionScore}}</span>
|
||||
<div class="review-item">
|
||||
<el-avatar v-if="infoData.memberProfile" :src="infoData.memberProfile" :size="40" />
|
||||
<div class="review-meta">
|
||||
<div class="review-name">{{ infoData.memberName }}</div>
|
||||
<div class="review-content">{{ infoData.content }}</div>
|
||||
</div>
|
||||
<div class="" v-if="infoData.haveImage">
|
||||
评价图
|
||||
<div style="margin-left: 40px">
|
||||
<template v-if="infoData.images && infoData.images.length">
|
||||
<img style="width: 100px;height: 110px;margin-left: 2px"
|
||||
v-for="(img,index) in infoData.images.split(',')" :src="img"
|
||||
alt="" :key="index"/>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="score-content">
|
||||
<span>物流评分:{{ infoData.deliveryScore }}</span>
|
||||
<span>服务评分:{{ infoData.serviceScore }}</span>
|
||||
<span>描述评分:{{ infoData.descriptionScore }}</span>
|
||||
</div>
|
||||
<div v-if="infoData.haveImage">
|
||||
评价图
|
||||
<div style="margin-left: 40px">
|
||||
<template v-if="infoData.images && infoData.images.length">
|
||||
<img
|
||||
v-for="(img, index) in infoData.images.split(',')"
|
||||
:key="index"
|
||||
style="width: 100px; height: 110px; margin-left: 2px"
|
||||
:src="img"
|
||||
alt=""
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-b" v-if="infoData.reply">
|
||||
<div v-if="infoData.reply" class="border-b">
|
||||
<div>
|
||||
<div>
|
||||
<div style="float: left"> 商家回复:</div>
|
||||
<div style="margin-left: 60px">{{ infoData.reply }}</div>
|
||||
</div>
|
||||
<div v-if="infoData.haveReplyImage">
|
||||
<div style="margin-left: 60px">
|
||||
<template v-if="infoData.replyImage && infoData.replyImage.length">
|
||||
<img style="width: 100px;height: 110px" v-for="(img,index) in infoData.replyImage.split(',')" :key="index"
|
||||
:src="img" alt=""/>
|
||||
</template>
|
||||
</div>
|
||||
<div style="float: left">商家回复:</div>
|
||||
<div style="margin-left: 60px">{{ infoData.reply }}</div>
|
||||
</div>
|
||||
<div v-if="infoData.haveReplyImage">
|
||||
<div style="margin-left: 60px">
|
||||
<template v-if="infoData.replyImage && infoData.replyImage.length">
|
||||
<img
|
||||
v-for="(img, index) in infoData.replyImage.split(',')"
|
||||
:key="index"
|
||||
style="width: 100px; height: 110px"
|
||||
:src="img"
|
||||
alt=""
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -105,223 +173,66 @@
|
||||
import * as API_Member from "@/api/member";
|
||||
|
||||
export default {
|
||||
name: "goods-review", // 会员评价
|
||||
name: "goods-review",
|
||||
data() {
|
||||
return {
|
||||
infoData: {}, // 商品信息
|
||||
infoFlag: false, // 评价展示
|
||||
infoTitle: "", // modal名称
|
||||
loading: true, // 表单加载状态
|
||||
infoData: {},
|
||||
infoFlag: false,
|
||||
infoTitle: "",
|
||||
loading: true,
|
||||
searchForm: {
|
||||
// 搜索框初始化对象
|
||||
pageNumber: 1, // 当前页数
|
||||
pageSize: 20, // 页面大小
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
goodsName: "",
|
||||
sort: "createTime", // 默认排序字段
|
||||
order: "desc", // 默认排序方式
|
||||
startDate: "", // 起始时间
|
||||
endDate: "", // 终止时间
|
||||
sort: "createTime",
|
||||
order: "desc",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
},
|
||||
columns: [
|
||||
// 表头
|
||||
{
|
||||
title: "商品名称",
|
||||
key: "goodsName",
|
||||
minWidth: 120,
|
||||
align: "left",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "会员名称",
|
||||
key: "memberName",
|
||||
minWidth: 120,
|
||||
align: "left",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "评论内容",
|
||||
key: "content",
|
||||
minWidth: 220,
|
||||
align: "left",
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "是否置顶",
|
||||
key: "top",
|
||||
align: "center",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"Tag",
|
||||
{
|
||||
props: {
|
||||
color: params.row.top ? "red" : "default",
|
||||
},
|
||||
},
|
||||
params.row.top ? "已置顶" : "未置顶"
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "评价",
|
||||
key: "grade",
|
||||
align: "left",
|
||||
width: 90,
|
||||
render: (h, params) => {
|
||||
if (params.row.grade == "GOOD") {
|
||||
return h("Tag", {props: {color: "green",},}, "好评");
|
||||
} else if (params.row.grade == "MODERATE") {
|
||||
return h("Tag", {props: {color: "orange",},}, "中评");
|
||||
} else {
|
||||
return h("Tag", {props: {color: "red",},}, "差评");
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "评价时间",
|
||||
key: "createTime",
|
||||
align: "left",
|
||||
width: 170
|
||||
},
|
||||
{
|
||||
title: "页面展示",
|
||||
key: "shopDisable",
|
||||
align: "left",
|
||||
width: 100,
|
||||
slot: "shopDisableSlot",
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 220,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
return h("div", { class: "ops" }, [
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.info(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
"查看"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2",
|
||||
},
|
||||
},
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
this.updateTop(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
params.row.top ? "取消置顶" : "置顶评论"
|
||||
),
|
||||
h(
|
||||
"span",
|
||||
{
|
||||
style: {
|
||||
margin: "0 8px",
|
||||
color: "#dcdee2",
|
||||
},
|
||||
},
|
||||
"|"
|
||||
),
|
||||
h(
|
||||
"Poptip",
|
||||
{
|
||||
props: { confirm: true, title: "确认删除" },
|
||||
on: {
|
||||
"on-ok": () => {
|
||||
this.remove(params.row);
|
||||
},
|
||||
},
|
||||
},
|
||||
[
|
||||
h(
|
||||
"a",
|
||||
{
|
||||
style: {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
},
|
||||
},
|
||||
"删除"
|
||||
),
|
||||
]
|
||||
),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [], // 表单数据
|
||||
total: 0, // 表单数据总数
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 切换查看switch
|
||||
changeSwitchView(val) {
|
||||
let status = val;
|
||||
API_Member.updateMemberReview(this.infoData.id, {status}).then(
|
||||
(res) => {
|
||||
this.$Message.success("修改成功!");
|
||||
this.init();
|
||||
}
|
||||
);
|
||||
gradeTagType(grade) {
|
||||
if (grade === "GOOD") return "success";
|
||||
if (grade === "MODERATE") return "warning";
|
||||
return "danger";
|
||||
},
|
||||
gradeText(grade) {
|
||||
if (grade === "GOOD") return "好评";
|
||||
if (grade === "MODERATE") return "中评";
|
||||
return "差评";
|
||||
},
|
||||
changeSwitchView(val) {
|
||||
const status = val;
|
||||
API_Member.updateMemberReview(this.infoData.id, { status }).then(() => {
|
||||
this.$Message.success("修改成功!");
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getDataList();
|
||||
},
|
||||
// 分页 改变页码
|
||||
changePage(v) {
|
||||
this.searchForm.pageNumber = v;
|
||||
this.getDataList();
|
||||
this.clearSelectAll();
|
||||
},
|
||||
// 分页 改变页数
|
||||
changePageSize(v) {
|
||||
this.searchForm.pageSize = v;
|
||||
this.getDataList();
|
||||
},
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.searchForm.pageNumber = 1;
|
||||
this.searchForm.pageSize = 20;
|
||||
this.getDataList();
|
||||
},
|
||||
//列表直接选择页面是否展示
|
||||
changeSwitch(v) {
|
||||
let status = v.status;
|
||||
API_Member.updateMemberReview(v.id, {status: status}).then((res) => {
|
||||
const status = v.status;
|
||||
API_Member.updateMemberReview(v.id, { status }).then(() => {
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
// 置顶评论
|
||||
updateTop(v) {
|
||||
const top = !v.top;
|
||||
API_Member.updateMemberReviewTop(v.id, { top }).then((res) => {
|
||||
@@ -340,7 +251,6 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 获取列表
|
||||
getDataList() {
|
||||
this.loading = true;
|
||||
API_Member.getMemberReview(this.searchForm).then((res) => {
|
||||
@@ -353,7 +263,6 @@ export default {
|
||||
this.total = this.data.length;
|
||||
this.loading = false;
|
||||
},
|
||||
//评价详情
|
||||
info(v) {
|
||||
this.infoFlag = true;
|
||||
this.infoTitle = `用户${v.memberName}的评价详情`;
|
||||
@@ -363,14 +272,13 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 删除评论
|
||||
remove(v) {
|
||||
this.$Modal.confirm({
|
||||
title: "确认删除",
|
||||
content: "您确认要删除会员" + v.memberName + "的评论?",
|
||||
loading: true,
|
||||
onOk: () => {
|
||||
API_Member.delMemberReview(v.id).then((res) => {
|
||||
API_Member.delMemberReview(v.id).then(() => {
|
||||
this.$Modal.remove();
|
||||
this.$Message.success("修改成功");
|
||||
this.init();
|
||||
@@ -384,6 +292,7 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.left-container {
|
||||
float: left;
|
||||
@@ -408,8 +317,8 @@ img {
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.show{
|
||||
label{
|
||||
.show {
|
||||
label {
|
||||
font-size: 14px;
|
||||
}
|
||||
margin-top: 15px;
|
||||
@@ -430,12 +339,26 @@ label {
|
||||
position: relative;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.div-height{
|
||||
.div-height {
|
||||
line-height: 25px;
|
||||
}
|
||||
.score-content {
|
||||
margin: 5px 0;
|
||||
span{margin-right: 20px;}
|
||||
span {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
.review-item {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.review-name {
|
||||
font-weight: 500;
|
||||
}
|
||||
.review-content {
|
||||
color: #666;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.ops a {
|
||||
color: #2d8cf0;
|
||||
|
||||
@@ -1,61 +1,70 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Row class="operation padding-row">
|
||||
<Button type="primary" @click="openAdd">添加分组</Button>
|
||||
</Row>
|
||||
<Table
|
||||
:loading="loading"
|
||||
border
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
ref="table"
|
||||
class="mt_10"
|
||||
></Table>
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<el-card>
|
||||
<div class="operation padding-row">
|
||||
<el-button type="primary" @click="openAdd">添加分组</el-button>
|
||||
</div>
|
||||
|
||||
<el-table ref="table" v-loading="loading" :data="data" border class="mt_10" style="width: 100%">
|
||||
<el-table-column prop="groupName" label="分组名称" min-width="160" show-overflow-tooltip />
|
||||
<el-table-column prop="description" label="分组描述" min-width="240" show-overflow-tooltip />
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" />
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" />
|
||||
<el-table-column label="操作" width="200" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="ops" style="display: flex; justify-content: center">
|
||||
<a class="link-text" @click="openEdit(row)">编辑</a>
|
||||
<span class="op-split">|</span>
|
||||
<a class="link-text" @click="remove(row)">删除</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
<Modal v-model="addFlag" title="添加商品分组">
|
||||
<Form ref="addForm" :model="formAdd" :rules="rulesAdd" :label-width="90">
|
||||
<FormItem label="分组名称" prop="groupName" style="width: 90%;">
|
||||
<Input v-model="formAdd.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</FormItem>
|
||||
<FormItem label="分组描述" prop="description" style="width: 90%;">
|
||||
<Input v-model="formAdd.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="addFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitAddLoading" @click="submitAdd">确定</Button>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal v-model="editFlag" title="编辑商品分组">
|
||||
<Form ref="editForm" :model="formEdit" :rules="rulesEdit" :label-width="90">
|
||||
<Input v-model="formEdit.id" v-show="false" />
|
||||
<FormItem label="分组名称" prop="groupName" style="width: 90%;">
|
||||
<Input v-model="formEdit.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</FormItem>
|
||||
<FormItem label="分组描述" prop="description" style="width: 90%;">
|
||||
<Input v-model="formEdit.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer">
|
||||
<Button @click="editFlag = false">取消</Button>
|
||||
<Button type="primary" :loading="submitEditLoading" @click="submitEdit">确定</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="addFlag" title="添加商品分组" width="500px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="addForm" :model="formAdd" :rules="rulesAdd" label-width="90px">
|
||||
<el-form-item label="分组名称" prop="groupName" style="width: 90%">
|
||||
<el-input v-model="formAdd.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分组描述" prop="description" style="width: 90%">
|
||||
<el-input v-model="formAdd.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="addFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitAddLoading" @click="submitAdd">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="editFlag" title="编辑商品分组" width="500px" :close-on-click-modal="false" destroy-on-close>
|
||||
<el-form ref="editForm" :model="formEdit" :rules="rulesEdit" label-width="90px">
|
||||
<el-input v-model="formEdit.id" style="display: none" />
|
||||
<el-form-item label="分组名称" prop="groupName" style="width: 90%">
|
||||
<el-input v-model="formEdit.groupName" maxlength="30" placeholder="请输入分组名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分组描述" prop="description" style="width: 90%">
|
||||
<el-input v-model="formEdit.description" maxlength="200" placeholder="请输入分组描述" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="editFlag = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitEditLoading" @click="submitEdit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -71,54 +80,6 @@ export default {
|
||||
pageNumber: 1,
|
||||
pageSize: 20,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: "分组名称",
|
||||
key: "groupName",
|
||||
minWidth: 160,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "分组描述",
|
||||
key: "description",
|
||||
minWidth: 240,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
key: "createTime",
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
key: "updateTime",
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
align: "center",
|
||||
width: 200,
|
||||
fixed: "right",
|
||||
render: (h, params) => {
|
||||
const linkStyle = {
|
||||
color: "#2d8cf0",
|
||||
cursor: "pointer",
|
||||
textDecoration: "none",
|
||||
};
|
||||
const sep = h(
|
||||
"span",
|
||||
{ style: { margin: "0 8px", color: "#dcdee2" } },
|
||||
"|"
|
||||
);
|
||||
return h("div", { class: "ops", style: { display: "flex", justifyContent: "center" } }, [
|
||||
h("a", { style: linkStyle, on: { click: () => this.openEdit(params.row) } }, "编辑"),
|
||||
sep,
|
||||
h("a", { style: linkStyle, on: { click: () => this.remove(params.row) } }, "删除"),
|
||||
]);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
total: 0,
|
||||
addFlag: false,
|
||||
@@ -135,10 +96,10 @@ export default {
|
||||
description: "",
|
||||
},
|
||||
rulesAdd: {
|
||||
groupName: [{ required: true, message: "请输入分组名称" }],
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
},
|
||||
rulesEdit: {
|
||||
groupName: [{ required: true, message: "请输入分组名称" }],
|
||||
groupName: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||
},
|
||||
};
|
||||
},
|
||||
@@ -248,7 +209,7 @@ export default {
|
||||
remove(row) {
|
||||
this.$Modal.confirm({
|
||||
title: "提示",
|
||||
content: "<p>确定删除该分组?</p>",
|
||||
content: "确定删除该分组?",
|
||||
onOk: () => {
|
||||
API_Goods.deleteGoodsGroup(row.id)
|
||||
.then((res) => {
|
||||
@@ -271,3 +232,16 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ops a {
|
||||
color: #2d8cf0;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ops span {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
color: #dcdee2;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,120 +1,160 @@
|
||||
<template>
|
||||
<div class="search">
|
||||
<Card>
|
||||
<Form
|
||||
<el-card>
|
||||
<el-form
|
||||
ref="searchForm"
|
||||
:model="searchForm"
|
||||
inline
|
||||
:label-width="70"
|
||||
label-width="70px"
|
||||
class="search-form"
|
||||
@keydown.enter.native="handleSearch"
|
||||
@keyup.enter="handleSearch"
|
||||
>
|
||||
<Form-item label="商品名称" prop="goodsName">
|
||||
<Input
|
||||
<el-form-item label="商品名称" prop="goodsName">
|
||||
<el-input
|
||||
v-model="searchForm.goodsName"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="商品ID" prop="goodsId">
|
||||
<Input
|
||||
</el-form-item>
|
||||
<el-form-item label="商品ID" prop="goodsId">
|
||||
<el-input
|
||||
v-model="searchForm.goodsId"
|
||||
placeholder="请输入商品ID"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="SKU货号" prop="sn">
|
||||
<Input
|
||||
</el-form-item>
|
||||
<el-form-item label="SKU货号" prop="sn">
|
||||
<el-input
|
||||
v-model="searchForm.sn"
|
||||
placeholder="请输入SKU货号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Form-item label="店铺名称" prop="storeName">
|
||||
<Input
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺名称" prop="storeName">
|
||||
<el-input
|
||||
v-model="searchForm.storeName"
|
||||
placeholder="请输入店铺名称"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
/>
|
||||
</Form-item>
|
||||
<Button
|
||||
@click="handleSearch"
|
||||
class="search-btn"
|
||||
type="primary"
|
||||
icon="ios-search"
|
||||
>
|
||||
搜索
|
||||
</Button>
|
||||
<Button @click="handleReset" style="margin-left: 8px">重置</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" class="search-btn" @click="handleSearch">搜索</el-button>
|
||||
<el-button style="margin-left: 8px" @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<Card class="mt_10">
|
||||
<Alert show-icon>
|
||||
支持按规格逐条设置虚拟销量,列表总销量 = 真实销量 + 虚拟销量。
|
||||
</Alert>
|
||||
<el-card class="mt_10">
|
||||
<el-alert
|
||||
type="info"
|
||||
show-icon
|
||||
:closable="false"
|
||||
title="支持按规格逐条设置虚拟销量,列表总销量 = 真实销量 + 虚拟销量。"
|
||||
style="margin-bottom: 10px"
|
||||
/>
|
||||
|
||||
<div class="batch-operations">
|
||||
<Button
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="selectedRows.length === 0"
|
||||
@click="openBatchVirtualSalesModal"
|
||||
>
|
||||
批量设置虚拟销量
|
||||
</Button>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
:data="data"
|
||||
<el-table
|
||||
ref="table"
|
||||
v-loading="loading"
|
||||
:data="data"
|
||||
class="mt_10"
|
||||
sortable="custom"
|
||||
@on-sort-change="changeSort"
|
||||
@on-selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
@sort-change="changeSort"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<template slot="goodsSlot" slot-scope="{ row }">
|
||||
<div class="goods-info">
|
||||
<img
|
||||
:src="row.thumbnail"
|
||||
class="goods-thumbnail"
|
||||
/>
|
||||
<div class="goods-text">
|
||||
<div class="div-zoom">{{ row.goodsName }}</div>
|
||||
<div class="sub-title" v-if="row.simpleSpecs">
|
||||
规格:{{ row.simpleSpecs.trim() || "-" }}
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column prop="id" label="SKU ID" width="180" show-overflow-tooltip />
|
||||
<el-table-column prop="goodsId" label="商品ID" width="180" show-overflow-tooltip />
|
||||
<el-table-column label="商品信息" min-width="360">
|
||||
<template #default="{ row }">
|
||||
<div v-if="row" class="goods-info">
|
||||
<img
|
||||
v-if="row.thumbnail"
|
||||
:src="row.thumbnail"
|
||||
class="goods-thumbnail"
|
||||
alt=""
|
||||
/>
|
||||
<div class="goods-text">
|
||||
<div class="div-zoom">{{ row.goodsName }}</div>
|
||||
<div v-if="row.simpleSpecs" class="sub-title">
|
||||
规格:{{ row.simpleSpecs.trim() || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="真实销量" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.buyCount || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="虚拟销量" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ row.virtualSalesInput || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总销量" width="110">
|
||||
<template #default="{ row }">
|
||||
<span v-if="row">{{ getTotalSales(row) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row" :type="row.marketEnable === 'UPPER' ? 'success' : 'warning'">
|
||||
{{ row.marketEnable === "UPPER" ? "上架" : "下架" }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="{ row, $index }">
|
||||
<a
|
||||
v-if="row"
|
||||
class="link-text"
|
||||
:class="{ disabled: row.saving }"
|
||||
@click="!row.saving && openVirtualSalesModal(row, $index)"
|
||||
>
|
||||
设置
|
||||
</a>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<Row type="flex" justify="end" class="mt_10">
|
||||
<Page
|
||||
:current="searchForm.pageNumber"
|
||||
<div class="mt_10" style="display: flex; justify-content: flex-end">
|
||||
<el-pagination
|
||||
v-model:current-page="searchForm.pageNumber"
|
||||
v-model:page-size="searchForm.pageSize"
|
||||
:page-sizes="[20, 50, 100]"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
:page-size-opts="[20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
size="small"
|
||||
show-total
|
||||
show-elevator
|
||||
show-sizer
|
||||
@on-change="changePage"
|
||||
@on-page-size-change="changePageSize"
|
||||
></Page>
|
||||
</Row>
|
||||
</Card>
|
||||
@current-change="changePage"
|
||||
@size-change="changePageSize"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<Modal
|
||||
<el-dialog
|
||||
v-model="editModalVisible"
|
||||
:title="modalMode === 'batch' ? '批量设置虚拟销量' : '设置虚拟销量'"
|
||||
:mask-closable="false"
|
||||
:closable="!modalSubmitting"
|
||||
width="480px"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="!modalSubmitting"
|
||||
:show-close="!modalSubmitting"
|
||||
destroy-on-close
|
||||
>
|
||||
<div v-if="modalMode === 'single' && currentSku" class="virtual-sales-modal">
|
||||
<div class="sku-info-item">
|
||||
@@ -129,50 +169,42 @@
|
||||
<span class="sku-info-label">SKU ID:</span>
|
||||
<span>{{ currentSku.id || "-" }}</span>
|
||||
</div>
|
||||
|
||||
<Form :label-width="90" class="mt_10">
|
||||
<Form-item label="虚拟销量">
|
||||
<InputNumber
|
||||
<el-form label-width="90px" class="mt_10">
|
||||
<el-form-item label="虚拟销量">
|
||||
<el-input-number
|
||||
v-model="editForm.virtualSales"
|
||||
:min="0"
|
||||
:max="99999999"
|
||||
:precision="0"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</Form-item>
|
||||
</Form>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div v-else-if="modalMode === 'batch'" class="virtual-sales-modal">
|
||||
<div class="sku-info-item">
|
||||
<span class="sku-info-label">已选规格:</span>
|
||||
<span>{{ selectedRows.length }} 个</span>
|
||||
</div>
|
||||
|
||||
<Form :label-width="90" class="mt_10">
|
||||
<Form-item label="虚拟销量">
|
||||
<InputNumber
|
||||
<el-form label-width="90px" class="mt_10">
|
||||
<el-form-item label="虚拟销量">
|
||||
<el-input-number
|
||||
v-model="editForm.virtualSales"
|
||||
:min="0"
|
||||
:max="99999999"
|
||||
:precision="0"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</Form-item>
|
||||
</Form>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<Button @click="handleCancelVirtualSales" :disabled="modalSubmitting">
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
:loading="modalSubmitting"
|
||||
@click="handleSubmitVirtualSales"
|
||||
>
|
||||
<template #footer>
|
||||
<el-button :disabled="modalSubmitting" @click="handleCancelVirtualSales">取消</el-button>
|
||||
<el-button type="primary" :loading="modalSubmitting" @click="handleSubmitVirtualSales">
|
||||
提交
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -216,84 +248,6 @@ export default {
|
||||
sn: "",
|
||||
storeName: "",
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
type: "selection",
|
||||
width: 60,
|
||||
align: "center",
|
||||
},
|
||||
{
|
||||
title: "SKU ID",
|
||||
key: "id",
|
||||
width: 180,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品ID",
|
||||
key: "goodsId",
|
||||
width: 180,
|
||||
tooltip: true,
|
||||
},
|
||||
{
|
||||
title: "商品信息",
|
||||
key: "goodsName",
|
||||
minWidth: 360,
|
||||
slot: "goodsSlot",
|
||||
},
|
||||
{
|
||||
title: "真实销量",
|
||||
key: "buyCount",
|
||||
width: 110,
|
||||
render: (h, params) => h("span", params.row.buyCount || 0),
|
||||
},
|
||||
{
|
||||
title: "虚拟销量",
|
||||
key: "virtualSalesInput",
|
||||
width: 110,
|
||||
render: (h, params) => h("span", params.row.virtualSalesInput || 0),
|
||||
},
|
||||
{
|
||||
title: "总销量",
|
||||
key: "totalSalesDisplay",
|
||||
width: 110,
|
||||
render: (h, params) => h("span", this.getTotalSales(params.row)),
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
key: "marketEnable",
|
||||
width: 100,
|
||||
render: (h, params) => {
|
||||
const isUpper = params.row.marketEnable === "UPPER";
|
||||
return h(
|
||||
"Tag",
|
||||
{ props: { color: isUpper ? "green" : "volcano" } },
|
||||
isUpper ? "上架" : "下架"
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
key: "action",
|
||||
width: 100,
|
||||
align: "center",
|
||||
render: (h, params) => {
|
||||
return h(
|
||||
"Button",
|
||||
{
|
||||
props: {
|
||||
type: "primary",
|
||||
size: "small",
|
||||
loading: !!params.row.saving,
|
||||
},
|
||||
on: {
|
||||
click: () => this.openVirtualSalesModal(params.row, params.index),
|
||||
},
|
||||
},
|
||||
"设置"
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
data: [],
|
||||
total: 0,
|
||||
};
|
||||
@@ -328,12 +282,13 @@ export default {
|
||||
};
|
||||
this.getDataList();
|
||||
},
|
||||
changeSort(e) {
|
||||
this.searchForm.sort = e.key;
|
||||
this.searchForm.order = e.order;
|
||||
if (e.order === "normal") {
|
||||
changeSort({ prop, order }) {
|
||||
if (!order) {
|
||||
this.searchForm.sort = "create_time";
|
||||
this.searchForm.order = "desc";
|
||||
} else {
|
||||
this.searchForm.sort = prop;
|
||||
this.searchForm.order = order === "ascending" ? "asc" : "desc";
|
||||
}
|
||||
this.getDataList();
|
||||
},
|
||||
@@ -394,9 +349,7 @@ export default {
|
||||
this.editModalVisible = true;
|
||||
},
|
||||
handleCancelVirtualSales() {
|
||||
if (this.modalSubmitting) {
|
||||
return;
|
||||
}
|
||||
if (this.modalSubmitting) return;
|
||||
this.resetVirtualSalesModal();
|
||||
},
|
||||
resetVirtualSalesModal() {
|
||||
@@ -416,18 +369,21 @@ export default {
|
||||
this.handleBatchSubmitVirtualSales(virtualSales);
|
||||
return;
|
||||
}
|
||||
if (!this.currentSku || this.currentIndex < 0) {
|
||||
return;
|
||||
}
|
||||
if (!this.currentSku || this.currentIndex < 0) return;
|
||||
|
||||
const currentIndex = this.currentIndex;
|
||||
const currentSkuId = this.currentSku.id;
|
||||
this.modalSubmitting = true;
|
||||
this.$set(this.data[currentIndex], "saving", true);
|
||||
if (this.data[currentIndex]) {
|
||||
this.data[currentIndex].saving = true;
|
||||
}
|
||||
updateGoodsSkuVirtualSales(currentSkuId, { virtualSales })
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
this.$set(this.data[currentIndex], "virtualSales", virtualSales);
|
||||
this.$set(this.data[currentIndex], "virtualSalesInput", virtualSales);
|
||||
if (this.data[currentIndex]) {
|
||||
this.data[currentIndex].virtualSales = virtualSales;
|
||||
this.data[currentIndex].virtualSalesInput = virtualSales;
|
||||
}
|
||||
this.$Message.success("虚拟销量设置成功");
|
||||
this.resetVirtualSalesModal();
|
||||
} else {
|
||||
@@ -439,7 +395,7 @@ export default {
|
||||
})
|
||||
.finally(() => {
|
||||
if (this.data[currentIndex]) {
|
||||
this.$set(this.data[currentIndex], "saving", false);
|
||||
this.data[currentIndex].saving = false;
|
||||
}
|
||||
this.modalSubmitting = false;
|
||||
});
|
||||
@@ -455,9 +411,7 @@ export default {
|
||||
.then((res) => {
|
||||
if (res && res.success) {
|
||||
this.data = this.data.map((item) => {
|
||||
if (!skuIds.includes(item.id)) {
|
||||
return item;
|
||||
}
|
||||
if (!skuIds.includes(item.id)) return item;
|
||||
return {
|
||||
...item,
|
||||
virtualSales,
|
||||
@@ -465,9 +419,7 @@ export default {
|
||||
};
|
||||
});
|
||||
this.selectedRows = [];
|
||||
if (this.$refs.table) {
|
||||
this.$refs.table.selectAll(false);
|
||||
}
|
||||
this.$refs.table?.clearSelection();
|
||||
this.$Message.success("虚拟销量设置成功");
|
||||
this.resetVirtualSalesModal();
|
||||
} else {
|
||||
@@ -517,6 +469,12 @@ export default {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.div-zoom {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.batch-operations {
|
||||
margin-top: 10px;
|
||||
}
|
||||
@@ -537,4 +495,8 @@ export default {
|
||||
color: #808695;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mt_10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user