提b2c部分基础迁移代码

This commit is contained in:
Yer11214
2024-10-02 20:41:30 +08:00
parent c970309802
commit c03778676c
26 changed files with 4395 additions and 462 deletions

View File

@@ -0,0 +1,528 @@
/*选择商品品类*/
.content-goods-publish {
padding: 15px;
margin: 0 auto;
text-align: center;
border-radius: 0.8em;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
background: none repeat 0 0 #fff;
/*商品品类*/
.goods-category {
min-height: 500px;
border-radius: 0.8em;
text-align: left;
padding: 10px;
background: #ededed;
ul {
padding: 12px 8px;
list-style: none;
width: 300px;
background: none repeat 0 0 #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
border-radius: 0.4em;
display: inline-block;
letter-spacing: normal;
margin-right: 15px;
vertical-align: top;
word-spacing: normal;
li {
line-height: 20px;
padding: 10px 5px;
cursor: pointer;
color: #333;
font-size: 12px;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
}
}
/** 当前品类被选中的样式 */
.activeClass {
border-radius: 0.4em;
background-color: rgba($color: $theme_color, $alpha: 0.2);
border: 1px solid rgba($color: $theme_color, $alpha: 0.8);
color: #fff;
}
/*!*当前选择的商品品类文字*!*/
.current-goods-category {
text-align: left;
padding: 10px;
width: 100%;
border: 1px solid #fbeed5;
color: #c09853;
background-color: #fcf8e3;
margin: 10px auto;
padding: 8px 35px 8px 14px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
font-size: 12px;
font-weight: bold;
}
}
/*编辑基本信息*/
.el-form {
padding-bottom: 80px;
.el-form-item {
width: 100%;
text-align: left;
}
}
.sku-val {
justify-content: flex-start;
flex-wrap: wrap;
>.ivu-form {
flex-wrap: wrap !important;
}
/deep/ .sku-item-content-val {
margin-right: 20px;
}
}
div.base-info-item {
h4 {
margin-bottom: 10px;
padding: 0 10px;
border: 1px solid #ddd;
background-color: #f8f8f8;
font-weight: bold;
color: #333;
font-size: 14px;
line-height: 40px;
text-align: left;
}
>div {
padding-left: 5%;
}
.form-item-view {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-between;
// padding-left: 80px;
.form-item-view-wholesale {
display: flex;
.form-item-view-wholesale-preview {
padding-left: 5%;
}
}
.layout {
margin-bottom: 20px;
width: 100%;
justify-content: center;
.sku-item-content {
margin: 20px 0;
display: flex;
width: 100% !important;
flex: 1;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
width: 100%;
>.ivu-card-body {
width: 100%;
}
.ivu-card-body {
width: 100%;
justify-content: center;
align-items: flex-start;
}
.sku-item-content-name {
display: flex;
align-items: flex-start;
justify-content: flex-start;
width: 100%;
}
}
}
.shop-category-text {
font-size: 12px;
}
}
.form-item-view-bottom {
margin-bottom: 50px;
}
.item-goods-properts-row {
display: flex;
flex-direction: row;
word-break: break-all;
white-space: normal;
width: 300px;
height: 100px;
}
.item-goods-properts {
display: flex;
flex-direction: row;
margin-bottom: 10px;
}
.form-item {
display: flex;
align-items: center;
}
/** 审核信息-拒绝原因 */
.auth-info {
color: red;
}
.el-form-item {
width: 30%;
min-width: 300px;
}
.goods-name-width {
width: 50%;
min-width: 300px;
}
.el-form-item__content {
margin-left: 120px;
text-align: left;
}
p.goods-group-manager {
padding-left: 7.5%;
text-align: left;
color: #999;
font-size: 13px;
}
/*teatarea*/
/deep/ .el-textarea {
width: 150%;
}
.seo-text {
width: 150%;
}
}
/*折叠面板*/
.el-collapse-item {
/deep/ .el-collapse-item__header {
text-align: left;
background-color: #f8f8f8;
padding: 0 10px;
font-weight: bold;
color: #333;
font-size: 14px;
}
.el-form-item {
margin-left: 5%;
width: 25%;
}
/deep/ .el-form-item__content {
margin-left: 120px;
text-align: left;
}
p.goods-group-manager {
padding-left: 12%;
text-align: left;
color: #999;
}
/deep/ .el-collapse-item__content {
padding: 10px 0;
text-align: left;
}
}
.success {
>h1 {
font-size: 28px;
}
>* {
margin: 10px;
}
}
.operation {
>* {
margin: 10px 0;
}
}
/*商品描述*/
.goods-intro {
line-height: 40;
}
/** 底部步骤 */
.footer {
width: 100%;
margin-top: 20px;
padding: 10px;
background-color: #ffc;
position: sticky;
bottom: 0px;
text-align: center;
z-index: 999;
>.ivu-btn {
margin: 0 10px;
}
}
/*图片上传组件第一张图设置封面*/
.goods-images {
/deep/ li.el-upload-list__item:first-child {
position: relative;
}
/deep/ li.el-upload-list__item:first-child:after {
content: "";
color: #fff;
font-weight: bold;
font-size: 12px;
position: absolute;
left: -15px;
top: -6px;
width: 40px;
height: 24px;
padding-top: 6px;
background: #13ce66;
text-align: center;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);
box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);
}
}
.el-form-item__label {
word-break: break-all;
}
.step-list {
height: 60px;
padding: 10px 30px;
background-color: #fff;
margin-bottom: 20px;
border-radius: 0.8em;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.add-sku-btn {
margin-top: 10px;
}
.sku-item:not(:first-child) {
margin-top: 10px;
}
.sku-upload-list {
text-align: center;
border: 1px solid transparent;
border-radius: 4px;
overflow: hidden;
background: #fff;
position: relative;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
margin-right: 8px;
}
.preview-picture {
width: 100%;
margin: 0 auto;
display: block;
// text-align: center;
border: 1px solid transparent;
// justify-self: center;
// align-self: center;
}
.preview-picture img {
width: 100%;
height: 100%;
}
.sku-upload-list img {
width: 100%;
height: 100%;
}
.sku-upload-list-cover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
}
.sku-upload-list:hover .sku-upload-list-cover {
display: block;
}
.sku-upload-list-cover i {
color: #fff;
font-size: 20px;
cursor: pointer;
margin: 0 2px;
}
.required {
/deep/ .ivu-form-item-label::before {
content: "*";
display: inline-block;
margin-right: 4px;
line-height: 1;
font-family: SimSun;
font-size: 14px;
color: #ed4014;
}
}
.demo-upload-list {
width: 150px;
height: 150px;
text-align: center;
border: 1px solid transparent;
border-radius: 4px;
display: inline-block;
background: #fff;
position: relative;
margin-right: 4px;
vertical-align: bottom;
}
.demo-upload-list img {
width: 100%;
height: 100%;
}
.demo-upload-list-cover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
justify-content: space-between;
align-items: center;
flex-direction: column;
}
.demo-upload-list:hover .demo-upload-list-cover {
display: flex;
}
.demo-upload-list-cover div {
margin-top: 50px;
width: 100%;
>i {
width: 50%;
margin-top: 8px;
color: #fff;
font-size: 20px;
cursor: pointer;
}
}
.active-goods-type {
background: #e8e8e8;
}
.goods-type-list {
max-height: 500px;
overflow-y: auto;
}
.template-item {
justify-content: flex-start !important;
}
.tree-bar {
height: auto !important;
max-height: auto !important;
min-height: 240px !important;
}
.goods-type-item {
padding: 20px 0;
width: 100%;
cursor: pointer;
transition: 0.35s;
display: flex;
justify-content: center;
align-items: center;
/deep/ img {
margin-right: 20px;
width: 100px;
margin-left: 10px;
}
/deep/ p {
color: #999;
font-size: 14px;
margin-top: 10px;
}
}
.goods-type-item:hover {
background: #ededed;
}
.goods-list-box {
height: 450px;
overflow: auto;
}
h2 {
cursor: pointer;
font-size: 21px;
color: #333;
}
.form-item-view-wholesale-form-col {
height: 400px;
}
.form-item-view-wholesale-row-del {
display: "flex";
justify-content: "space-between";
align-items: "center";
}
.promise-intro-btn{
margin: 10px 0;
text-align: left;
}

View File

@@ -69,6 +69,9 @@
>搜索</Button
>
</Form>
<div class="mt_10">
<Button type="primary" @click="handleAdd">新增商品</Button>
</div>
<Table
:loading="loading"
border
@@ -336,6 +339,10 @@ export default {
};
},
methods: {
// 新增商品
handleAdd(){
this.$router.push('/goods-publish')
},
// 初始化数据
init() {
this.getDataList();
@@ -410,7 +417,7 @@ export default {
showDetail(v) {
let id = v.id;
this.$options.filters.customRouterPush({
name: "goods-detail",
name: "goods-publish",
query: { id: id },
})
},

View File

@@ -65,12 +65,6 @@
</Button>
</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 }">
<Tag
:class="{ ml_10: row.deleteFlag }"
@@ -113,9 +107,7 @@
<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"
@@ -240,7 +232,6 @@ export default {
specForm: {}, // 规格数据
// 表单验证规则
formValidate: {
commissionRate: [regular.REQUIRED, regular.INTEGER],
name: [regular.REQUIRED, regular.VARCHAR20],
sortOrder: [regular.REQUIRED, regular.INTEGER],
},
@@ -254,12 +245,7 @@ export default {
title: "状态",
slot: "deleteFlag",
},
{
title: "佣金",
key: "commissionRate",
slot: "commissionRate",
},
{
title: "操作",
key: "action",
@@ -340,7 +326,7 @@ export default {
this.modalTitle = "添加子分类";
this.parentTitle = v.name;
this.formAdd.level = eval(v.level + "+1");
this.formAdd.commissionRate = v.commissionRate;
this.formAdd.commissionRate = 0;
this.showParent = true;
delete this.formAdd.id;
this.formAdd.parentId = v.id;
@@ -355,7 +341,7 @@ export default {
this.formAdd.level = v.level;
this.formAdd.parentId = v.parentId;
this.formAdd.sortOrder = v.sortOrder;
this.formAdd.commissionRate = v.commissionRate;
this.formAdd.commissionRate = 0;
this.formAdd.deleteFlag = v.deleteFlag;
this.formAdd.image = v.image;
this.showParent = false;

View File

@@ -18,6 +18,11 @@
<span slot="close">隐藏</span>
</i-switch>
</template>
<!-- 回复状态 -->
<template slot="replyStatus" slot-scope="scope">
<Tag v-if="scope.row.replyStatus" color="green">已回复</Tag>
<Tag v-if="!scope.row.replyStatus" color="red">未回复</Tag>
</template>
</Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="searchForm.pageNumber" :total="total" :page-size="searchForm.pageSize" @on-change="changePage"
@@ -73,22 +78,16 @@
</div>
</List>
</div>
<div class="border-b" v-if="infoData.reply">
<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>
</div>
<div >
<Form ref="form" :model="replyForm" :label-width="100">
<FormItem prop="reply" label="平台回复">
<Input :disabled="infoData.reply" show-word-limit v-model="replyForm.reply" type="textarea"/>
</FormItem>
<FormItem prop="reply" label="回复图片">
</FormItem>
</Form>
</div>
</div>
</div>
</Modal>
@@ -102,6 +101,10 @@ export default {
name: "goods-review", // 会员评价
data() {
return {
replyForm:{
reply:'',
replyImage:[]
},
infoData: {}, // 商品信息
infoFlag: false, // 评价展示
infoTitle: "", // modal名称
@@ -173,6 +176,14 @@ export default {
align: "left",
width: 170
},
{
title: "回复状态",
key: "replyStatus",
align: "left",
width: 100,
slot: "replyStatus",
},
{
title: "页面展示",
key: "shopDisable",

View File

@@ -0,0 +1,60 @@
<template>
<div class="goods-operation">
<div class="step-list">
<steps :current="activestep" style="height:60px;margin-top: 10px">
<step title="选择商品品类"/>
<step title="填写商品详情"/>
<step title="商品发布成功"/>
</steps>
</div>
<!-- 第一步 选择分类 -->
<first-step ref='first' v-show="activestep === 0" @change="getFirstData"></first-step>
<!-- 第二步 商品详细信息 -->
<second-step ref='second' :firstData="firstData" v-if="activestep === 1"></second-step>
<!-- 第三步 发布完成 -->
<third-step ref='third' v-if="activestep === 2"></third-step>
</div>
</template>
<script>
import firstStep from './goodsOperationFirst'
import secondStep from './goodsOperationSec'
import thirdStep from './goodsOperationThird'
export default {
name: "addGoods",
components: {
firstStep,
secondStep,
thirdStep
},
data() {
return {
/** 当前激活步骤*/
activestep: 0,
firstData: {}, // 第一步传递的数据
};
},
methods: {
// 选择商品分类回调
getFirstData (item) {
this.firstData = item;
this.activestep = 1;
}
},
mounted() {
// 编辑商品、模板
if (this.$route.query.id || this.$route.query.draftId) {
this.activestep = 1;
} else {
this.activestep = 0
this.$refs.first.selectGoodsType = true;
}
}
};
</script>
<style lang="scss" scoped>
@import "./addGoods.scss";
</style>

View File

@@ -0,0 +1,260 @@
<template>
<div>
<!-- 选择商品类型 -->
<Modal v-model="selectGoodsType" width="550" :closable="false">
<div class="goods-type-list" v-if="!showGoodsTemplates">
<div
class="goods-type-item"
:class="{ 'active-goods-type': item.check }"
@click="handleClickGoodsType(item)"
v-for="(item, index) in goodsTypeWay"
:key="index"
>
<img :src="item.img" />
<div>
<h2>{{ item.title }}</h2>
<p>{{ item.desc }}</p>
</div>
</div>
</div>
<div v-else class="goods-type-list">
<h2 @click="showGoodsTemplates = !showGoodsTemplates">返回</h2>
<div class="goods-list-box">
<Scroll :on-reach-bottom="handleReachBottom">
<div
class="goods-type-item template-item"
@click="handleClickGoodsTemplate(item)"
v-for="(item, tempIndex) in goodsTemplates"
:key="tempIndex"
>
<img :src="item.thumbnail" />
<div>
<h2>{{ item.goodsName }}</h2>
<p>{{ item.sellingPoint || "" }}</p>
</div>
</div>
</Scroll>
</div>
</div>
</Modal>
<!-- 商品分类 -->
<div class="content-goods-publish">
<div class="goods-category">
<ul v-if="categoryListLevel1.length > 0">
<li
v-for="(item, index) in categoryListLevel1"
:class="{ activeClass: category[0].name === item.name }"
@click="handleSelectCategory(item, index, 1)"
:key="index"
>
<span>{{ item.name }}</span>
<span>&gt;</span>
</li>
</ul>
<ul v-if="categoryListLevel2.length > 0">
<li
v-for="(item, index) in categoryListLevel2"
:class="{ activeClass: category[1].name === item.name }"
@click="handleSelectCategory(item, index, 2)"
:key="index"
>
<span>{{ item.name }}</span>
<span>&gt;</span>
</li>
</ul>
<ul v-if="categoryListLevel3.length > 0">
<li
v-for="(item, index) in categoryListLevel3"
:class="{ activeClass: category[2].name === item.name }"
@click="handleSelectCategory(item, index, 3)"
:key="index"
>
<span>{{ item.name }}</span>
</li>
</ul>
</div>
<p class="current-goods-category">
您当前选择的商品类别是
<span>{{ category[0].name }}</span>
<span v-show="category[1].name">> {{ category[1].name }}</span>
<span v-show="category[2].name">> {{ category[2].name }}</span>
</p>
<template v-if="selectedTemplate.goodsName">
<Divider>已选商品模版:{{ selectedTemplate.goodsName }}</Divider>
</template>
</div>
<!-- 底部按钮 -->
<div class="footer">
<ButtonGroup>
<Button type="primary" @click="selectGoodsType = true">商品类型</Button>
<Button type="primary" @click="next">下一步</Button>
</ButtonGroup>
</div>
</div>
</template>
<script>
import * as API_GOODS from "@/api/goods";
export default {
data() {
return {
selectedTemplate: {}, // 已选模板
selectGoodsType: false, // 展示选择商品分类modal
goodsTemplates: [], // 商品模板列表
showGoodsTemplates: false, //是否显示选择商品模板
goodsTypeWay: [
{
title: "实物商品",
img: require("@/assets/goodsType1.png"),
desc: "零售批发,物流配送",
type: "PHYSICAL_GOODS",
check: false,
},
{
title: "虚拟商品",
img: require("@/assets/goodsType2.png"),
desc: "虚拟核验,无需物流",
type: "VIRTUAL_GOODS",
check: false,
},
{
title: "商品模板导入",
img: require("@/assets/goodsTypeTpl.png"),
desc: "商品模板,一键导入",
check: false,
},
],
// 商品分类选择数组
category: [
{ name: "", id: "" },
{ name: "", id: "" },
{ name: "", id: "" },
],
// 商品类型
goodsType: "",
/** 1级分类列表*/
categoryListLevel1: [],
/** 2级分类列表*/
categoryListLevel2: [],
/** 3级分类列表*/
categoryListLevel3: [],
searchParams: {
saveType: "TEMPLATE",
sort: "create_time",
order: "desc",
pageSize: 10,
pageNumber: 1,
},
templateTotal: 0,
};
},
methods: {
// 商品模版触底加载
handleReachBottom() {
setTimeout(() => {
if (
this.searchParams.pageNumber * this.searchParams.pageSize <=
this.templateTotal
) {
this.searchParams.pageNumber++;
this.GET_GoodsTemplate();
}
}, 1000);
},
// 点击商品类型
handleClickGoodsType(val) {
this.goodsTypeWay.map((item) => {
return (item.check = false);
});
val.check = !val.check;
if (!val.type) {
this.GET_GoodsTemplate();
this.showGoodsTemplates = true;
} else {
this.goodsType = val.type;
this.selectedTemplate = {};
}
},
// 点击商品模板
handleClickGoodsTemplate(val) {
this.selectedTemplate = val;
this.selectGoodsType = false;
this.$emit("change", { tempId: val.id });
},
// 获取商品模板
GET_GoodsTemplate() {
API_GOODS.getDraftGoodsListData(this.searchParams).then((res) => {
if (res.success) {
this.goodsTemplates.push(...res.result.records);
this.templateTotal = res.result.total;
}
});
},
/** 选择商城商品分类 */
handleSelectCategory(row, index, level) {
if (level === 1) {
this.category.forEach((cate) => {
(cate.name = ""), (cate.id = "");
});
this.category[0].name = row.name;
this.category[0].id = row.id;
this.categoryListLevel2 = this.categoryListLevel1[index].children;
this.categoryListLevel3 = [];
} else if (level === 2) {
this.category[1].name = row.name;
this.category[1].id = row.id;
this.category[2].name = "";
this.category[2].id = "";
this.categoryListLevel3 = this.categoryListLevel2[index].children;
} else {
this.category[2].name = row.name;
this.category[2].id = row.id;
}
},
/** 查询下一级 商城商品分类*/
GET_NextLevelCategory(row) {
const _id = row && row.id !== 0 ? row.id : 0;
API_GOODS.getCategoryTree().then((res) => {
if (res.success && res.result) {
this.categoryListLevel1 = res.result;
}
});
},
// 下一步
next() {
window.scrollTo(0, 0);
if (!this.goodsType && !this.selectedTemplate.goodsName) {
this.$Message.error("请选择商品类型");
return;
}
if (!this.category[0].name) {
this.$Message.error("请选择商品分类");
return;
} else if (!this.category[2].name) {
this.$Message.error("必须选择到三级分类");
return;
} else if (this.category[2].name) {
let params = {
category: this.category,
goodsType: this.goodsType,
};
if (this.selectedTemplate.id) {
params.tempId = this.selectedTemplate.id;
this.$emit("change", params);
} else {
this.$emit("change", params);
}
}
},
},
mounted() {
this.GET_NextLevelCategory();
},
};
</script>
<style lang="scss" scoped>
@import "./addGoods.scss";
/deep/ .ivu-scroll-container {
height: 450px !important;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
<template>
<div class="content-goods-publish">
<div class="success" style="text-align: left">
<h1>恭喜您商品发布成功!</h1>
<div class="goToGoodsList" @click="gotoGoodsList">
<a>去店铺查看商品列表>></a>
</div>
<div class="operation">
<h3>您还可以</h3>
<div>
1继续
<a @click="gotoBack">发布商品</a>
</div>
<div>
2进入卖家中心管理
<a @click="gotoGoodsList">商品列表</a>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
methods: {
// 跳转商品列表
gotoGoodsList() {
this.$router.push({name: "goods"});
},
// 刷新页面
gotoBack() {
this.$router.go();
},
}
}
</script>
<style lang="scss" scoped>
@import "./addGoods.scss";
</style>