master
271556543@qq.com 3 years ago
parent 65b63027e3
commit df6ea3050d

@ -65,7 +65,7 @@ export function destroyMerchantItems(data){
}) })
} }
export function savePicture(data){ export function storePicture(data){
return request({ return request({
method:'post', method:'post',
url:'/api/admin/confinement-service/store-picture', url:'/api/admin/confinement-service/store-picture',

@ -0,0 +1,121 @@
<script>
import {itemAction,itemPreAction} from '@/api/order'
import { Message } from 'element-ui'
export default {
props:{
row:Object
},
data() {
return {
icons:{
follow:'ios-chatbubbles-outline',
assign:'ios-paper-plane-outline',
recover:'md-redo',
cancel:'ios-close',
confirm_merchant_cancel:'ios-close-circle',
confirm_member_cancel:'md-close-circle'
},
isShow:false,
action:'',
content:'',
}
},
methods: {
view(e){
this.isShow = e
},
actionRender(){
if(!this.row?.admin_actions) return
let keys = Object.keys(this.row.admin_actions)
return keys.map(item => {
return (
<Button
icon={this.icons[item]}
type="primary"
style="margin-left: 10px;margin-bottom: 6px;"
size="small"
ghost
on-click={()=>this.actionPreClick(item)}>
{this.row.admin_actions[item]}
</Button>
)
})
},
contentRender(){
return (
<div>
<div style={{'display':'flex'}}>
<div>产品名称</div>
<div>{this.content.vo?.order?.order_name}</div>
</div>
</div>
)
},
actionPreClick(action){
this.action = action
itemPreAction({
item_id:this.row.id,
action
}).then(res => {
this.content = res
console.log(this.content)
this.isShow = true
})
},
actionClick(){
itemAction({
item_id:this.row.id,
action:this.action
}).then(res => {
console.log(res)
Message({
type:'success',
message:res.msg || '操作成功'
})
this.isShow = false
})
}
},
render(h) {
let {actionRender,contentRender} = this
return (
<div>
{ actionRender() }
<Button
icon="ios-clipboard-outline"
type="primary"
style="margin-left: 10px;margin-bottom: 6px;"
size="small"
ghost
on-click={()=>{
this.$emit('log')
}}>日志</Button>
<xy-dialog
width={40}
title={this.row.admin_actions[this.action] || '操作'}
is-show={this.isShow}
type="normal"
on={{
['update:isShow']: this.view,
['on-ok']:this.actionClick
}}
scopedSlots={{
default:contentRender
}}>
</xy-dialog>
</div>
)
}
}
</script>
<style scoped lang="scss">
</style>

@ -78,11 +78,12 @@
<template v-slot:btns> <template v-slot:btns>
<el-table-column fixed="right" label="操作" width="200" header-align="center"> <el-table-column fixed="right" label="操作" width="200" header-align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<Button icon="ios-chatbubbles-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>跟进</Button> <actions :row="scope.row" @log="showLog(scope.row)"></actions>
<Button v-show="scope.row.state_name == ''" icon="ios-paper-plane-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>分发</Button> <!-- <Button icon="ios-chatbubbles-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>跟进</Button>-->
<Button v-show="scope.row.state_name == ''" icon="ios-close" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>取消</Button> <!-- <Button v-show="scope.row.state_name == ''" icon="ios-paper-plane-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>分发</Button>-->
<Button v-show="scope.row.state_name == ''" icon="ios-redo" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>收回</Button> <!-- <Button v-show="scope.row.state_name == ''" icon="ios-close" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>取消</Button>-->
<Button icon="ios-clipboard-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost @click="selectId = scope.row.id,isShowLog = true">日志</Button> <!-- <Button v-show="scope.row.state_name == ''" icon="ios-redo" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost>收回</Button>-->
<!-- <Button icon="ios-clipboard-outline" type="primary" style="margin-left: 10px;margin-bottom: 6px;" size="small" ghost @click="selectId = scope.row.id,isShowLog = true">日志</Button>-->
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
@ -97,9 +98,11 @@ import {getList,index as getTypes} from "@/api/order"
import {parseTime} from "@/utils" import {parseTime} from "@/utils"
import orderLog from '@/views/order/component/orderLog' import orderLog from '@/views/order/component/orderLog'
import actions from '@/views/order/component/actions'
export default { export default {
components:{ components:{
orderLog orderLog,
actions
}, },
data() { data() {
return { return {
@ -125,7 +128,9 @@ export default {
{ {
prop: "order_name", prop: "order_name",
label:"订单名称", label:"订单名称",
width:220 width:220,
align:'left',
fixed:'left'
}, },
{ {
prop:'bookable_name', prop:'bookable_name',
@ -141,7 +146,7 @@ export default {
{ {
prop:"created_at", prop:"created_at",
label:"下单时间", label:"下单时间",
width: 160, width: 200,
formatter:(cell,data,value,index)=>{ formatter:(cell,data,value,index)=>{
return parseTime(new Date(value)) return parseTime(new Date(value))
} }
@ -149,7 +154,7 @@ export default {
{ {
prop:"paid_at", prop:"paid_at",
label:"支付时间", label:"支付时间",
width: 160, width: 200,
formatter:(cell,data,value,index)=>{ formatter:(cell,data,value,index)=>{
return parseTime(new Date(value)) return parseTime(new Date(value))
} }
@ -157,7 +162,7 @@ export default {
{ {
prop:"updated_at", prop:"updated_at",
label:"更新时间", label:"更新时间",
width: 160, width: 200,
formatter:(cell,data,value,index)=>{ formatter:(cell,data,value,index)=>{
return parseTime(new Date(value),"{y}-{m}-{d}") return parseTime(new Date(value),"{y}-{m}-{d}")
} }
@ -257,6 +262,11 @@ export default {
}) })
this.total = res.total this.total = res.total
this.list = res.rows this.list = res.rows
},
showLog(row){
this.selectId = row.id
this.isShowLog = true
} }
}, },
mounted() { mounted() {

@ -5,11 +5,11 @@
<div slot="content"></div> <div slot="content"></div>
<slot> <slot>
<div> <div>
<Input v-model="select.keywords" style="width: 200px; margin-right: 10px" placeholder="关键字搜索" /> <Input clearable v-model="select.keywords" style="width: 200px; margin-right: 10px" placeholder="关键字搜索" />
<Select placeholder="类型搜索" v-model="select.type" style="width: 140px;margin-right: 10px"> <Select placeholder="类型搜索" v-model="select.type" style="width: 140px;margin-right: 10px">
</Select> </Select>
<Button type="primary"></Button> <Button type="primary" @click="getClubProduct"></Button>
<Button type="primary" style="margin-left: 10px" @click="$refs['addClubProduct'].type = 'add',$refs['addClubProduct'].isShow = true">新增</Button> <Button type="primary" style="margin-left: 10px" @click="$refs['addClubProduct'].type = 'add',$refs['addClubProduct'].isShow = true">新增</Button>
</div> </div>
</slot> </slot>
@ -30,7 +30,7 @@
<Button ghost size="small" type="primary" style="margin: 0 6px 4px 0">删除</Button> <Button ghost size="small" type="primary" style="margin: 0 6px 4px 0">删除</Button>
</Poptip> </Poptip>
<Button ghost size="small" type="primary" style="margin: 0 6px 4px 0;width: 95px" @click="comboClick(scope.row)"></Button> <Button ghost size="small" type="primary" style="margin: 0 6px 4px 0;width: 95px" @click="comboClick(scope.row)"></Button>
<Button ghost size="small" type="primary" style="margin: 0 6px 4px 0;width: 95px">产品图</Button> <Button ghost size="small" type="primary" style="margin: 0 6px 4px 0;width: 95px" @click="picClick(scope.row)"></Button>
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
@ -38,6 +38,7 @@
<addClubProduct ref="addClubProduct" @refresh="getClubProduct"></addClubProduct> <addClubProduct ref="addClubProduct" @refresh="getClubProduct"></addClubProduct>
<addProductCombo ref="addProductCombo"></addProductCombo> <addProductCombo ref="addProductCombo"></addProductCombo>
<addProductPic ref="addProductPic"></addProductPic>
</div> </div>
</template> </template>
@ -48,10 +49,12 @@ import { Message } from 'element-ui'
import addClubProduct from '@/views/productService/components/confinement/addClubProduct' import addClubProduct from '@/views/productService/components/confinement/addClubProduct'
import addProductCombo from '@/views/productService/components/confinement/addProductCombo' import addProductCombo from '@/views/productService/components/confinement/addProductCombo'
import addProductPic from '@/views/productService/components/confinement/addProductPic'
export default { export default {
components:{ components:{
addClubProduct, addClubProduct,
addProductCombo addProductCombo,
addProductPic
}, },
data() { data() {
return { return {
@ -68,12 +71,15 @@ export default {
{ {
prop:'name', prop:'name',
label:'名称', label:'名称',
width: 220 width: 220,
fixed:'left',
align:'left'
}, },
{ {
label:'所属会所', label:'所属会所',
prop:'service.name', prop:'service.name',
width: 220 width: 220,
align:'left'
}, },
{ {
label:'产品信息', label:'产品信息',
@ -89,6 +95,24 @@ export default {
) )
} }
}, },
{
label:'特色标签',
width: 260,
align:'left',
prop:'featured_label',
customFn:(row) => {
return (
<div>
{
row.featured_label ?
row.featured_label?.split(',').map(item => {
return <el-tag type="border" style={{'margin':'0 6px 4px 0'}}>{item}</el-tag>
}) : <div style={{'text-align':'center'}}></div>
}
</div>
)
}
},
{ {
label:'排序', label:'排序',
width: 160, width: 160,
@ -144,6 +168,10 @@ export default {
comboClick(row){ comboClick(row){
this.$refs['addProductCombo'].id = row.id this.$refs['addProductCombo'].id = row.id
this.$refs['addProductCombo'].isShow = true this.$refs['addProductCombo'].isShow = true
},
picClick(row){
this.$refs['addProductPic'].id = row.id
this.$refs['addProductPic'].isShow = true
} }
}, },
mounted() { mounted() {

@ -18,6 +18,7 @@
<script> <script>
import {storeMerchantItems,getMerchantItems,destroyMerchantItems} from '@/api/confinementClub' import {storeMerchantItems,getMerchantItems,destroyMerchantItems} from '@/api/confinementClub'
import { Message } from 'element-ui'
export default { export default {
data() { data() {
return { return {
@ -66,15 +67,21 @@ export default {
}, },
submit(){ submit(){
//console.log(this.list) let promiseAll = []
Promise.all(this.list.map(item => { this.list.forEach(item => {
return storeMerchantItems({ if(!item.id){
confinement_services_id:this.id, promiseAll.push(storeMerchantItems({
name:item.name, confinement_services_id:this.id,
content:item.content name:item.name,
content:item.content
}))
}
})
Promise.all(promiseAll).then(res => {
Message({
type:'success',
message:`新增${res.length}条简介`
}) })
})).then(res => {
console.log(res)
this.isShow = false this.isShow = false
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)

@ -12,14 +12,14 @@
:file-list="fileList" :file-list="fileList"
list-type="picture"> list-type="picture">
<el-button size="small" type="primary">点击上传</el-button> <el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过500kb</div> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过2M</div>
</el-upload> </el-upload>
</xy-dialog> </xy-dialog>
</div> </div>
</template> </template>
<script> <script>
import {getPicture,savePicture,destroyPicture} from '@/api/confinementClub' import {getPicture,storePicture,destroyPicture} from '@/api/confinementClub'
import { Message } from 'element-ui' import { Message } from 'element-ui'
export default { export default {
data() { data() {
@ -53,7 +53,7 @@ export default {
} }
}, },
handleRemove(file, fileList) { handleRemove(file, fileList) {
console.log(file, fileList); //console.log(file, fileList);
}, },
handlePreview(file) { handlePreview(file) {
console.log(file); console.log(file);
@ -63,26 +63,30 @@ export default {
}, },
handleBeforeRemove(file){ handleBeforeRemove(file){
console.log(file) console.log(file)
destroyPicture({id:file.id}).then(res => { if(file.id){
Message({ destroyPicture({id:file.id}).then(res => {
type:'success', Message({
message:'删除图片成功' type:'success',
message:'删除图片成功'
})
}).catch(err => {
this.getPic()
}) })
}).catch(err => { }else{
this.getPic() this.pics.splice(this.pics.indexOf(file.response.id),1)
}) }
}, },
submit(){ submit(){
Promise.all(this.fileList.map(item => { Promise.all(this.pics.map(item => {
savePicture({ return storePicture({
confinement_services_id:this.id, confinement_services_id:this.id,
picture:item.url picture:item
}) })
})).then(res => { })).then(res => {
Message({ Message({
type:'success', type:'success',
message:`${res.length}张图片保存成功` message:`新增${res.length}张图片`
}) })
this.isShow = false this.isShow = false
}).catch(err => { }).catch(err => {

@ -147,7 +147,7 @@
<div class="xy-table-item-label"> <div class="xy-table-item-label">
<span style="color: red;font-weight: 600;padding-right: 4px;">*</span>封面图 <span style="color: red;font-weight: 600;padding-right: 4px;">*</span>封面图
</div> </div>
<div class="xy-table-item-content"> <div class="xy-table-item-content xy-table-item-content-cover">
<div v-if="form.coverPicture" style="position: relative;"> <div v-if="form.coverPicture" style="position: relative;">
<img :src="form.coverPicture" class="avatar"> <img :src="form.coverPicture" class="avatar">
<Button <Button
@ -338,7 +338,7 @@ export default {
sortNumber:res?.sort_number, sortNumber:res?.sort_number,
featuredLabel:res?.featured_label?.split(',') || [],// featuredLabel:res?.featured_label?.split(',') || [],//
roomOrientation:res?.room_orientation,// roomOrientation:res?.room_orientation,//
roomFacility:res?.featured_label?.room_facility,// roomFacility:res?.room_facility?.split(',').map(item=>Number(item)) || [],//
roomArea:res?.room_area, roomArea:res?.room_area,
price:res?.price, price:res?.price,
coverPicture:res?.cover_picture, coverPicture:res?.cover_picture,
@ -464,6 +464,21 @@ export default {
flex: 0; flex: 0;
} }
} }
&-content-cover{
position: relative;
&::after{
font-size: 10px;
white-space: nowrap;
word-break: keep-all;
content: '建议尺寸 800*450';
zoom: 0.84;
position: absolute;
bottom: -34px;
right: 4px;
}
}
&-area{ &-area{
position: relative; position: relative;
&::after{ &::after{

@ -1,13 +1,13 @@
<template> <template>
<div> <div>
<xy-dialog :is-show.sync="isShow" title="产品套餐" ok-text=""> <xy-dialog :is-show.sync="isShow" title="产品套餐" ok-text="" @on-ok="submit">
<Button type="primary" icon="md-add" @click="" style="margin-bottom: 10px">新增</Button> <Button type="primary" icon="md-add" @click="addList" style="margin-bottom: 10px">新增</Button>
<xy-table :height="260" :is-page="false" :list="list" :table-item="table"> <xy-table :height="260" :is-page="false" :list="list" :table-item="table">
<template v-slot:btns> <template v-slot:btns>
<el-table-column label="操作" width="90" header-align="center" align="center"> <el-table-column label="操作" width="90" header-align="center" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<Button size="small" type="primary" ghost @click=""></Button> <Button size="small" type="primary" ghost @click="deleteCombo(scope)"></Button>
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
@ -17,17 +17,98 @@
</template> </template>
<script> <script>
import {getCombo,destroyCombo,storeCombo} from '@/api/clubProduct'
import { Message } from 'element-ui'
export default { export default {
data() { data() {
return { return {
id:'', id:'',
isShow:false, isShow:false,
table:[],
list:[], list:[],
table:[
{
label:'名称',
sortable:false,
minWidth:60,
customFn:(row)=>{
return (
<div>
<el-input size='small' placeholder="请输入名称" value={row.name} on={{['input']:(e)=>{row.name = e}}}/>
</div>
)
}
},
{
label:'内容',
sortable:false,
customFn:(row)=>{
return (
<div>
<el-input size='small' placeholder="请输入内容" value={row.content} on={{['input']:(e)=>{row.content = e}}}/>
</div>
)
}
}
],
}
},
methods: {
async getCombo(){
this.list = []
const res = await getCombo({confinement_products_id:this.id})
this.list.push(...res)
},
addList(){
this.list.push({
name:'',
content:''
})
},
deleteCombo(scope){
if(scope.row?.id){
destroyCombo({id:scope.row.id}).then(res => {
this.getCombo()
})
}else{
this.list.splice(scope.$index,1)
}
},
submit(){
let promiseAll = []
this.list.forEach(item => {
if(!item.id){
promiseAll.push(storeCombo({
confinement_products_id:this.id,
name:item.name,
content:item.content
}))
}
})
Promise.all(promiseAll).then(res => {
Message({
type:'success',
message:`新增${res.length}条套餐`
})
this.isShow = false
}).catch(err => {
console.log(err)
})
} }
}, },
methods: {} watch:{
isShow(newVal){
if(newVal){
this.getCombo()
}else{
this.id = ''
this.list = []
}
}
}
} }
</script> </script>

@ -0,0 +1,116 @@
<template>
<div>
<xy-dialog :is-show.sync="isShow" title="产品图片" ok-text="" @on-ok="submit">
<el-upload
class="upload-demo"
:action="action"
:before-upload="handleBefore"
:on-success="handleSuccess"
:on-preview="handlePreview"
:before-remove="handleBeforeRemove"
:on-remove="handleRemove"
:file-list="fileList"
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过2M</div>
</el-upload>
</xy-dialog>
</div>
</template>
<script>
import {getPicture,storePicture,destroyPicture} from '@/api/clubProduct'
import { Message } from 'element-ui'
export default {
data() {
return {
id:'',
isShow:false,
action:`${process.env.VUE_APP_BASE_API}api/admin/upload-file`,
fileList:[],
pics:[],//
}
},
methods: {
getPic(){
getPicture({confinement_products_id:this.id}).then(res => {
this.fileList = []
this.fileList.push(...res.map(item => {
return {
url:item.picture,name:item.name || item.picture,
id:item.id,
status: 1
}
}))
})
},
handleBefore(file){
console.log(file)
if((file.size/1000) > 2048){
Message({
type:'warning',
message:'上传图片大小超过2M'
})
return false
}
},
handleRemove(file, fileList) {
//console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
handleSuccess(response, file, fileList){
this.pics.push(response.url)
},
handleBeforeRemove(file){
console.log(file)
if(file.id){
destroyPicture({id:file.id}).then(res => {
Message({
type:'success',
message:'删除图片成功'
})
}).catch(err => {
this.getPic()
})
}else{
this.pics.splice(this.pics.indexOf(file.response.id),1)
}
},
submit(){
Promise.all(this.pics.map(item => {
return storePicture({
confinement_products_id:this.id,
picture:item
})
})).then(res => {
Message({
type:'success',
message:`新增${res.length}张图片`
})
this.isShow = false
}).catch(err => {
console.log(err)
})
}
},
watch:{
isShow(newVal){
if(newVal){
this.getPic()
}else{
this.id = ''
this.fileList = []
this.pics = []
}
}
}
}
</script>
<style scoped lang="scss">
</style>

@ -5,11 +5,11 @@
<div slot="content"></div> <div slot="content"></div>
<slot> <slot>
<div> <div>
<Input v-model="select.keywords" style="width: 200px; margin-right: 10px" placeholder="关键字搜索" /> <Input clearable v-model="select.keywords" style="width: 200px; margin-right: 10px" placeholder="关键字搜索" />
<Select placeholder="类型搜索" v-model="select.type" style="width: 140px;margin-right: 10px"> <Select placeholder="类型搜索" v-model="select.type" style="width: 140px;margin-right: 10px">
</Select> </Select>
<Button type="primary"></Button> <Button type="primary" @click="getClubs"></Button>
<Button type="primary" style="margin-left: 10px" @click="$refs['addConfinementClub'].type = 'add',$refs['addConfinementClub'].isShow = true">新增</Button> <Button type="primary" style="margin-left: 10px" @click="$refs['addConfinementClub'].type = 'add',$refs['addConfinementClub'].isShow = true">新增</Button>
</div> </div>
</slot> </slot>
@ -129,7 +129,8 @@ export default {
async getClubs(){ async getClubs(){
const res = await index({ const res = await index({
page:this.select.page, page:this.select.page,
pageSize:this.select.pageSize pageSize:this.select.pageSize,
keyword:this.select.keywords
}) })
console.log(res) console.log(res)
this.list = res.rows this.list = res.rows

Loading…
Cancel
Save