master
271556543@qq.com 3 years ago
parent 6247637ad8
commit 58496a4bc9

@ -2,4 +2,4 @@
ENV = 'development'
# base api
VUE_APP_BASE_API = ''
VUE_APP_BASE_API = 'http://yybtest.ali251.langye.net/'

@ -0,0 +1,49 @@
import request from '@/utils/request'
export function index(params){
return request({
method:'get',
url:'/api/admin/product/index',
params
})
}
export function show(params){
return request({
method:'get',
url:'/api/admin/product/show',
params
})
}
export function store(data){
return request({
method:'post',
url:'/api/admin/product/store',
data
})
}
export function save(data){
return request({
method:'post',
url:'/api/admin/product/save',
data
})
}
export function destroy(data){
return request({
method:'post',
url:'/api/admin/product/destroy',
data
})
}
export function toggleActive(data){
return request({
method:'post',
url:'/api/admin/product/toggleActive',
data
})
}

@ -0,0 +1,111 @@
<template>
<div class="upload-container">
<el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true">
upload
</el-button>
<el-dialog :visible.sync="dialogVisible">
<el-upload
:multiple="true"
:file-list="fileList"
:show-file-list="true"
:on-remove="handleRemove"
:on-success="handleSuccess"
:before-upload="beforeUpload"
class="editor-slide-upload"
action="https://httpbin.org/post"
list-type="picture-card"
>
<el-button size="small" type="primary">
Click upload
</el-button>
</el-upload>
<el-button @click="dialogVisible = false">
Cancel
</el-button>
<el-button type="primary" @click="handleSubmit">
Confirm
</el-button>
</el-dialog>
</div>
</template>
<script>
// import { getToken } from 'api/qiniu'
export default {
name: 'EditorSlideUpload',
props: {
color: {
type: String,
default: '#1890ff'
}
},
data() {
return {
dialogVisible: false,
listObj: {},
fileList: []
}
},
methods: {
checkAllSuccess() {
return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess)
},
handleSubmit() {
const arr = Object.keys(this.listObj).map(v => this.listObj[v])
if (!this.checkAllSuccess()) {
this.$message('Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!')
return
}
this.$emit('successCBK', arr)
this.listObj = {}
this.fileList = []
this.dialogVisible = false
},
handleSuccess(response, file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
this.listObj[objKeyArr[i]].url = response.files.file
this.listObj[objKeyArr[i]].hasSuccess = true
return
}
}
},
handleRemove(file) {
const uid = file.uid
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
delete this.listObj[objKeyArr[i]]
return
}
}
},
beforeUpload(file) {
const _self = this
const _URL = window.URL || window.webkitURL
const fileName = file.uid
this.listObj[fileName] = {}
return new Promise((resolve, reject) => {
const img = new Image()
img.src = _URL.createObjectURL(file)
img.onload = function() {
_self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height }
}
resolve(true)
})
}
}
}
</script>
<style lang="scss" scoped>
.editor-slide-upload {
margin-bottom: 20px;
::v-deep .el-upload--picture-card {
width: 100%;
}
}
</style>

@ -0,0 +1,59 @@
let callbacks = []
function loadedTinymce() {
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144
// check is successfully downloaded script
return window.tinymce
}
const dynamicLoadScript = (src, callback) => {
const existingScript = document.getElementById(src)
const cb = callback || function() {}
if (!existingScript) {
const script = document.createElement('script')
script.src = src // src url for the third-party library being loaded.
script.id = src
document.body.appendChild(script)
callbacks.push(cb)
const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd
onEnd(script)
}
if (existingScript && cb) {
if (loadedTinymce()) {
cb(null, existingScript)
} else {
callbacks.push(cb)
}
}
function stdOnEnd(script) {
script.onload = function() {
// this.onload = null here is necessary
// because even IE9 works not like others
this.onerror = this.onload = null
for (const cb of callbacks) {
cb(null, script)
}
callbacks = null
}
script.onerror = function() {
this.onerror = this.onload = null
cb(new Error('Failed to load ' + src), script)
}
}
function ieOnEnd(script) {
script.onreadystatechange = function() {
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
this.onreadystatechange = null
for (const cb of callbacks) {
cb(null, script) // there is no way to catch loading errors in IE8
}
callbacks = null
}
}
}
export default dynamicLoadScript

@ -0,0 +1,262 @@
<template>
<div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}">
<textarea :id="tinymceId" class="tinymce-textarea" />
<div class="editor-custom-btn-container">
<editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" />
</div>
</div>
</template>
<script>
/**
* docs:
* https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce
*/
import editorImage from './components/EditorImage'
import plugins from './plugins'
import toolbar from './toolbar'
import load from './dynamicLoadScript'
// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
const skinCdDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/skins/lightgray/skin.min.css'
const contentCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/skins/lightgray/content.min.css'
const prismCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/plugins/codesample/css/prism.css'
let skin = document.createElement('link');
skin.setAttribute('rel', 'stylesheet');
skin.setAttribute('href', skinCdDN);
document.body.appendChild(skin);
let content = document.createElement('link')
content.setAttribute('rel', 'stylesheet');
content.setAttribute('href', contentCDN);
document.body.appendChild(content);
let prism = document.createElement('link')
prism.setAttribute('rel', 'stylesheet');
prism.setAttribute('href', prismCDN);
document.body.appendChild(prism);
export default {
name: 'Tinymce',
components: { editorImage },
props: {
id: {
type: String,
default: function() {
return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
}
},
value: {
type: String,
default: ''
},
toolbar: {
type: Array,
required: false,
default() {
return []
}
},
menubar: {
type: String,
default: 'file edit insert view format table'
},
height: {
type: [Number, String],
required: false,
default: 360
},
width: {
type: [Number, String],
required: false,
default: 'auto'
}
},
data() {
return {
hasChange: false,
hasInit: false,
tinymceId: this.id,
fullscreen: false,
languageTypeList: {
'en': 'en',
'zh': 'zh_CN',
'es': 'es_MX',
'ja': 'ja'
}
}
},
computed: {
containerWidth() {
const width = this.width
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
return `${width}px`
}
return width
}
},
watch: {
value(val) {
if (!this.hasChange && this.hasInit) {
this.$nextTick(() =>
window.tinymce.get(this.tinymceId).setContent(val || ''))
}
}
},
mounted() {
this.init()
},
activated() {
if (window.tinymce) {
this.initTinymce()
}
},
deactivated() {
this.destroyTinymce()
},
destroyed() {
this.destroyTinymce()
},
methods: {
init() {
// dynamic load tinymce from cdn
load(tinymceCDN, (err) => {
if (err) {
this.$message.error(err.message)
return
}
this.initTinymce()
})
},
initTinymce() {
const _this = this
window.tinymce.init({
selector: `#${this.tinymceId}`,
language: this.languageTypeList['en'],
height: this.height,
body_class: 'panel-body ',
object_resizing: false,
toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
menubar: this.menubar,
plugins: plugins,
end_container_on_empty_block: true,
powerpaste_word_import: 'clean',
code_dialog_height: 450,
code_dialog_width: 1000,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
default_link_target: '_blank',
link_title: false,
nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value)
}
_this.hasInit = true
editor.on('NodeChange Change KeyUp SetContent', () => {
this.hasChange = true
this.$emit('input', editor.getContent())
})
},
setup(editor) {
editor.on('FullscreenStateChanged', (e) => {
_this.fullscreen = e.state
})
},
// it will try to keep these URLs intact
// https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
// https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
convert_urls: false
//
// images_dataimg_filter(img) {
// setTimeout(() => {
// const $image = $(img);
// $image.removeAttr('width');
// $image.removeAttr('height');
// if ($image[0].height && $image[0].width) {
// $image.attr('data-wscntype', 'image');
// $image.attr('data-wscnh', $image[0].height);
// $image.attr('data-wscnw', $image[0].width);
// $image.addClass('wscnph');
// }
// }, 0);
// return img
// },
// images_upload_handler(blobInfo, success, failure, progress) {
// progress(0);
// const token = _this.$store.getters.token;
// getToken(token).then(response => {
// const url = response.data.qiniu_url;
// const formData = new FormData();
// formData.append('token', response.data.qiniu_token);
// formData.append('key', response.data.qiniu_key);
// formData.append('file', blobInfo.blob(), url);
// upload(formData).then(() => {
// success(url);
// progress(100);
// })
// }).catch(err => {
// failure('')
// console.log(err);
// });
// },
})
},
destroyTinymce() {
const tinymce = window.tinymce.get(this.tinymceId)
if (this.fullscreen) {
tinymce.execCommand('mceFullScreen')
}
if (tinymce) {
tinymce.destroy()
}
},
setContent(value) {
window.tinymce.get(this.tinymceId).setContent(value)
},
getContent() {
window.tinymce.get(this.tinymceId).getContent()
},
imageSuccessCBK(arr) {
arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`))
}
}
}
</script>
<style lang="scss" scoped>
.tinymce-container {
position: relative;
line-height: normal;
}
.tinymce-container {
::v-deep {
.mce-fullscreen {
z-index: 10000;
}
}
}
.tinymce-textarea {
visibility: hidden;
z-index: -1;
}
.editor-custom-btn-container {
position: absolute;
right: 4px;
top: 4px;
/*z-index: 2005;*/
}
.fullscreen .editor-custom-btn-container {
z-index: 10000;
position: fixed;
}
.editor-upload-btn {
display: inline-block;
}
</style>

@ -0,0 +1,7 @@
// Any plugins you want to use has to be imported
// Detail plugins list see https://www.tinymce.com/docs/plugins/
// Custom builds see https://www.tinymce.com/download/custom-builds/
const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
export default plugins

@ -0,0 +1,6 @@
// Here is a list of the toolbar
// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']
export default toolbar

@ -60,7 +60,7 @@ export default {
{
prop:'business_number',
label:'营业执照号码',
width: 180
width: 200
},
{
prop:"address",

File diff suppressed because one or more lines are too long

@ -0,0 +1,547 @@
<template>
<div>
<xy-dialog :width="66" ref="dialog" type="form" :is-show.sync="isShow" :title="type === 'add' ? '新增商品' : '编辑商品'" :form="form" :rules="rules" @submit="submit">
<template v-slot:name>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>名称
</div>
<div class="xy-table-item-content">
<el-input v-model="form.name" placeholder="请输入商品名称" clearable style="width: 300px;"></el-input>
</div>
</div>
</template>
<template v-slot:poster>
<div class="xy-table-item">
<div class="xy-table-item-label">
海报图
</div>
<div class="xy-table-item-content">
<div v-if="form.poster" style="position: relative;">
<img :src="form.poster" class="avatar">
<Button
shape="circle"
icon="md-close"
type="error"
size="small"
class="img__delete"
@click="form.poster = ''"></Button>
</div>
<el-upload
v-else
accept="picture"
:limit="1"
class="avatar-uploader"
list-type="picture-card"
action="/api/admin/upload-file"
:show-file-list="true"
:on-error="uploadFail"
:on-success="uploadSuccess"
:before-upload="uploadBefore">
<i class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
</div>
</template>
<template v-slot:merchantId>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>所属商户
</div>
<div class="xy-table-item-content">
<el-input suffix-icon="el-icon-arrow-down" readonly :value="form.merchantId.label" placeholder="请选择所属商户" clearable style="width: 300px;" @focus="isShowMerchantSelect = true,getMerchants()"></el-input>
</div>
</div>
</template>
<template v-slot:shopIds>
<div class="xy-table-item">
<div class="xy-table-item-label">
限制门店
</div>
<div class="xy-table-item-content">
<el-input v-model="form.shopIds" placeholder="请选择限制门店" clearable style="width: 300px;"></el-input>
</div>
</div>
</template>
<template v-slot:productTypePid>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>所属板块
</div>
<div class="xy-table-item-content">
<el-select clearable placeholder="请选择所属板块" style="width: 300px" v-model="form.productTypePid" @change="typeChange">
<el-option v-for="item in types" :key="item.id" :value="item.id" :label="item.name">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:productTypeId>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>产品类别
</div>
<div class="xy-table-item-content">
<el-select clearable placeholder="请选择产品类别" style="width: 300px" v-model="form.productTypeId">
<el-option v-for="item in products" :key="item.id" :value="item.id" :label="item.name">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:originalPrice>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>原价
</div>
<div class="xy-table-item-content number-input">
<el-input-number :precision="2" :controls="false" :min="0" placeholder="请输入原价" clearable v-model="form.originalPrice" style="width: 300px;"></el-input-number>
</div>
</div>
</template>
<template v-slot:price>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>价格
</div>
<div class="xy-table-item-content number-input">
<el-input-number :precision="2" :controls="false" :min="0" placeholder="请输入价格" clearable v-model="form.price" style="width: 300px;"></el-input-number>
</div>
</div>
</template>
<template v-slot:fee>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>平台佣金
</div>
<div class="xy-table-item-content number-input">
<el-input-number :precision="2" :controls="false" :min="0" placeholder="请输入平台佣金" clearable v-model="form.fee" style="width: 300px;"></el-input-number>
</div>
</div>
</template>
<template v-slot:sharing>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>分享金
</div>
<div class="xy-table-item-content number-input">
<el-input-number :precision="2" :controls="false" :min="0" placeholder="请输入分享金" clearable v-model="form.sharing" style="width: 300px;"></el-input-number>
</div>
</div>
</template>
<template v-slot:maxQuantity>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>总份数
</div>
<div class="xy-table-item-content">
<el-input-number :min="0" placeholder="请输入总份数" clearable v-model="form.maxQuantity" style="width: 200px;"></el-input-number>
</div>
</div>
</template>
<template v-slot:limitQuantity>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>每用户限购
</div>
<div class="xy-table-item-content">
<el-input-number :min="0" placeholder="请输入每用户限购数" clearable v-model="form.limitQuantity" style="width: 200px;"></el-input-number>
</div>
</div>
</template>
<template v-slot:pretendQuantity>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>虚拟购买次数
</div>
<div class="xy-table-item-content">
<el-input-number :min="0" placeholder="请输入虚拟购买次数" clearable v-model="form.pretendQuantity" style="width: 200px;"></el-input-number>
</div>
</div>
</template>
<template v-slot:time>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>上架/下架时间
</div>
<div class="xy-table-item-content">
<el-date-picker
clearable
style="width: 440px;"
v-model="form.time"
type="datetimerange"
:picker-options="pickerOptions"
range-separator="至"
start-placeholder="上架日期"
end-placeholder="下架日期"
align="right"
value-format="yyyy-MM-dd hh:mm:ss">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:sortnumber>
<div class="xy-table-item">
<div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>排序<span style="font-size: 12px;padding-left: 2px;color: rgb(140,140,140)">大到小</span>
</div>
<div class="xy-table-item-content">
<el-input-number v-model="form.sortnumber" :controls="false" style="width: 200px;"></el-input-number>
</div>
</div>
</template>
<template v-slot:content>
<div class="xy-table-item">
<div class="xy-table-item-label">
内容:
</div>
<div class="xy-table-item-content">
<tinymce ref="tinymce" :height="200" v-model="form.content" id='tinymce'></tinymce>
</div>
</div>
</template>
</xy-dialog>
<Modal v-model="isShowMerchantSelect" title="所属商户选择">
<Table
size="small"
highlight-row
ref="currentRowTable"
:columns="merchantTable"
:data="merchants"
@on-current-change="merchantSelect" />
<Page :current="merchantIndex" :total="merchantTotal" simple style="padding-top: 14px;display: flex;justify-content: center;" @on-change="merchantPageChange"/>
</Modal>
</div>
</template>
<script>
import {store,show,save} from '@/api/product'
import {index as typeIndex} from '@/api/type'
import {index as merchantIndex} from '@/api/merchant'
import { Message } from 'element-ui'
import tinymce from "@/components/Tinymce"
export default {
components:{
tinymce
},
data() {
return {
id:'',
isShow:false,
type:'add',
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}]
},
form:{
name:'',
poster:'',
merchantId:'',
shopIds:'',
productTypePid:'',
productTypeId:'',
originalPrice:'',
price:'',
fee:'',
sharing:'',
maxQuantity:'',
limitQuantity:'',
pretendQuantity:0,
time:[],
sortnumber:0,
content:''
},
rules:{
name:[
{required:true,message:'请填写商品名称'}
],
merchantId:[
{required:true,message:'请选择所属商家'}
],
productTypePid:[
{required:true,message:'请选择所属模块'}
],
productTypeId:[
{required:true,message:'请选择产品类别'}
],
originalPrice:[
{required:true,message:'请输入原价'}
],
price:[
{required:true,message:'请输入价格'}
],
fee:[
{required:true,message:'请输入平台佣金'}
],
sharing:[
{required:true,message:'请输入分享金'}
],
maxQuantity:[
{required:true,message:'请输入总分数'}
],
limitQuantity:[
{required:true,message:'请输入用户限购'}
],
time:[
{required:true,message:'请选择上架/下架时间'}
]
},
types:[],//
products:[],//
isShowMerchantSelect:false,
merchants:[],
merchantTable:[
{
title:'简称',
key:'username',
width:130
},
{
title:'全称',
key:'name',
align:'left',
width:220
},
{
title:'状态',
key:'state',
sortable:true
}
],
merchantIndex:1,
merchantTotal:0,
}
},
methods: {
async getDetail(){
const res = await show({id:this.id})
this.typeChange(res?.product_type_pid)
this.form = {
name:res?.name,
poster:res?.poster_url,
merchantId:{
label:res.merchant.name,
value:res.merchant.id
},
shopIds:res?.shop_ids,
productTypePid:res?.product_type_pid,
productTypeId:res?.product_type_id,
originalPrice:res?.original_price,
price:res?.price,
fee:res?.fee,
sharing:res?.sharing,
maxQuantity:res?.max_quantity,
limitQuantity:res?.limit_quantity,
pretendQuantity:res?.pretend_quantity,
time:[res?.start_time,res?.end_time],
sortnumber:res?.sortnumber,
content:res?.content
}
this.$refs['tinymce'].setContent(this.form.content ||' ')
},
//
uploadFail(err){
console.log(err)
},
uploadSuccess(response){
console.log(response)
this.form.poster = response.url
},
uploadBefore(file){
if((file.size/1000) > 2024){
Message({
type:'warning',
message:'上传图片大小超过2M'
})
return false
}
},
async getTypes(){
const res = await typeIndex()
this.types = res
},
typeChange(val){
if(!val){
this.products = []
return
}
let res = this.types.filter(item => {
return item.id === val
})
this.products = res[0].children
},
async getMerchants(){
const res = await merchantIndex({
page_size:10,
page:this.merchantIndex
})
this.merchantTotal = res.total
this.merchants = res.data
},
merchantPageChange(e){
this.merchantIndex = e
this.getMerchants()
},
merchantSelect(row){
this.form.merchantId = {
label:row.username,
value:row.id
}
},
submit(){
if(this.type === 'add'){
store({
name:this.form.name,
poster:this.form.poster,
merchant_id:this.form.merchantId?.value,
shop_ids:this.form.shopIds,
product_type_pid:this.form.productTypePid,
product_type_id:this.form.productTypeId,
original_price:this.form.originalPrice.toString(),
price:this.form.price.toString(),
fee:this.form.fee.toString(),
sharing:this.form.sharing.toString(),
max_quantity:this.form.maxQuantity.toString(),
limit_quantity:this.form.limitQuantity.toString(),
pretend_quantity:this.form.pretendQuantity.toString(),
start_time:this.form.time[0],
sortnumber:this.form.sortnumber,
end_time:this.form.time[1],
content:this.form.content
}).then(res => {
Message({
type:'success',
message:'新增成功'
})
this.isShow = false
this.$emit('refresh')
})
return
}
if(this.type === 'editor'){
save({
id:this.id,
name:this.form.name,
poster:this.form.poster,
merchant_id:this.form.merchantId?.value,
shop_ids:this.form.shopIds,
product_type_pid:this.form.productTypePid,
product_type_id:this.form.productTypeId,
original_price:this.form.originalPrice.toString(),
price:this.form.price.toString(),
fee:this.form.fee.toString(),
sharing:this.form.sharing.toString(),
max_quantity:this.form.maxQuantity.toString(),
limit_quantity:this.form.limitQuantity.toString(),
pretend_quantity:this.form.pretendQuantity.toString(),
start_time:this.form.time[0],
sortnumber:this.form.sortnumber,
end_time:this.form.time[1],
content:this.form.content
}).then(res => {
Message({
type:'success',
message:'编辑商品成功'
})
this.isShow = false
this.$emit('refresh')
})
}
}
},
watch:{
isShow(newVal){
if(newVal){
this.getTypes()
if(this.type === 'editor'){
this.getDetail()
}
}else{
this.$refs['tinymce'].setContent(' ')
this.$refs['dialog'].reset()
this.id = ''
this.type = ''
}
}
}
}
</script>
<style scoped lang="scss">
.xy-table-item-label{
width: 164px;
}
.number-input{
::v-deep .el-input-number .el-input__inner{
text-align: left !important;
}
}
</style>
<style>
.avatar-uploader .el-upload {
width: 110px;
height: 110px;
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
}
.avatar-uploader .el-upload:hover {
border-color: #BF617C;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 110px;
height: 110px;
line-height: 110px;
text-align: center;
}
.avatar {
width: 110px;
display: block;
border-radius: 6px;
}
.img__delete{
transform: scale(0.8,0.8);
position: absolute;
top: 1px;
right: 12px;
}
</style>

File diff suppressed because one or more lines are too long

@ -7,13 +7,13 @@
<div>
<Input style="width: 200px; margin-right: 10px" placeholder="关键字搜索" />
<Button type="primary">查询</Button>
<Button type="primary" style="margin-left: 10px" >新增分类</Button>
<Button type="primary" style="margin-left: 10px" >新增会员</Button>
</div>
</slot>
</lx-header>
</div>
<xy-table></xy-table>
<xy-table :list="list" :table-item="table"></xy-table>
<div style="display: flex;justify-content: flex-end;">
<Page :total="total" show-elevator @on-change="pageChange"/>
@ -23,6 +23,7 @@
<script>
import {index} from '@/api/member'
import {parseTime} from "@/utils"
export default {
data() {
return {
@ -43,7 +44,7 @@ export default {
{
prop:'phone',
label:'电话',
width:220
width:200
},
{
prop:'due_date',
@ -68,10 +69,19 @@ export default {
},
{
prop:'promotion',
label:'推广人员'
label:'推广人员',
width:140,
customFn:(row)=>{
return (<Tag color={row.promotion == 1 ? 'success' : 'error'}>{row.promotion == 1 ? '是' : '否'}</Tag>)
}
},
{
prop:'created_at',
label:'注册日期',
width:200,
formatter:(cell,data,value)=>{
return parseTime(new Date(value),'{y}-{m}-{d}')
}
}
]
}

Loading…
Cancel
Save