1、提货点
2、客服(腾讯云智服)
3、接口权限控制
4、复制第三方商品可配置
4、优化附件上传配置
5、手机端核销订单
6、手机端订单统计、订单管理
7、短信优化
8、订阅消息全自动化
This commit is contained in:
张乐
2020-09-15 16:13:25 +08:00
parent aee9c1d692
commit db2c3b44a6
245 changed files with 19900 additions and 994 deletions

View File

@@ -0,0 +1,272 @@
<template>
<div class="divBox">
<el-card class="box-card">
<div slot="header" class="clearfix">
<div class="container">
<el-form size="small" :inline="true" label-width="55px" label-position="left">
<el-form-item label="状态:">
<el-select v-model="tableFrom.status" placeholder="请选择状态" clearable class="selWidth">
<el-option :label="item.label" :value="item.value" v-for="(item, index) in switchData" :key="index"></el-option>
</el-select>
</el-form-item>
<el-form-item label="名称:">
<el-input v-model="tableFrom.title" placeholder="请输入模板名称" class="selWidth" size="small"></el-input>
</el-form-item>
<el-form-item label="ID">
<el-input v-model="tableFrom.tempId" placeholder="请输入模板ID" class="selWidth" size="small"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="seachList" size="small">查询</el-button>
</el-form-item>
</el-form>
<router-link :to=" { path:'/appSetting/publicRoutine/publicRoutineTemplate' } ">
<el-button type="primary" size="small" class="mr10">添加</el-button>
</router-link>
<el-button type="primary" size="small" class="mr10" @click="checkTemp">一键同步我的模板</el-button>
</div>
</div>
<el-table
v-loading="listLoading"
:data="tableData.data"
style="width: 100%"
size="mini"
class="table"
highlight-current-row
>
<el-table-column
label="ID"
width="80"
prop="id"
/>
<el-table-column
prop="tempId"
label="模板ID"
min-width="320"
/>
<el-table-column
prop="title"
label="模板名"
min-width="150"
/>
<el-table-column
label="模板关键字"
min-width="250">
<template slot-scope="scope" v-if="scope.row.extra">
<span v-for="item in JSON.parse(scope.row.extra)" :key="item.kid" class="mr5">{{item.name}}</span>
</template>
<template slot-scope="scope" v-else>
<span class="mr5">-</span>
</template>
</el-table-column>
<el-table-column
label="状态"
min-width="100"
>
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
class="demo"
active-text="开启"
inactive-text="关闭"
:active-value="true"
:inactive-value="false"
@click.native="onchangeIsShow(scope.row)"
/>
</template>
</el-table-column>
<el-table-column
label="应用场景"
min-width="150"
>
<template slot-scope="scope">
<el-select v-model="scope.row.type" placeholder="请选择" clearable @change="onchangeType(scope.row)">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</template>
</el-table-column>
<el-table-column
prop="createTime"
label="添加时间"
min-width="120"
/>
<el-table-column label="操作" min-width="150" fixed="right" align="center">
<template slot-scope="scope">
<router-link :to=" { path:'/appSetting/publicRoutine/creatPublicTemplate/' + scope.row.tid + '/0/' + scope.row.id } ">
<el-button size="small" type="text" class="mr10">编辑</el-button>
</router-link>
<!--<el-button type="text" size="small" @click="handleDelete(scope.row, scope.$index)">删除</el-button>-->
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
:page-sizes="[20, 40, 60, 80]"
:page-size="tableFrom.limit"
:current-page="tableFrom.page"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.total"
@size-change="handleSizeChange"
@current-change="pageChange"
/>
</div>
</el-card>
<!--编辑-->
<el-dialog
title="编辑订单"
:visible.sync="dialogVisible"
width="500px"
:before-close="handleClose">
<zb-parser
v-if="dialogVisible"
:form-id="105"
:is-create="isCreate"
:edit-data="editData"
@submit="handlerSubmit"
/>
</el-dialog>
</div>
</template>
<script>
import * as constants from '@/utils/constants.js'
import { tempAsyncApi, myTempTypeApi, myTempListApi, wechatTemplateStatusApi, wechatTemplateSaveApi, wechatTemplateUpdateApi, wechatTemplateDeleteApi, myTempStatusApi} from '@/api/wxApi'
import zbParser from '@/components/FormGenerator/components/parser/ZBParser'
export default {
name: "MyTemplates",
components: { zbParser },
data() {
return {
value: '',
options: [{
value: 'paySubscribe',
label: '支付成功'
}, {
value: 'orderSubscribe',
label: '订单相关'
}, {
value: 'extrctSubscribe',
label: '提现消息'
}, {
value: 'orderRefundSubscribe',
label: '订单退款'
}, {
value: 'rechargeSubscribe',
label: '充值成功'
}],
labelPosition:'right',
isCreate: 0,
editData: {},
dialogVisible: false,
switchData: constants.switchStatus,
tableFrom: {
page: 1,
limit: 20,
status: null,
title: null,
tempId: null
},
tableData: {
data: [],
total: 0
},
listLoading: true,
tempId: null
}
},
mounted() {
this.getList()
},
methods: {
checkTemp() {
this.$modalSure('同步我的模板到小程序').then(() => {
tempAsyncApi().then(() => {
this.$message.success('同步成功')
})
})
},
seachList() {
this.tableFrom.page = 1
this.getList()
},
// 订单删除
handleDelete(row, idx) {
this.$modalSure().then(() => {
wechatTemplateDeleteApi( row.id ).then(() => {
this.$message.success('删除成功')
this.tableData.data.splice(idx, 1)
})
})
},
handleClose() {
this.dialogVisible = false
this.editData = {}
},
handlerSubmit(formValue) {
this.isCreate === 0 ? wechatTemplateSaveApi(formValue).then(data => {
this.$message.success('新增成功')
this.dialogVisible = false
this.editData = {}
this.getList()
}) : wechatTemplateUpdateApi(this.tempId, formValue).then(data => {
this.$message.success('编辑成功')
this.dialogVisible = false
this.getList()
})
},
add() {
this.dialogVisible = true
},
edit(row) {
this.tempId = row.id
this.dialogVisible = true
this.isCreate = 1
this.editData = JSON.parse(JSON.stringify(row))
},
// 列表
getList() {
this.listLoading = true
myTempListApi(this.tableFrom).then(res => {
this.tableData.data = res.list || []
this.tableData.total = res.total
this.listLoading = false
}).catch(() => {
this.listLoading = false
})
},
pageChange(page) {
this.tableFrom.page = page
this.getList()
},
handleSizeChange(val) {
this.tableFrom.limit = val
this.getList()
},
// 修改状态
onchangeIsShow(row) {
myTempStatusApi({status: row.status , id: row.id}).then(() => {
this.$message.success('修改成功')
this.getList()
})
},
// 修改场景
onchangeType(row) {
myTempTypeApi({type: row.type , id: row.id}).then(() => {
this.$message.success('修改成功')
this.getList()
})
}
}
}
</script>
<style scoped lang="scss">
.selWidth {
width: 350px;
}
</style>

View File

@@ -0,0 +1,272 @@
<template>
<div class="divBox">
<el-card class="box-card" v-loading="loadingAll">
<el-alert
:closable="false"
title="你可用该标题的模板搭配不同的关键词使用,配置提交后关键词种类和顺序将不能修改"
type="warning">
</el-alert>
<el-divider></el-divider>
<el-row>
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8">
<div class="tmplmsg-box">
<div class="tmplmsg-preview">
<div class="tmplmsg-preview-title mb35" v-text="form.title"></div>
<div class="acea-row row-middle tmplmsg-preview-cont mb10" v-for="(item, index) in KeywordCheck" :key="item.kid">
<label v-text="item.name"></label>
<span v-text="item.example"></span>
</div>
</div>
</div>
</el-col>
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16">
<div class="tmplmsg-form">
<el-form ref="form" :model="form" :rules="rules" label-width="100px" size="mini">
<el-form-item label="配置关键词" prop="checkList">
<div class="tmplmsg-form-cont">
<el-checkbox-group v-model="form.checkList" :max="5" @change="handleChecked">
<el-checkbox :label="item.kid" v-for="item in KeywordList" :key="item.kid">{{item.name}}</el-checkbox>
</el-checkbox-group>
</div>
</el-form-item>
<el-form-item :label=" '已选择(' + KeywordCheck.length + '/5)'">
<span v-if="KeywordCheck.length ===0 ">请先从上方选择关键词</span>
<div v-else class="tmplmsg-form-check">
<div class="tmplmsg-form-check-list mb10 acea-row row-between" v-for="(item, index) in KeywordCheck" :key="item.kid"
draggable="true"
@dragstart="handleDragStart($event, item)"
@dragover.prevent="handleDragOver($event, item)"
@dragover="handleDragEnter($event, item)"
@dragend="handleDragEnd($event, item)">
<span v-text="item.name"></span>
<i class="el-icon-close" @click="closeCheck(index)"></i>
</div>
</div>
</el-form-item>
<el-form-item label="场景说明" prop="sceneDesc">
<el-input
type="textarea"
:rows="2"
placeholder="请输入场景说明"
v-model="form.sceneDesc">
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loading" @click="onSubmit('form')">提交</el-button>
</el-form-item>
</el-form>
</div>
</el-col>
</el-row>
</el-card>
</div>
</template>
<script>
import { getWeChatKeywordsByTidApi, myTempSaveApi, publicTempInfoApi, myTempInfoApi, myTempUpdateApi } from '@/api/wxApi'
export default {
name: "creatPublicTemplate",
data() {
return {
KeywordList: [],
form: {
checkList: [],
kid: '',
sceneDesc: '',
tid: '',
title: '',
extra: ''
},
KeywordCheck: [],
loading: false,
loadingAll: false,
rules: {
sceneDesc: [
{ required: true, message: '请填写场景说明', trigger: 'blur' }
],
checkList: [
{ type: 'array', required: true, message: '请至少选择一个关键词', trigger: 'change' }
]
},
tempRoute: {}
}
},
created() {
this.tempRoute = Object.assign({}, this.$route)
},
mounted() {
this.getKeywordList()
if( this.$route.params.id !== '0' )this.getTitle()
if( this.$route.params.myId!== '0'){
this.setTagsViewTitle()
this.wxInfo()
}
},
methods: {
// 设置tab标题
setTagsViewTitle() {
const title = '编辑模板'
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.$route.params.myId}` })
this.$store.dispatch('tagsView/updateVisitedView', route)
},
handleChecked(val) {
this.KeywordCheck = this.KeywordList.filter(item=> val.some(ele=>ele == item.kid))
},
onSubmit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let data = {
kid: this.form.checkList.join(','),
sceneDesc: this.form.sceneDesc,
tid: this.$route.params.tid,
title: this.form.title,
extra: JSON.stringify(this.KeywordCheck)
}
this.loading = true
this.$route.params.myId === '0' ? myTempSaveApi(data).then(res => {
this.$message.success('提交成功')
this.$router.push('/appSetting/publicRoutine/publicRoutineTemplate')
this.loading = false
}).catch(()=>{
this.loading = false
}) : myTempUpdateApi({id: this.$route.params.myId}, data).then(res => {
this.$message.success('提交成功')
this.$router.push('/appSetting/publicRoutine/routineTemplate')
this.loading = false
}).catch(()=>{
this.loading = false
})
} else {
return false;
}
});
},
closeCheck(i) {
this.form.checkList.splice(i, 1)
},
// 详情
wxInfo() {
myTempInfoApi({ id: this.$route.params.myId}).then(res => {
this.form = {
checkList: res.kid.split(',').map(Number),
sceneDesc: res.sceneDesc,
tid: res.tid,
title: res.title,
extra: res.extra
}
this.KeywordCheck = JSON.parse(res.extra)
})
},
// 标题
getTitle() {
publicTempInfoApi({ id: this.$route.params.id}).then(res => {
this.form.title = res.title
})
},
// 关键字列表
getKeywordList() {
this.loadingAll = true
getWeChatKeywordsByTidApi({ tid: this.$route.params.tid}).then(res => {
this.KeywordList = res
for (let i=0;i<res; i++) {
this.$set(this.form.checkList, i,res[i])
}
this.loadingAll = false
}).catch(() => {
this.loadingAll = false
})
},
// 移动
handleDragStart (e, item) {
this.dragging = item;
},
handleDragEnd (e, item) {
this.dragging = null
},
handleDragOver (e) {
e.dataTransfer.dropEffect = 'move'
},
handleDragEnter (e, item) {
e.dataTransfer.effectAllowed = 'move'
if (item === this.dragging) {
return
}
const newItems = [...this.KeywordCheck]
const src = newItems.indexOf(this.dragging)
const dst = newItems.indexOf(item)
newItems.splice(dst, 0, ...newItems.splice(src, 1))
this.KeywordCheck = newItems;
}
}
}
</script>
<style scoped lang="scss">
.tmplmsg{
&-box{
border: 1px solid #E7E7EB;
border-radius: 5px;
width: 90%;
min-width: 325px;
margin-right: 30px;
}
&-preview{
min-height: 230px;
padding: 15px;
&-title{
font-size: 14px;
}
&-cont{
font-size: 13px;
label{
width: 100px;
}
}
}
&-form{
position: relative;
width: 60%;
height: auto;
background: #f6f8f9;
background-clip: padding-box;
padding: 20px 20px;
&-cont{
width: 100%;
height: auto;
background: #fff;
padding: 15px;
max-height: 250px;
overflow-y: auto;
/deep/.el-checkbox{
display: block !important;
}
}
&-check{
&-list{
width: 100%;
background: #fff;
line-height: 37px;
height: 37px;
align-items: center;
padding: 0 15px;
box-sizing: border-box;
cursor: pointer;
}
/deep/.el-alert--success{
line-height: normal !important;
}
}
}
&-form::after {
content:"";
position: absolute;
right: 100%;
top: 26px;
width: 0;
height: 0;
border-top: 13px solid transparent;
border-right: 26px solid #f6f8f9;
border-bottom: 13px solid transparent;
}
}
</style>

View File

@@ -0,0 +1,157 @@
<template>
<div class="divBox">
<el-card class="box-card">
<div slot="header" class="clearfix">
<div class="container">
<el-form size="small" :inline="true" label-width="100px">
<el-form-item label="模板标题:">
<el-input v-model="tableFrom.title" placeholder="请输入模板标题" class="selWidth" size="small"></el-input>
</el-form-item>
<el-form-item label="所属类目:">
<el-select v-model="tableFrom.categoryId" placeholder="请选择状态" clearable class="selWidth">
<el-option :label="item.name" :value="item.id" v-for="item in categoryList" :key="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="模板类型:">
<el-select v-model="tableFrom.type" placeholder="请选择类型" clearable class="selWidth">
<el-option label="一次性订阅" value="2"></el-option>
<el-option label="长期订阅" value="3"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="seachList" size="small">查询</el-button>
</el-form-item>
</el-form>
</div>
</div>
<el-table
v-loading="listLoading"
:data="tableData.data"
style="width: 100%"
size="mini"
class="table"
highlight-current-row
>
<el-table-column
label="ID"
width="80"
prop="id"
/>
<el-table-column
prop="tid"
label="模板ID"
min-width="100"
/>
<el-table-column
prop="title"
label="模版标题"
min-width="150"
/>
<el-table-column
label="所属类目"
min-width="100"
>
<template slot-scope="scope">
<span>{{ scope.row.categoryId | wxCategoryFilter }}</span>
</template>
</el-table-column>
<el-table-column
label="模版类型"
min-width="100"
>
<template slot-scope="scope">
<span>{{ scope.row.type | wxTypeFilter }}</span>
</template>
</el-table-column>
<el-table-column
prop="createTime"
label="创建时间"
min-width="150"
/>
<el-table-column label="操作" min-width="80" fixed="right" align="center">
<template slot-scope="scope">
<router-link :to=" { path:'/appSetting/publicRoutine/creatPublicTemplate/' + scope.row.tid + '/' + scope.row.id + '/0' } ">
<el-button size="small" type="text" class="mr10">选用</el-button>
</router-link>
</template>
</el-table-column>
</el-table>
<div class="block">
<el-pagination
:page-sizes="[20, 40, 60, 80]"
:page-size="tableFrom.limit"
:current-page="tableFrom.page"
layout="total, sizes, prev, pager, next, jumper"
:total="tableData.total"
@size-change="handleSizeChange"
@current-change="pageChange"
/>
</div>
</el-card>
</div>
</template>
<script>
import { publicTempListApi, categoryApi } from '@/api/wxApi'
import Cookies from 'js-cookie'
export default {
name: "index",
data() {
return {
tableData: {
data: [],
total: 0
},
listLoading: true,
tableFrom: {
page: 1,
limit: 20,
title: '',
type: '',
categoryId: ''
},
categoryList: []
}
},
mounted() {
this.getList()
this.getCategoryList()
},
methods: {
seachList() {
this.tableFrom.page = 1
this.getList()
},
// 列表
getList() {
this.listLoading = true
publicTempListApi(this.tableFrom).then(res => {
this.tableData.data = res.list || []
this.tableData.total = res.total
this.listLoading = false
}).catch(() => {
this.listLoading = false
})
},
pageChange(page) {
this.tableFrom.page = page
this.getList()
},
handleSizeChange(val) {
this.tableFrom.limit = val
this.getList()
},
// 所属类目
getCategoryList() {
categoryApi().then(res => {
this.categoryList = res
Cookies.set('WxCategory', res)
})
},
}
}
</script>
<style scoped>
</style>