xh-pan1
11 months ago
135 changed files with 2144 additions and 366 deletions
-
3.eslintignore
-
33canvas-container/assets/font_icon/demo_index.html
-
10canvas-container/assets/font_icon/iconfont.css
-
2canvas-container/assets/font_icon/iconfont.js
-
7canvas-container/assets/font_icon/iconfont.json
-
BINcanvas-container/assets/font_icon/iconfont.ttf
-
BINcanvas-container/assets/font_icon/iconfont.woff
-
BINcanvas-container/assets/font_icon/iconfont.woff2
-
372canvas-container/components/Upload/index.vue
-
50canvas-container/components/canvasEditPage.vue
-
2canvas-container/components/canvasShow/basics/discount/app/index.vue
-
2canvas-container/components/canvasShow/basics/discount/pc/index.vue
-
2canvas-container/components/canvasShow/basics/group/pc/index.vue
-
104canvas-container/components/canvasShow/basics/header/app/index.vue
-
48canvas-container/components/canvasShow/basics/header/mixin.js
-
108canvas-container/components/canvasShow/basics/header/pc/index.vue
-
2canvas-container/components/canvasShow/basics/live/app/index.vue
-
2canvas-container/components/canvasShow/basics/newProduct/app/index.vue
-
2canvas-container/components/canvasShow/basics/price/pc/index.vue
-
2canvas-container/components/canvasShow/basics/product/app/index.vue
-
2canvas-container/components/canvasShow/basics/product/pc/index.vue
-
2canvas-container/components/canvasShow/basics/spike/pc/index.vue
-
2canvas-container/components/canvasShow/basics/text.vue
-
2canvas-container/components/canvasShow/basics/vip/pc/index.vue
-
12canvas-container/components/canvasShow/componentMap.js
-
2canvas-container/components/canvasShow/config/api.js
-
9canvas-container/components/leftBar/panel.vue
-
29canvas-container/components/leftBar/panelList.js
-
1canvas-container/components/toolBar/BasicsComp/assistDiv.vue
-
4canvas-container/components/toolBar/BasicsComp/brandList.vue
-
2canvas-container/components/toolBar/BasicsComp/customTool.vue
-
180canvas-container/components/toolBar/BasicsComp/headerTool.vue
-
4canvas-container/components/toolBar/BasicsComp/imageTextList.vue
-
4canvas-container/components/toolBar/BasicsComp/shopTop.vue
-
2canvas-container/components/toolBar/BasicsComp/textTool.vue
-
22canvas-container/components/toolBar/BasicsComp/videoTool.vue
-
1canvas-container/components/toolBar/componentMap.js
-
8canvas-container/components/toolBar/goodsComp/categoryTool.vue
-
6canvas-container/components/toolBar/goodsComp/productList.vue
-
6canvas-container/components/toolBar/shopComp/discountTool.vue
-
6canvas-container/components/toolBar/shopComp/groupTool.vue
-
2canvas-container/components/toolBar/shopComp/liveTool.vue
-
6canvas-container/components/toolBar/shopComp/newProductTool.vue
-
10canvas-container/components/toolBar/shopComp/priceTool.vue
-
4canvas-container/components/toolBar/shopComp/spikeTool.vue
-
2canvas-container/components/toolBar/shopComp/vipTool.vue
-
113canvas-container/components/toolBar/toolModule/notice-select.vue
-
4canvas-container/components/toolBar/toolModule/product-source-category.vue
-
4canvas-container/components/toolBar/toolModule/product-source-multiple.vue
-
4canvas-container/components/toolBar/toolModule/tool-coupon.vue
-
4canvas-container/components/toolBar/toolModule/tool-select-category.vue
-
50canvas-container/components/toolBar/toolModule/tool-select-link.vue
-
7canvas-container/components/toolBar/toolModule/tool-single-img.vue
-
7canvas-container/views/canvasContainer.vue
-
57mock/index.js
-
81mock/mock-server.js
-
29mock/table.js
-
84mock/user.js
-
25mock/utils.js
-
4package.json
-
4src/App.vue
-
54src/layout/components/Navbar.vue
-
4src/layout/components/Sidebar/SidebarItem.vue
-
182src/locales/en.json
-
184src/locales/zh-CN.json
-
30src/main.js
-
8src/utils/auth.js
-
2src/views/commodity/commdityClass/Edit.vue
-
6src/views/commodity/commdityClass/index.vue
-
12src/views/commodity/commodityList copy/commodityGroup.vue
-
8src/views/commodity/commodityList copy/index.vue
-
14src/views/commodity/commodityList/commodityGroup.vue
-
8src/views/commodity/commodityList/index.vue
-
6src/views/commodity/commoditySystem/addCommodity.vue
-
2src/views/commodity/commoditySystem/addComponent.vue
-
8src/views/commodity/commoditySystem/index.vue
-
4src/views/customer/addClustering.vue
-
10src/views/customer/addOperate.vue
-
8src/views/customer/clusteringList/index.vue
-
4src/views/customer/customerList/customerDetail.vue
-
10src/views/customer/customerList/index.vue
-
6src/views/customer/operate/index.vue
-
10src/views/customer/tagList.vue
-
14src/views/customerService/service/index.vue
-
2src/views/customerService/setting/index.vue
-
20src/views/dashboard/index.vue
-
8src/views/distributor/achievement/programme.vue
-
4src/views/distributor/customer/popSearch.vue
-
4src/views/distributor/customer/popSys.vue
-
4src/views/distributor/exten/invite.vue
-
4src/views/distributor/exten/shopTen.vue
-
8src/views/distributor/personnel/list.vue
-
4src/views/distributor/personnel/sys.vue
-
4src/views/finance/account/index.vue
-
8src/views/finance/list/index.vue
-
8src/views/liveMenu/liveProduct/index.vue
-
12src/views/liveMenu/liveRoom/index.vue
-
6src/views/marketing/channelActivity/form.vue
-
4src/views/marketing/channelActivity/selectChannelCoupons.vue
-
2src/views/marketing/channelCoupons/form.vue
@ -1,5 +1,6 @@ |
|||
build/*.js |
|||
src/assets |
|||
src/canvas-container |
|||
canvas-container |
|||
public |
|||
dist |
|||
canvas-container |
2
canvas-container/assets/font_icon/iconfont.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,372 @@ |
|||
<!-- |
|||
* @FileDescription: index |
|||
* @Author: kahu |
|||
* @Date: 2022/12/14 |
|||
* @LastEditors: kahu |
|||
* @LastEditTime: 2022/12/14 |
|||
--> |
|||
<template> |
|||
<div class="content"> |
|||
<el-upload |
|||
v-loading="isUploading" |
|||
:disabled="componentError" |
|||
class="upload-demo" |
|||
drag |
|||
:headers="headers" |
|||
:file-list="viewFileList" |
|||
:name="name" |
|||
:show-file-list="showFileList" |
|||
:list-type="showFileListType" |
|||
:multiple="multiple" |
|||
:action="uploadUrl" |
|||
:limit="limit" |
|||
:on-success="handleUploadSuccess" |
|||
:before-upload="handleBeforeUpload" |
|||
:on-error="handleUploadError" |
|||
:on-exceed="handleExceed" |
|||
:before-remove="handleBeforeRemove" |
|||
:on-remove="handleRemove" |
|||
:on-preview="handlePreviewOpen" |
|||
> |
|||
<i class="el-icon-upload"></i> |
|||
<div |
|||
class="el-upload__text" |
|||
v-if="!componentError" |
|||
>将文件拖到此处,或<em>点击上传</em></div> |
|||
<div |
|||
class="error-text" |
|||
v-else |
|||
> 组件配置错误,请查看控制台 |
|||
</div> |
|||
<div |
|||
class="el-upload__tip" |
|||
slot="tip" |
|||
> |
|||
文件大小不超过{{ limitSize }}m,文件类型为{{ types.toString() }} |
|||
</div> |
|||
</el-upload> |
|||
|
|||
<!-- 预览 --> |
|||
<el-dialog |
|||
title="预览" |
|||
:visible.sync="previewObj.show" |
|||
width="60%" |
|||
:before-close="handlePreviewClose" |
|||
> |
|||
<div class="preview-content"> |
|||
<template v-if="previewObj.file && previewObj.file.type.includes('image')"> |
|||
<el-image class="preview-item" :src="previewObj.file.url" /> |
|||
</template> |
|||
<template v-if="previewObj.file && previewObj.file.type.includes('video')"> |
|||
<video class="preview-item" controls :src="previewObj.file.url" /> |
|||
</template> |
|||
</div> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import mime from 'mime' |
|||
let fullLoading = null |
|||
const baseURL = process.env.VUE_APP_DOMAIN_PREFIX |
|||
export default { |
|||
name: "Upload", |
|||
props: { |
|||
headers:{ |
|||
type:Object, |
|||
default:()=>({}) |
|||
}, |
|||
/** 上传时候表单的KEY */ |
|||
name: { |
|||
type: String, |
|||
default: () => "file" |
|||
}, |
|||
/** 限制上传数量 */ |
|||
limit: { |
|||
type: Number, |
|||
default: () => 5 |
|||
}, |
|||
/** 限制的那张大小 单位M */ |
|||
limitSize: { |
|||
type: Number, |
|||
default: () => 5 |
|||
}, |
|||
/** 是否多选 */ |
|||
multiple: { |
|||
type: Boolean, |
|||
default: () => true |
|||
}, |
|||
/** 是否展示文件列表 */ |
|||
showFileList: { |
|||
type: Boolean, |
|||
default: () => true |
|||
}, |
|||
/** 文件展示方式 text/picture/picture-card */ |
|||
showFileListType:{ |
|||
type:String, |
|||
default:()=>'text' |
|||
}, |
|||
/** 允许上传的文件尾缀 string[] */ |
|||
types: { |
|||
type: Array, |
|||
default: () => (['jpg', 'png', 'gif']) |
|||
}, |
|||
/** 默认的文件列表 string[] */ |
|||
defaultFileList: { |
|||
type: Array, |
|||
default: () => ([]) |
|||
}, |
|||
/** 上传成功后端返回的字段名称 */ |
|||
responseFileName: { |
|||
type: String, |
|||
default: () => 'url' |
|||
}, |
|||
/** 是否需要全屏loading */ |
|||
needFullScreenLoading:{ |
|||
type:Boolean, |
|||
default:()=>true |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
uploadUrl: `${ baseURL }/file/upload`, |
|||
// 真实文件列表 |
|||
fileList: [], |
|||
// 默认展示的list,解决多上传只回调success一次的问题 |
|||
viewFileList:[], |
|||
// 组件是否部署错误 |
|||
componentError: false, |
|||
// 是否正在上传 |
|||
isUploading:false, |
|||
// 预览对象 |
|||
previewObj:{ |
|||
show:false, |
|||
file:null |
|||
} |
|||
} |
|||
}, |
|||
watch: { |
|||
defaultFileList: { |
|||
handler() { |
|||
// 判断类型 |
|||
const flag = Object.prototype.toString.call(this.defaultFileList) === '[object Array]' |
|||
&& this.defaultFileList.length > 0 && |
|||
Object.prototype.toString.call(this.defaultFileList[0]) !== '[object String]' |
|||
if (flag) { |
|||
this.componentError = true |
|||
throw new Error('defaultFileList格式错误,应为string[]格式') |
|||
}else{ |
|||
this.componentError = false |
|||
} |
|||
this.viewFileList = this.defaultFileList.map(defaultFilePath => ({name: defaultFilePath, url: defaultFilePath})) |
|||
this.viewFileList.forEach(item=>{ |
|||
this.fileList.push(item) |
|||
}) |
|||
}, |
|||
deep: true, |
|||
immediate: true |
|||
}, |
|||
fileList:{ |
|||
handler(){ |
|||
this.handleNotifyFather() |
|||
}, |
|||
deep:true, |
|||
immediate:false |
|||
} |
|||
}, |
|||
methods: { |
|||
/** |
|||
* 检查type是否符合types的mime |
|||
* @param type 文件后缀 |
|||
* @param types 可用文件后缀集合 |
|||
*/ |
|||
handleCheckFileMime(type, types) { |
|||
const typeMimes = types.map(item => mime.getType(item)) |
|||
return typeMimes.includes(type) |
|||
}, |
|||
|
|||
handleCheckFileSize(fileSize, limitSize) { |
|||
const limitByteSize = limitSize * 1024 * 1024 |
|||
return limitByteSize > fileSize |
|||
}, |
|||
|
|||
/** |
|||
* 上传之前的钩子 |
|||
* @param file |
|||
* @return {undefined} |
|||
*/ |
|||
handleBeforeUpload(file) { |
|||
// 检查mime |
|||
const fileType = file.type || mime.getType(file.name.slice(file.name.lastIndexOf('.') + 1)) |
|||
const checkFileMime = this.handleCheckFileMime(fileType, this.types) |
|||
const checkFileSize = this.handleCheckFileSize(file.size, this.limitSize); |
|||
!checkFileSize ? file.isJumpRemove = true : undefined |
|||
!checkFileSize ? this.$notify.warning(`文件大小不得超出${ this.limitSize }m`) : undefined |
|||
!checkFileMime ? file.isJumpRemove = true : undefined |
|||
!checkFileMime ? this.$notify.warning(`文件类型不在合法列表 ${ this.types }`) : undefined |
|||
if(checkFileSize && checkFileMime){ |
|||
// 开启loading |
|||
this.isUploading = true |
|||
if(this.needFullScreenLoading){ |
|||
fullLoading = this.$loading({ |
|||
background:`rgba(255,255,255,0.5)`, |
|||
text:'上传中', |
|||
fullscreen:true |
|||
}) |
|||
} |
|||
} |
|||
return checkFileSize && checkFileMime |
|||
}, |
|||
|
|||
/** |
|||
* 上传成功钩子 |
|||
* @param response |
|||
* @param file |
|||
* @param fileList |
|||
*/ |
|||
handleUploadSuccess(response, file, fileList) { |
|||
this.isUploading = false |
|||
if(this.needFullScreenLoading){ |
|||
fullLoading?.close() |
|||
} |
|||
const successObj = { |
|||
url: response.data[this.responseFileName], |
|||
name: file.name |
|||
} |
|||
file.url = response.data[this.responseFileName] |
|||
this.fileList.push(successObj) |
|||
}, |
|||
|
|||
/** |
|||
* 上传失败的钩子 |
|||
* @param err |
|||
* @param file |
|||
* @param fileList |
|||
*/ |
|||
handleUploadError(err, file, fileList) { |
|||
}, |
|||
|
|||
/** |
|||
* 超出数量的钩子 |
|||
* @param files |
|||
* @param fileList |
|||
*/ |
|||
handleExceed(files, fileList) { |
|||
this.$notify.warning(`文件总数大于可上传数量 ${ this.limit }`) |
|||
}, |
|||
|
|||
/** |
|||
* 文件即将移除的钩子 |
|||
* @param file |
|||
* @param fileList |
|||
*/ |
|||
async handleBeforeRemove(file, fileList) { |
|||
// 如果是超出文件大小调用,放行 |
|||
if (file?.raw?.isJumpRemove) { |
|||
return true |
|||
} |
|||
return await this.$confirm('此操作将会删除已上传的文件, 是否继续?', '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}) |
|||
}, |
|||
|
|||
/** |
|||
* 移除文件的钩子 |
|||
*/ |
|||
handleRemove(file, fileList) { |
|||
if (file?.raw?.isJumpRemove) { |
|||
return |
|||
} |
|||
this.fileList.splice(this.fileList.findIndex(fileItem => file?.response?.data[this.responseFileName] === fileItem.url || file.url === fileItem.url), 1) |
|||
}, |
|||
|
|||
/** |
|||
* 通知父组件 |
|||
*/ |
|||
handleNotifyFather(){ |
|||
this.$emit('change',this.fileList) |
|||
}, |
|||
|
|||
/** |
|||
* 预览 |
|||
* 图片视频直接预览,其他下载 |
|||
* @param file |
|||
*/ |
|||
handlePreviewOpen(file){ |
|||
if(!file.type){ |
|||
file.type = mime.getType(file?.url?.slice(file?.url?.lastIndexOf('.')+1)) || mime.getType(file?.name?.slice(file?.name.lastIndexOf('.')+1)) || undefined |
|||
} |
|||
if(file.type.includes('image') || file.type.includes('video')){ |
|||
this.previewObj.file = file |
|||
this.previewObj.show = true |
|||
}else{ |
|||
this.$confirm('需要下载才能预览此文件, 是否继续?', '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
}).then(() => { |
|||
let htmlAnchorElement = document.createElement('a'); |
|||
htmlAnchorElement.download = file?.url.slice(file?.url.lastIndexOf('/')+1) |
|||
htmlAnchorElement.target='_bank' |
|||
htmlAnchorElement.href = file?.url |
|||
htmlAnchorElement.click() |
|||
htmlAnchorElement = null |
|||
}).catch(() => { |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
handlePreviewClose(){ |
|||
this.previewObj.file = null |
|||
this.previewObj.show = false |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style |
|||
lang="scss" |
|||
scoped |
|||
> |
|||
::v-deep .el-upload { |
|||
width: 100% !important; |
|||
|
|||
.el-upload-dragger { |
|||
width: 100% !important; |
|||
} |
|||
} |
|||
|
|||
.error-text { |
|||
font-size: 18px; |
|||
font-weight: bolder; |
|||
color: red; |
|||
animation: error-animation 2.5s ease-in-out infinite; |
|||
} |
|||
|
|||
@keyframes error-animation { |
|||
0%, 100% { |
|||
font-size: 18px; |
|||
color: red; |
|||
} |
|||
25%, 75% { |
|||
font-size: 16px; |
|||
color: #b9b1b1; |
|||
} |
|||
50% { |
|||
font-size: 18px; |
|||
color: #500000; |
|||
} |
|||
} |
|||
|
|||
.preview-content{ |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
.preview-item{ |
|||
min-width: 800px; |
|||
} |
|||
} |
|||
|
|||
</style> |
@ -0,0 +1,104 @@ |
|||
<template> |
|||
<div class="header"> |
|||
<div class="top-box"> |
|||
<img v-if="componentContent.logoType === 1" class="logo" |
|||
:src="componentContent.imageUrl" |
|||
mode="heightFix"> |
|||
<h3 v-else class="h3" :style="{fontSize:componentContent.fontSizeNum+'px',fontWeight:componentContent.textFontW,color:componentContent.titColor}">{{componentContent.title}}</h3> |
|||
<div class="search-btn"> |
|||
<img class="search-icon" |
|||
src="https://ceres.zkthink.com/static/img/search.png" |
|||
mode="widthFix"> |
|||
</div> |
|||
</div> |
|||
<div class="tabs-nav-warp"> |
|||
<div class="tabs-nav" scroll-x="true"> |
|||
<div class="ul"> |
|||
<div class="li" :class="{'on':activeTab===0}" @click="tabChange(0)">首页</div> |
|||
<div class="li" :class="{'on':activeTab===index+1}" v-for="(item,index) in classifyData" :key="index"> |
|||
{{item.categoryName}} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
data () { |
|||
return { |
|||
activeTab: 0 |
|||
} |
|||
}, |
|||
computed: { |
|||
|
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.header { |
|||
.top-box { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding-left: 30px; |
|||
width: 100%; |
|||
.logo { |
|||
// width: 280px; |
|||
height: 70px; |
|||
margin-top: 0px; |
|||
} |
|||
|
|||
.search-btn { |
|||
height: 66px; |
|||
background: rgba(255, 255, 255, 1); |
|||
border-radius: 33px; |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
margin-right: 30px; |
|||
.search-icon { |
|||
width: 60px; |
|||
height: 60px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.tabs-nav-warp{ |
|||
margin-top: 20px; |
|||
padding:0 30px; |
|||
overflow: hidden; |
|||
.tabs-nav{ |
|||
.ul{ |
|||
display: flex; |
|||
.li{ |
|||
flex: 1 0 auto; |
|||
margin-left: 36px; |
|||
font-size: 30px; |
|||
color: #999999; |
|||
position: relative; |
|||
padding-bottom: 18px; |
|||
&:first-child{ |
|||
margin-left: 0; |
|||
} |
|||
&.on{ |
|||
&:after{ |
|||
content: ''; |
|||
width: 100%; |
|||
height: 4px; |
|||
background: #C5AA7B; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: 0; |
|||
} |
|||
font-weight:bold; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,48 @@ |
|||
import api from '../../config/api' |
|||
import {funMixin} from '../../config/mixin' |
|||
|
|||
export const commonMixin = { |
|||
name: 'headerComponent', |
|||
mixins: [funMixin], |
|||
props: { |
|||
terminal: { |
|||
type: Number, |
|||
default: 4 |
|||
}, |
|||
typeId: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
shopId: { |
|||
type: Number, |
|||
default: 0 |
|||
}, |
|||
componentContent: { |
|||
type: Object |
|||
} |
|||
}, |
|||
data () { |
|||
return { |
|||
classifyData: [] |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
getData() { |
|||
this.beforeGetData() |
|||
const _ = this |
|||
_.sendReq({ |
|||
url: `${api.getClassify}?page=1&pageSize=20`, |
|||
method: 'GET' |
|||
}, (res) => { |
|||
_.afterGetData() |
|||
_.classifyData = res.data |
|||
console.log(_.classifyData) |
|||
},(err)=>{ |
|||
_.afterGetData() |
|||
}) |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,108 @@ |
|||
<template> |
|||
<div class="header"> |
|||
<nav class="nav"> |
|||
<ul> |
|||
<li class="on"> |
|||
<router-link to="/"> |
|||
首页 |
|||
</router-link> |
|||
</li> |
|||
<li v-for="(item,index) in classifyData.slice(0, 6)" :key="index" @click="jumpCategory(item)"> |
|||
{{item.categoryName}} |
|||
</li> |
|||
</ul> |
|||
</nav> |
|||
<div class="search"> |
|||
<div class="searchSelect"> |
|||
<el-dropdown trigger="click"> |
|||
<span class="el-dropdown-link">宝贝 |
|||
<i class="el-icon-arrow-down cur-poi el-icon--right"></i> |
|||
</span> |
|||
<el-dropdown-menu slot="dropdown"> |
|||
<el-dropdown-item command="宝贝">宝贝</el-dropdown-item> |
|||
<el-dropdown-item command="店铺">店铺</el-dropdown-item> |
|||
</el-dropdown-menu> |
|||
</el-dropdown> |
|||
</div> |
|||
<div class="searchRight"> |
|||
<input type="text" maxlength="20" placeholder="请输入搜索商品"> |
|||
</div> |
|||
<span class="btn cur-poi"> |
|||
<i class="icon el-icon-search"></i> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {commonMixin} from '../mixin' |
|||
export default { |
|||
mixins: [commonMixin], |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.header{ |
|||
height: 80px; |
|||
width: 1200px; |
|||
margin: 0 auto; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
flex-wrap: nowrap; |
|||
.nav{ |
|||
float: left; |
|||
padding-top: 30px; |
|||
ul{ |
|||
width: 760px; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
} |
|||
li{ |
|||
font-size: 16px; |
|||
line-height: 21px; |
|||
padding-bottom: 24px; |
|||
color: #333; |
|||
cursor: pointer; |
|||
border-bottom: 3px solid #fff; |
|||
&.on,&:hover{ |
|||
color: #C5AA7B; |
|||
border-color: #C5AA7B; |
|||
} |
|||
} |
|||
} |
|||
.search{ |
|||
width: 394px; |
|||
height: 39px; |
|||
border: 2px solid #F3F4F5; |
|||
float: right; |
|||
// margin-top: 21px; |
|||
display: flex; |
|||
.searchSelect{ |
|||
width: 82px; |
|||
height: 30px; |
|||
margin-top: 2px; |
|||
border-right: 1px solid #CCCCCC; |
|||
text-align: center; |
|||
line-height: 30px; |
|||
.el-dropdown{ |
|||
color: #C5AA7B; |
|||
} |
|||
} |
|||
.searchRight{ |
|||
flex: 1; |
|||
input{ |
|||
padding-left: 15px; |
|||
font-size: 14px; |
|||
color: #333; |
|||
line-height: 35px; |
|||
} |
|||
} |
|||
.btn{ |
|||
font-size: 20px; |
|||
line-height: 35px; |
|||
padding-right: 15px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,180 @@ |
|||
<template> |
|||
<div class="textTool"> |
|||
<h3 class="toolTit">头部设置</h3> |
|||
<div class="operationBox"> |
|||
<div class="itemBox"> |
|||
<div class="Tit">LOGO类型</div> |
|||
<el-radio-group v-model="activeComponent.componentContent.logoType"> |
|||
<el-radio :label="1">图片</el-radio> |
|||
<el-radio :label="2">文本</el-radio> |
|||
</el-radio-group> |
|||
</div> |
|||
<div v-if="activeComponent.componentContent.logoType === 1"> |
|||
<tool-single-img :imageUrl.sync='activeComponent.componentContent.imageUrl' tip='建议尺寸: 高度100px, 宽度自适应'></tool-single-img> |
|||
</div> |
|||
<div v-else> |
|||
<div class="itemBox"> |
|||
<div class="Tit">LOGO文本</div> |
|||
<el-input class="item-input" v-model="activeComponent.componentContent.title" maxlength="20" placeholder="请输入内容"></el-input> |
|||
</div> |
|||
<div class="itemBox"> |
|||
<div class="Tit">文本大小</div> |
|||
<div class="modifyBox fontSize"> |
|||
<font-size-select :fontSize.sync='activeComponent.componentContent.fontSizeNum'></font-size-select> |
|||
</div> |
|||
</div> |
|||
<div class="itemBox"> |
|||
<div class="Tit">文本粗细</div> |
|||
<div class="Info" v-text="activeComponent.componentContent.textFontW === 'bold' ? '加粗体' : '常规体'"></div> |
|||
<div class="modifyBox fontSize"> |
|||
<span class="iconfont" :class="{textActive: activeComponent.componentContent.textFontW === 'bold'}" @click="changeFontW(type = 'bold')"></span> |
|||
<span class="iconfont" :class="{textActive: activeComponent.componentContent.textFontW === 'normal'}" @click="changeFontW(type = 'normal')"></span> |
|||
</div> |
|||
</div> |
|||
<div class="itemBox"> |
|||
<div class="Tit">文本颜色</div> |
|||
<div class="Info">{{activeComponent.componentContent.titColor}}</div> |
|||
<div class="modifyBox"> |
|||
<div class="colorBox"> |
|||
<span @click="resetColor">重置</span> |
|||
<div class="block"> |
|||
<el-color-picker v-model="activeComponent.componentContent.titColor"></el-color-picker> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {toolMixin} from '@@/config/mixin' |
|||
import FontSizeSelect from '../toolModule/font-size-select' |
|||
import ToolSingleImg from "../toolModule/tool-single-img"; |
|||
export default { |
|||
name: 'textTool', |
|||
components: {ToolSingleImg, FontSizeSelect }, |
|||
mixins: [toolMixin], |
|||
data () { |
|||
return { |
|||
} |
|||
}, |
|||
computed: { |
|||
|
|||
}, |
|||
methods: { |
|||
// 修改文本字体粗细 |
|||
changeFontW (type) { |
|||
this.activeComponent.componentContent.textFontW = type |
|||
}, |
|||
// 重置文本颜色 |
|||
resetColor () { |
|||
this.activeComponent.componentContent.titColor = '#333333' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.textTool { |
|||
padding: 20px 20px 0 20px; |
|||
h3 { |
|||
font-size: 18px; |
|||
font-weight: 500; |
|||
height: 35px; |
|||
line-height: 35px; |
|||
color: #333333; |
|||
margin-bottom: 20px; |
|||
} |
|||
.operationBox { |
|||
margin-top: 30px; |
|||
.itemBox { |
|||
font-size: 14px; |
|||
display: flex; |
|||
margin-bottom: 20px; |
|||
align-items: center; |
|||
.Tit { |
|||
color: #888888; |
|||
margin-right: 10px; |
|||
width: 70px; |
|||
} |
|||
.item-input{ |
|||
flex: 1; |
|||
} |
|||
.Info { |
|||
color: #222222; |
|||
} |
|||
.modifyBox { |
|||
text-align: right; |
|||
margin-left: auto; |
|||
span { |
|||
height: 26px; |
|||
line-height: 26px; |
|||
float: left; |
|||
display: block; |
|||
text-align: center; |
|||
cursor: pointer; |
|||
width: 30px; |
|||
border: 1px solid #E8EAEC; |
|||
} |
|||
/*span:last-child {*/ |
|||
/* border-right: 1px solid #E8EAEC;*/ |
|||
/*}*/ |
|||
.textActive { |
|||
border: 1px solid $mainColor; |
|||
color: $mainColor; |
|||
} |
|||
.colorBox { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
span { |
|||
margin-right: 10px; |
|||
cursor: pointer; |
|||
border: none; |
|||
color: $mainColor; |
|||
} |
|||
} |
|||
} |
|||
.fontSize { |
|||
span:nth-child(1) { |
|||
font-size: 16px; |
|||
} |
|||
span:nth-child(2) { |
|||
font-size: 14px; |
|||
} |
|||
span:nth-child(3) { |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
} |
|||
.moreBox{ |
|||
border: 1px solid #E8EAEC; |
|||
border-radius: 4px; |
|||
padding:20px 10px; |
|||
.radio{ |
|||
margin-bottom: 20px; |
|||
} |
|||
.el-radio{ |
|||
margin-right: 10px; |
|||
} |
|||
.link{ |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
} |
|||
} |
|||
.block { |
|||
height: 30px; |
|||
} |
|||
::v-deep .el-color-picker__trigger { |
|||
width: 45px; |
|||
height: 26px; |
|||
} |
|||
::v-deep .el-icon-arrow-down:before { |
|||
display: none; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,113 @@ |
|||
<template> |
|||
<div class="product-select"> |
|||
<el-form :inline="true" :model="formData" class="demo-form-inline"> |
|||
<el-form-item label=""> |
|||
<el-input v-model="formData.keyword" maxlength="20" placeholder="店铺名称"></el-input> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="onSubmit">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
<el-table |
|||
:data="tableData" |
|||
max-height="500" |
|||
border |
|||
style="width: 100%"> |
|||
<el-table-column label="" width="35" align="center"> |
|||
<template slot-scope="scope"> |
|||
<el-radio v-model="tableRadio" :label="scope.row"><i></i></el-radio> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="noticeTitle" label="标题" /> |
|||
<el-table-column label="内容"> |
|||
<template slot-scope="scope"> |
|||
<span v-html="scope.row.noticeContent" /> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="createTime" label="发送时间" /> |
|||
</el-table> |
|||
<el-pagination |
|||
@size-change="handleSizeChange" |
|||
@current-change="handleCurrentChange" |
|||
:current-page="currentPage" |
|||
:page-sizes="[10, 20, 50, 100]" |
|||
:page-size="pageSize" |
|||
layout="total, sizes, prev, pager, next, jumper" |
|||
:total="total"> |
|||
</el-pagination> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import api from '@@/components/canvasShow/config/api' |
|||
import {sendReqMixin} from '@@/components/canvasShow/config/mixin' |
|||
export default { |
|||
name: 'notice-select', |
|||
mixins: [sendReqMixin], |
|||
data () { |
|||
return { |
|||
tableRadio: '', |
|||
currentPage: 1, |
|||
total: 0, |
|||
pageSize: 10, |
|||
formData: { |
|||
keyword: '' |
|||
}, |
|||
tableData: [] |
|||
} |
|||
}, |
|||
mounted () { |
|||
this.getTableData() |
|||
}, |
|||
methods: { |
|||
// 获取公告信息 |
|||
getTableData () { |
|||
var _this = this |
|||
var paramsUrl = `${api.getNoticesAll}?page=${this.currentPage}&pageSize=${this.pageSize}` |
|||
if (this.formData.keyword) { |
|||
paramsUrl += `¬iceTitle=${this.formData.keyword}` |
|||
} |
|||
var data = { |
|||
page: this.currentPage, |
|||
pageSize: this.pageSize, |
|||
noticeType: 2 |
|||
} |
|||
if (this.formData.keyword) { |
|||
data.noticeTitle = this.formData.keyword |
|||
} |
|||
let params = { |
|||
url: paramsUrl, |
|||
method: 'POST', |
|||
data |
|||
} |
|||
this.sendReq(params, (res) => { |
|||
_this.tableData = res.data.list |
|||
_this.total = res.data.total |
|||
}) |
|||
}, |
|||
// 搜索 |
|||
onSubmit () { |
|||
this.getTableData() |
|||
}, |
|||
// 每页条数改变 |
|||
handleSizeChange (val) { |
|||
this.pageSize = val |
|||
this.getTableData() |
|||
}, |
|||
// 当前页改变 |
|||
handleCurrentChange (val) { |
|||
this.currentPage = val |
|||
this.getTableData() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.product-select{ |
|||
.el-pagination{ |
|||
padding: 0px; |
|||
margin-top: 30px; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,57 @@ |
|||
const Mock = require('mockjs') |
|||
const { param2Obj } = require('./utils') |
|||
|
|||
const user = require('./user') |
|||
const table = require('./table') |
|||
|
|||
const mocks = [ |
|||
...user, |
|||
...table |
|||
] |
|||
|
|||
// for front mock
|
|||
// please use it cautiously, it will redefine XMLHttpRequest,
|
|||
// which will cause many of your third-party libraries to be invalidated(like progress event).
|
|||
function mockXHR() { |
|||
// mock patch
|
|||
// https://github.com/nuysoft/Mock/issues/300
|
|||
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send |
|||
Mock.XHR.prototype.send = function() { |
|||
if (this.custom.xhr) { |
|||
this.custom.xhr.withCredentials = this.withCredentials || false |
|||
|
|||
if (this.responseType) { |
|||
this.custom.xhr.responseType = this.responseType |
|||
} |
|||
} |
|||
this.proxy_send(...arguments) |
|||
} |
|||
|
|||
function XHR2ExpressReqWrap(respond) { |
|||
return function(options) { |
|||
let result = null |
|||
if (respond instanceof Function) { |
|||
const { body, type, url } = options |
|||
// https://expressjs.com/en/4x/api.html#req
|
|||
result = respond({ |
|||
method: type, |
|||
body: JSON.parse(body), |
|||
query: param2Obj(url) |
|||
}) |
|||
} else { |
|||
result = respond |
|||
} |
|||
return Mock.mock(result) |
|||
} |
|||
} |
|||
|
|||
for (const i of mocks) { |
|||
Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response)) |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
mocks, |
|||
mockXHR |
|||
} |
|||
|
@ -0,0 +1,81 @@ |
|||
const chokidar = require('chokidar') |
|||
const bodyParser = require('body-parser') |
|||
const chalk = require('chalk') |
|||
const path = require('path') |
|||
const Mock = require('mockjs') |
|||
|
|||
const mockDir = path.join(process.cwd(), 'mock') |
|||
|
|||
function registerRoutes(app) { |
|||
let mockLastIndex |
|||
const { mocks } = require('./index.js') |
|||
const mocksForServer = mocks.map(route => { |
|||
return responseFake(route.url, route.type, route.response) |
|||
}) |
|||
for (const mock of mocksForServer) { |
|||
app[mock.type](mock.url, mock.response) |
|||
mockLastIndex = app._router.stack.length |
|||
} |
|||
const mockRoutesLength = Object.keys(mocksForServer).length |
|||
return { |
|||
mockRoutesLength: mockRoutesLength, |
|||
mockStartIndex: mockLastIndex - mockRoutesLength |
|||
} |
|||
} |
|||
|
|||
function unregisterRoutes() { |
|||
Object.keys(require.cache).forEach(i => { |
|||
if (i.includes(mockDir)) { |
|||
delete require.cache[require.resolve(i)] |
|||
} |
|||
}) |
|||
} |
|||
|
|||
// for mock server
|
|||
const responseFake = (url, type, respond) => { |
|||
return { |
|||
url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`), |
|||
type: type || 'get', |
|||
response(req, res) { |
|||
console.log('request invoke:' + req.path) |
|||
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = app => { |
|||
// parse app.body
|
|||
// https://expressjs.com/en/4x/api.html#req.body
|
|||
app.use(bodyParser.json()) |
|||
app.use(bodyParser.urlencoded({ |
|||
extended: true |
|||
})) |
|||
|
|||
const mockRoutes = registerRoutes(app) |
|||
var mockRoutesLength = mockRoutes.mockRoutesLength |
|||
var mockStartIndex = mockRoutes.mockStartIndex |
|||
|
|||
// watch files, hot reload mock server
|
|||
chokidar.watch(mockDir, { |
|||
ignored: /mock-server/, |
|||
ignoreInitial: true |
|||
}).on('all', (event, path) => { |
|||
if (event === 'change' || event === 'add') { |
|||
try { |
|||
// remove mock routes stack
|
|||
app._router.stack.splice(mockStartIndex, mockRoutesLength) |
|||
|
|||
// clear routes cache
|
|||
unregisterRoutes() |
|||
|
|||
const mockRoutes = registerRoutes(app) |
|||
mockRoutesLength = mockRoutes.mockRoutesLength |
|||
mockStartIndex = mockRoutes.mockStartIndex |
|||
|
|||
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`)) |
|||
} catch (error) { |
|||
console.log(chalk.redBright(error)) |
|||
} |
|||
} |
|||
}) |
|||
} |
@ -0,0 +1,29 @@ |
|||
const Mock = require('mockjs') |
|||
|
|||
const data = Mock.mock({ |
|||
'items|30': [{ |
|||
id: '@id', |
|||
title: '@sentence(10, 20)', |
|||
'status|1': ['published', 'draft', 'deleted'], |
|||
author: 'name', |
|||
display_time: '@datetime', |
|||
pageviews: '@integer(300, 5000)' |
|||
}] |
|||
}) |
|||
|
|||
module.exports = [ |
|||
{ |
|||
url: '/vue-admin-template/table/list', |
|||
type: 'get', |
|||
response: config => { |
|||
const items = data.items |
|||
return { |
|||
code: 20000, |
|||
data: { |
|||
total: items.length, |
|||
items: items |
|||
} |
|||
} |
|||
} |
|||
} |
|||
] |
@ -0,0 +1,84 @@ |
|||
|
|||
const tokens = { |
|||
admin: { |
|||
token: 'admin-token' |
|||
}, |
|||
editor: { |
|||
token: 'editor-token' |
|||
} |
|||
} |
|||
|
|||
const users = { |
|||
'admin-token': { |
|||
roles: ['admin'], |
|||
introduction: 'I am a super administrator', |
|||
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', |
|||
name: 'Super Admin' |
|||
}, |
|||
'editor-token': { |
|||
roles: ['editor'], |
|||
introduction: 'I am an editor', |
|||
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', |
|||
name: 'Normal Editor' |
|||
} |
|||
} |
|||
|
|||
module.exports = [ |
|||
// user login
|
|||
{ |
|||
url: '/vue-admin-template/user/login', |
|||
type: 'post', |
|||
response: config => { |
|||
const { username } = config.body |
|||
const token = tokens[username] |
|||
|
|||
// mock error
|
|||
if (!token) { |
|||
return { |
|||
code: 60204, |
|||
message: 'Account and password are incorrect.' |
|||
} |
|||
} |
|||
|
|||
return { |
|||
code: 20000, |
|||
data: token |
|||
} |
|||
} |
|||
}, |
|||
|
|||
// get user info
|
|||
{ |
|||
url: '/vue-admin-template/user/info\.*', |
|||
type: 'get', |
|||
response: config => { |
|||
const { token } = config.query |
|||
const info = users[token] |
|||
|
|||
// mock error
|
|||
if (!info) { |
|||
return { |
|||
code: 50008, |
|||
message: 'Login failed, unable to get user details.' |
|||
} |
|||
} |
|||
|
|||
return { |
|||
code: 20000, |
|||
data: info |
|||
} |
|||
} |
|||
}, |
|||
|
|||
// user logout
|
|||
{ |
|||
url: '/vue-admin-template/user/logout', |
|||
type: 'post', |
|||
response: _ => { |
|||
return { |
|||
code: 20000, |
|||
data: 'success' |
|||
} |
|||
} |
|||
} |
|||
] |
@ -0,0 +1,25 @@ |
|||
/** |
|||
* @param {string} url |
|||
* @returns {Object} |
|||
*/ |
|||
function param2Obj(url) { |
|||
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') |
|||
if (!search) { |
|||
return {} |
|||
} |
|||
const obj = {} |
|||
const searchArr = search.split('&') |
|||
searchArr.forEach(v => { |
|||
const index = v.indexOf('=') |
|||
if (index !== -1) { |
|||
const name = v.substring(0, index) |
|||
const val = v.substring(index + 1, v.length) |
|||
obj[name] = val |
|||
} |
|||
}) |
|||
return obj |
|||
} |
|||
|
|||
module.exports = { |
|||
param2Obj |
|||
} |
@ -0,0 +1,182 @@ |
|||
{ |
|||
"main": { |
|||
"message": "message", |
|||
"display": "display", |
|||
"todaydata": "Today's Data", |
|||
"yonghufangwenqushi": "User Access Trends", |
|||
"fangwenyonghushu": "Users Reach", |
|||
"zhuanhualv": "Conversion rate", |
|||
"dingdanzhuanhuanloudou": "Order conversion funnel", |
|||
"remaishangpin": "Best Sellers" |
|||
}, |
|||
"navbar": { |
|||
"changePwd": "change password", |
|||
"changeAvatar": "change avatar", |
|||
"logout": "Logout", |
|||
"chinese": "中文", |
|||
"english": "English", |
|||
"businessMode": "Merchant platform", |
|||
"password": "password", |
|||
"newPassword": "newPassword", |
|||
"confirmPassword": "onfirmPassword" |
|||
}, |
|||
"common": { |
|||
"sure": "OK", |
|||
"cancle": "Cancle", |
|||
"export": "Export", |
|||
"view": "View", |
|||
"seemore": "See More", |
|||
"seeall": "See All", |
|||
"save": "Save", |
|||
"submit": "Submit", |
|||
"edit": "Edit", |
|||
"delete": "Delete", |
|||
"choose": "Please choose" |
|||
}, |
|||
"permission": { |
|||
"概括": "Overview", |
|||
"分销商": "Distributor", |
|||
"系统管理": "System Management", |
|||
"字典管理": "Dict Management", |
|||
"角色管理": "Role Management", |
|||
"菜单管理": "Menu Management", |
|||
"用户管理": "User Management", |
|||
"新增": "Add", |
|||
"修改": "Edit", |
|||
"删除": "Delete", |
|||
"新增父级菜单": "Add Parent Menu", |
|||
"新增子级菜单": "Add Child Menu", |
|||
"新增子级按钮": "Add Child Btn", |
|||
"客户管理": "Custom Management", |
|||
"标签管理": "Tag Management", |
|||
"评论": "Comment", |
|||
"评论管理": "Comment Management", |
|||
"敏感词管理": "Sensitive word management", |
|||
"评论列表": "Comment List", |
|||
"添加": "Add", |
|||
"售后处理": "After Sales", |
|||
"平台活动": "Platform activities", |
|||
"商品管理": "Product Management", |
|||
"商品类别": "Product category", |
|||
"商家管理": "Business Management", |
|||
"商家列表": "Business List", |
|||
"入驻申请": "Settled Request", |
|||
"导出标签": "Export", |
|||
"关键词管理": "Keyword Management", |
|||
"订单": "Order", |
|||
"待处理订单": "Pending orders", |
|||
"售后订单": "After sales orders", |
|||
"商品": "Product", |
|||
"商品分组": "Product Group", |
|||
"店铺": "Shop", |
|||
"素材管理": "Material Management", |
|||
"设置": "Setting", |
|||
"商家设置": "Business Setting", |
|||
"物流设置": "Logistics Settings", |
|||
"财务": "Finance", |
|||
"财务明细": "Finance Detail", |
|||
"收款账户": "Finance Account", |
|||
"分销员": "Distributors", |
|||
"保证金": "Margin", |
|||
"财务管理": "Finance Management", |
|||
"提现申请": "Withdrawal Apply", |
|||
"财务概况": "Financial Overview", |
|||
"用户提现": "User withdrawal", |
|||
"批量导入": "Import", |
|||
"新增商品": "Add", |
|||
"新增分组": "Add", |
|||
"新增标签": "Add", |
|||
"上传": "Upload", |
|||
"新建方案": "Add", |
|||
"商家菜单": "Business Menu", |
|||
"终端装修": "Terminal decoration", |
|||
"消息中心": "Msg Center", |
|||
"历史消息": "Msg History", |
|||
"消息推送": "Message push", |
|||
"营销活动": "Marketing activities", |
|||
"优惠券管理": "Coupon Management", |
|||
"拼团": "Piecing together a group", |
|||
"秒杀": "Flash killing", |
|||
"限时折扣": "Limited time discount", |
|||
"客户列表": "Customer List", |
|||
"标签列表": "Tag List", |
|||
"客户分群": "Customer segmentation", |
|||
"运营计划": "Operational planning", |
|||
"优惠券活动": "Coupon activity", |
|||
"秒杀活动": "Flash sale activity", |
|||
"支付有礼": "Pay with courtesy", |
|||
"会员管理": "Member Management", |
|||
"会员列表": "Member List", |
|||
"会员标签": "Member Tag", |
|||
"导出": "Export", |
|||
"会员权益": "Member Benefits", |
|||
"会员等级": "Member Level", |
|||
"订单管理": "Order Management", |
|||
"订单列表": "Order List", |
|||
"场景营销": "Scenario marketing", |
|||
"组合捆绑": "Combination bundling", |
|||
"定价捆绑": "Pricing Bundle", |
|||
"商品列表": "Product List", |
|||
"汽车管理": "Car Management", |
|||
"汽车类别": "Car Category", |
|||
"类别参数": "Category Management", |
|||
"房产管理": "Property Management", |
|||
"房产类型": "Property Type", |
|||
"沙石管理": "Stone Management", |
|||
"沙石类型": "Stone Type", |
|||
"类别分类": "Category classification", |
|||
"再生管理": "Regeneration management", |
|||
"再生类型": "Regeneration type", |
|||
"税务管理": "Tax management", |
|||
"税务类型": "Tax type", |
|||
"直播管理": "Live management", |
|||
"广告管理": "Advertisement Management", |
|||
"直播列表": "Live List", |
|||
"直播商品": "Live Product", |
|||
"广告列表": "Advertising List", |
|||
"风控管理": "Risk control management", |
|||
"IP黑名单": "IP BlackList", |
|||
"用户黑名单": "User BlackList", |
|||
"风控规则": "Risk control rules", |
|||
"客服配置": "Customer configuration", |
|||
"客服管理": "Customer management", |
|||
"测试秒杀活动": "Flash killing activity test", |
|||
"测试限时折扣": "Limited time discount test", |
|||
"测试支付有礼": "Payment courtesy test", |
|||
"测试优惠卷": "Coupon test", |
|||
"积分管理": "Points Management", |
|||
"积分配置": "Integral configuration", |
|||
"积分记录": "Points Record", |
|||
"签到配置": "Sign-in configuration", |
|||
"微信客服": "WeChat customer", |
|||
"直播间管理": "Live room management", |
|||
"直播间商品管理": "Live Room Product Management", |
|||
"微信客服管理": "WeChat customer management", |
|||
"渠道优惠券管理": "Channel coupon management", |
|||
"测试": "Test", |
|||
"手机管理": "Mobile management", |
|||
"二次认证": "Secondary certification", |
|||
"二次认证管理": "Secondary certification management", |
|||
"手机号管理": "Mobile number management", |
|||
"渠道管理": "Channel management", |
|||
"渠道列表": "Channel List", |
|||
"渠道券管理": "Channel voucher management", |
|||
"渠道券活动": "Channel voucher activity", |
|||
"品牌管理": "Branding", |
|||
"手机号码": "Phone Number", |
|||
"渠道优惠券": "Channel Coupon", |
|||
"仓库管理": "Storehouse management", |
|||
"跨境设置": "Cross border settings", |
|||
"分账比例设置": "Allocation ratio setting", |
|||
"库存管理": "Inventory management", |
|||
"库存明细": "Inventory Details", |
|||
"店铺列表": "Shop List", |
|||
"我的店铺": "My Shop", |
|||
"商家商品分类": "Business Product ", |
|||
"商家装修": "BUsiness Build" |
|||
}, |
|||
"commom": { |
|||
"nodata": "No Data" |
|||
}, |
|||
"notice_dialog_title": "Tips" |
|||
} |
@ -0,0 +1,184 @@ |
|||
{ |
|||
"main": { |
|||
"message": "消息", |
|||
"display": "展示", |
|||
"todaydata": "今日数据", |
|||
"yonghufangwenqushi": "用户访问趋势", |
|||
"renci": "人次", |
|||
"fangwenyonghushu": "访问用户数", |
|||
"zhuanhualv": "总转化率", |
|||
"dingdanzhuanhuanloudou": "订单转换漏斗", |
|||
"remaishangpin": "热卖商品" |
|||
}, |
|||
"navbar": { |
|||
"changePwd": "修改密码", |
|||
"changeAvatar": "修改头像", |
|||
"logout": "退出登录", |
|||
"chinese": "中文", |
|||
"english": "英文", |
|||
"businessMode": "商家终端", |
|||
"password": "密码", |
|||
"newPassword": "新密码", |
|||
"confirmPassword": "确认密码" |
|||
}, |
|||
"common": { |
|||
"sure": "确定", |
|||
"cancle": "取消", |
|||
"export": "导出", |
|||
"view": "查看", |
|||
"seemore": "查看更多", |
|||
"seeall": "查看全部", |
|||
"save": "保存", |
|||
"submit": "提交", |
|||
"edit": "编辑", |
|||
"delete": "删除", |
|||
"choose": "请选择" |
|||
}, |
|||
"permission": { |
|||
"概况": "概况", |
|||
"概括": "概括", |
|||
"分销商": "分销商", |
|||
"系统管理": "系统管理", |
|||
"字典管理": "字典管理", |
|||
"角色管理": "角色管理", |
|||
"菜单管理": "菜单管理", |
|||
"用户管理": "用户管理", |
|||
"新增": "新增", |
|||
"修改": "修改", |
|||
"删除": "删除", |
|||
"新增父级菜单": "新增父级菜单", |
|||
"新增子级菜单": "新增子级菜单", |
|||
"新增子级按钮": "新增子级按钮", |
|||
"客户管理": "客户管理", |
|||
"标签管理": "标签管理", |
|||
"评论": "评论", |
|||
"评论管理": "评论管理", |
|||
"敏感词管理": "敏感词管理", |
|||
"评论列表": "评论列表", |
|||
"添加": "添加", |
|||
"售后处理": "售后处理", |
|||
"平台活动": "平台活动", |
|||
"商品管理": "商品管理", |
|||
"商品类别": "商品类别", |
|||
"商家管理": "商家管理", |
|||
"商家列表": "商家列表", |
|||
"入驻申请": "入驻申请", |
|||
"导出标签": "导出标签", |
|||
"关键词管理": "关键词管理", |
|||
"订单": "订单", |
|||
"待处理订单": "待处理订单", |
|||
"售后订单": "售后订单", |
|||
"商品": "商品", |
|||
"商品分组": "商品分组", |
|||
"店铺": "店铺", |
|||
"素材管理": "素材管理", |
|||
"设置": "设置", |
|||
"商家设置": "商家设置", |
|||
"物流设置": "物流设置", |
|||
"财务": "财务", |
|||
"财务明细": "财务明细", |
|||
"收款账户": "收款账户", |
|||
"分销员": "分销员", |
|||
"保证金": "保证金", |
|||
"财务管理": "财务管理", |
|||
"提现申请": "提现申请", |
|||
"财务概况": "财务概况", |
|||
"用户提现": "用户提现", |
|||
"批量导入": "批量导入", |
|||
"新增商品": "新增商品", |
|||
"新增分组": "新增分组", |
|||
"新增标签": "新增标签", |
|||
"上传": "上传", |
|||
"新建方案": "新建方案", |
|||
"商家菜单": "商家菜单", |
|||
"终端装修": "终端装修", |
|||
"消息中心": "消息中心", |
|||
"历史消息": "历史消息", |
|||
"消息推送": "消息推送", |
|||
"营销活动": "营销活动", |
|||
"优惠券管理": "优惠券管理", |
|||
"拼团": "拼团", |
|||
"秒杀": "秒杀", |
|||
"限时折扣": "限时折扣", |
|||
"客户列表": "客户列表", |
|||
"标签列表": "标签列表", |
|||
"客户分群": "客户分群", |
|||
"运营计划": "运营计划", |
|||
"优惠券活动": "优惠券活动", |
|||
"秒杀活动": "秒杀活动", |
|||
"支付有礼": "支付有礼", |
|||
"会员管理": "会员管理", |
|||
"会员列表": "会员列表", |
|||
"会员标签": "会员标签", |
|||
"导出": "导出", |
|||
"会员权益": "会员权益", |
|||
"会员等级": "会员等级", |
|||
"订单管理": "订单管理", |
|||
"订单列表": "订单列表", |
|||
"场景营销": "场景营销", |
|||
"组合捆绑": "组合捆绑", |
|||
"定价捆绑": "定价捆绑", |
|||
"商品列表": "商品列表", |
|||
"汽车管理": "汽车管理", |
|||
"汽车类别": "汽车类别", |
|||
"类别参数": "类别参数", |
|||
"房产管理": "房产管理", |
|||
"房产类型": "房产类型", |
|||
"沙石管理": "沙石管理", |
|||
"沙石类型": "沙石类型", |
|||
"类别分类": "类别分类", |
|||
"再生管理": "再生管理", |
|||
"再生类型": "再生类型", |
|||
"税务管理": "税务管理", |
|||
"税务类型": "税务类型", |
|||
"直播管理": "直播管理", |
|||
"广告管理": "广告管理", |
|||
"直播列表": "直播列表", |
|||
"直播商品": "直播商品", |
|||
"广告列表": "广告列表", |
|||
"风控管理": "风控管理", |
|||
"IP黑名单": "IP黑名单", |
|||
"用户黑名单": "用户黑名单", |
|||
"风控规则": "风控规则", |
|||
"客服配置": "客服配置", |
|||
"客服管理": "客服管理", |
|||
"测试秒杀活动": "测试秒杀活动", |
|||
"测试限时折扣": "测试限时折扣", |
|||
"测试支付有礼": "测试支付有礼", |
|||
"测试优惠卷": "测试优惠卷", |
|||
"积分管理": "积分管理", |
|||
"积分配置": "积分配置", |
|||
"积分记录": "积分记录", |
|||
"签到配置": "签到配置", |
|||
"微信客服": "微信客服", |
|||
"直播间管理": "直播间管理", |
|||
"直播间商品管理": "直播间商品管理", |
|||
"微信客服管理": "微信客服管理", |
|||
"渠道优惠券管理": "渠道优惠券管理", |
|||
"测试": "测试", |
|||
"手机管理": "手机管理", |
|||
"二次认证": "二次认证", |
|||
"二次认证管理": "二次认证管理", |
|||
"手机号管理": "手机号管理", |
|||
"渠道管理": "渠道管理", |
|||
"渠道列表": "渠道列表", |
|||
"渠道券管理": "渠道券管理", |
|||
"渠道券活动": "渠道券活动", |
|||
"品牌管理": "品牌管理", |
|||
"手机号码": "手机号码", |
|||
"渠道优惠券": "渠道优惠券", |
|||
"仓库管理": "仓库管理", |
|||
"跨境设置": "跨境设置", |
|||
"分账比例设置": "分账比例设置", |
|||
"库存管理": "库存管理", |
|||
"库存明细": "库存明细", |
|||
"店铺列表": "店铺列表", |
|||
"我的店铺": "我的店铺", |
|||
"商家商品分类": "商家商品分类", |
|||
"商家装修": "商家装修" |
|||
}, |
|||
"commom": { |
|||
"nodata": "暂无数据" |
|||
}, |
|||
"notice_dialog_title": "温馨提示" |
|||
} |
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue