This commit is contained in:
2026-09-09 16:16:22 +08:00
parent ebffbab428
commit ba3a985c40
3749 changed files with 29 additions and 608551 deletions
@@ -1,464 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava>
<el-card shadow="never">
<div class="btn-group tool-button">
<el-button size="medium" @click="openAdd">
新增公众号
</el-button>
</div>
</el-card>
<el-card shadow="never" class="mt10">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column label="公众号名称" header-align="left" prop="appname"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="AppId" header-align="left" prop="appid"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="AppSecret" header-align="left" prop="appsecret"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="Token" header-align="left" prop="token"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="微信支付" header-align="left" prop="payEnabled"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.payEnabled">已配置</span>
<span v-if="!scope.row.payEnabled">未配置</span>
</template>
</el-table-column>
<el-table-column
prop="id"
label="操作"
width="120">
<template slot-scope="scope">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'edit',id:scope.row.id}">
修改
</el-dropdown-item>
<el-dropdown-item
:command="{type:'delete',id:scope.row.id,name:scope.row.name}">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-card>
</guava>
<el-dialog
title="新增公众号"
:visible.sync="addDialogVisible"
width="60%">
<el-form :model="formData" ref="addForm" :rules="formRules" size="small" label-width="120px">
<el-form-item label="配置URL">
${AppDomain!}${base!}/public/weixin/api/{{formData.id}}
<el-alert
title="URL需为公网可访问地址,[系统] - [系统管理] - [系统参数] - 修改 AppDomain 配置项"
type="success">
</el-alert>
</el-form-item>
<el-form-item prop="id" label="唯一标识">
<el-input maxlength="100" placeholder="公众号名称"
v-model="formData.id"
auto-complete="off" tabindex="1" type="text"></el-input>
</el-form-item>
<el-form-item prop="appname" label="公众号名称">
<el-input maxlength="100" placeholder="公众号名称"
v-model="formData.appname"
auto-complete="off" tabindex="1" type="text"></el-input>
</el-form-item>
<el-form-item prop="appid" label="Appid">
<el-input maxlength="100" placeholder="Appid"
v-model="formData.appid"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="appsecret" label="Appsecret">
<el-input maxlength="100" placeholder="Appsecret"
v-model="formData.appsecret"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="token" label="Token">
<el-input maxlength="100" placeholder="Token"
v-model="formData.token"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="encodingAESKey" label="EncodingAESKey">
<el-input maxlength="100" placeholder="EncodingAESKey"
v-model="formData.encodingAESKey"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="payEnabled" label="微信支付">
<el-radio-group v-model="formData.payEnabled" @change="payEnabledChange">
<el-radio :label="true">配置</el-radio>
<el-radio :label="false">不配置</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="配置授权目录" v-if="formData.payEnabled">
${AppDomain!}${base!}/open/pay/
<el-alert
title="请在微信支付后台添加支付授权目录"
type="success">
</el-alert>
</el-form-item>
<el-form-item class="is-required" prop="wxpay_mchid" label="商户号Mchid" v-if="formData.payEnabled">
<el-input maxlength="100" placeholder="商户号Mchid"
v-model="formData.payInfo.wxpay_mchid"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item class="is-required" prop="wxpay_key" label="商户Key" v-if="formData.payEnabled">
<el-input maxlength="100" placeholder="商户Key"
v-model="formData.payInfo.wxpay_key"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doAdd">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="修改公众号"
:visible.sync="editDialogVisible"
width="60%">
<el-form :model="formData" ref="editForm" :rules="formRules" size="small" label-width="120px">
<el-form-item label="配置URL">
${AppDomain!}${base!}/public/weixin/api/{{formData.id}}
<el-alert
title="URL需为公网可访问地址,[系统] - [系统管理] - [系统参数] - 修改 AppDomain 配置项"
type="success">
</el-alert>
</el-form-item>
<el-form-item prop="id" label="唯一标识">
{{formData.id}}
</el-form-item>
<el-form-item prop="appname" label="公众号名称">
<el-input maxlength="100" placeholder="公众号名称"
v-model="formData.appname"
auto-complete="off" tabindex="1" type="text"></el-input>
</el-form-item>
<el-form-item prop="appid" label="Appid">
<el-input maxlength="100" placeholder="Appid"
v-model="formData.appid"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="appsecret" label="Appsecret">
<el-input maxlength="100" placeholder="Appsecret"
v-model="formData.appsecret"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="token" label="Token">
<el-input maxlength="100" placeholder="Token"
v-model="formData.token"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="encodingAESKey" label="EncodingAESKey">
<el-input maxlength="100" placeholder="EncodingAESKey"
v-model="formData.encodingAESKey"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="payEnabled" label="微信支付">
<el-radio-group v-model="formData.payEnabled" @change="payEnabledChange">
<el-radio :label="true">配置</el-radio>
<el-radio :label="false">不配置</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="配置授权目录" v-if="formData.payEnabled">
${AppDomain!}${base!}/open/pay/
<el-alert
title="请在微信支付后台添加支付授权目录"
type="success">
</el-alert>
</el-form-item>
<el-form-item class="is-required" prop="wxpay_mchid" label="商户号Mchid" v-if="formData.payEnabled">
<el-input maxlength="100" placeholder="商户号Mchid"
v-model="formData.payInfo.wxpay_mchid"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item class="is-required" prop="wxpay_key" label="商户Key" v-if="formData.payEnabled">
<el-input maxlength="100" placeholder="商户Key"
v-model="formData.payInfo.wxpay_key"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doEdit">确 定</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var self = this;
var validateId = function (rule, value, callback) {
var regex = new RegExp("^[A-Za-z]+$");
if (!regex.test(value)) {
callback(new Error('唯一标识只可为字母'));
} else {
callback();
}
};
var validateMchid = function (rule, value, callback) {
if (self.formData.payInfo.wxpay_mchid && self.formData.payInfo.wxpay_mchid != "") {
callback();
} else {
callback(new Error('请输入商户号'));
}
};
var validateKey = function (rule, value, callback) {
if (self.formData.payInfo.wxpay_key && self.formData.payInfo.wxpay_key != "") {
callback();
} else {
callback(new Error('请输入商户key'));
}
};
return {
addDialogVisible: false,
editDialogVisible: false,
pageForm: {
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending",
},
tableData: [],
formData: {},
formRules: {
id: [
{required: true, message: '公众号唯一标识', trigger: ['blur', 'change']},
{min: 0, max: 32, message: '长度在 32 个字符以内', trigger: ['blur', 'change']},
{validator: validateId, trigger: ['blur', 'change']}
],
appname: [
{required: true, message: '微信公众号名称', trigger: 'blur'}
],
appid: [
{required: true, message: 'Appid', trigger: 'blur'}
],
appsecret: [
{required: true, message: 'Appsecret', trigger: 'blur'}
],
token: [
{required: true, message: 'Token', trigger: 'blur'}
],
wxpay_mchid: [
{validator: validateMchid, trigger: 'blur'}
],
wxpay_key: [
{validator: validateKey, trigger: 'blur'}
]
},
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/conf/account/data", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
payEnabledChange: function (val) {
if (!val) {
this.formData.payInfo = {};
}
},
openAdd: function () {
var self = this;
self.addDialogVisible = true;
self.formData = {
id: "",
payEnabled: false,
payInfo: {}
};
if (this.$refs["addForm"])
this.$refs["addForm"].resetFields();
},
doAdd: function () {
var self = this;
var url = base + "/platform/wx/conf/account/addDo";
self.$refs["addForm"].validate(function (valid) {
if (valid) {//表单验证通过
self.formData.payInfo = JSON.stringify(self.formData.payInfo);
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.addDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
doEdit: function () {
var self = this;
var url = base + "/platform/wx/conf/account/editDo";
self.$refs["editForm"].validate(function (valid) {
if (valid) {//表单验证通过
self.formData.payInfo = JSON.stringify(self.formData.payInfo);
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.editDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
dropdownCommand: function (command) {//监听下拉框事件
var self = this;
if ("edit" == command.type) {
$.post(base + "/platform/wx/conf/account/edit/" + command.id, {}, function (data) {
if (data.code == 0) {
self.formData = data.data;//加载后台表单数据
self.formData.payInfo = JSON.parse(data.data.payInfo);
self.editDialogVisible = true;//打开编辑窗口
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
if ("delete" == command.type) {
self.$confirm('此操作将删除: ' + command.name, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/conf/account/delete/" + command.id, {}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
}
}
},
created: function () {
this.pageData();
}
});
</script>
<!--#
}
#-->
@@ -1,752 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava>
<el-card shadow="never">
<div class="btn-group tool-button">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="btn-group tool-button">
<el-button size="medium" @click="openAdd">
<i class="ti-plus"></i>
新建菜单
</el-button>
</div>
<div class="pull-right offscreen-right">
<el-button size="medium" @click="pushMenu">
<i class="el-icon-upload"></i>
推送菜单
</el-button>
<el-button size="medium" @click="openSort">
排序
</el-button>
</div>
</el-card>
<el-card shadow="never" class="mt10">
<el-table :key="tableKey" :data="tableData" style="width: 100%" size="small"
:highlight-current-row="true" row-key="id" lazy
:load="loadChild">
<el-table-column label="菜单名称" header-align="center" prop="menuName"
width="200" :show-overflow-tooltip="true" align="left">
</el-table-column>
<el-table-column label="菜单类型" header-align="center" align="center" prop="menuType"
:show-overflow-tooltip="true" width="120">
<template slot-scope="scope">
<span v-if="scope.row.menuType==''">菜单</span>
<span v-if="scope.row.menuType=='view'">链接</span>
<span v-if="scope.row.menuType=='click'">点击事件</span>
<span v-if="scope.row.menuType=='miniprogram'">小程序</span>
</template>
</el-table-column>
<el-table-column label="配置内容" header-align="left"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.menuType==''">-</span>
<span v-if="scope.row.menuType=='view'">{{scope.row.url}}</span>
<span v-if="scope.row.menuType=='click'">绑定关键词: {{scope.row.menuKey}}</span>
<span v-if="scope.row.menuType=='miniprogram'">小程序appid: {{scope.row.appid}}</span>
</template>
</el-table-column>
<el-table-column label="操作" header-align="center"
:show-overflow-tooltip="true" align="center" width="120">
<template slot-scope="scope">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
:command="{type:'add',id:scope.row.id,name:scope.row.menuName}">
添加子菜单
</el-dropdown-item>
<el-dropdown-item divided
:command="{type:'edit',id:scope.row.id,name:scope.row.menuName}">
修改
</el-dropdown-item>
<el-dropdown-item :command="{type:'delete',id:scope.row.id,name:scope.row.menuName}">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-card>
</guava>
<el-dialog
title="新建菜单"
:visible.sync="addDialogVisible"
:close-on-click-modal="false"
width="50%">
<el-form :model="formData" ref="addForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="parentId" label="上级菜单" label-width="80px">
<el-cascader v-if="!isAddFromSub"
style="width: 100%"
tabindex="1"
:options="menuOptions"
:props="props"
v-model="parentMenu"
placeholder="不选择则为顶级"
></el-cascader>
<el-input v-if="isAddFromSub" type="text" v-model="formData.parentName" :disabled="true"></el-input>
</el-form-item>
<el-form-item prop="menuName" label="菜单名称">
<el-input maxlength="100" placeholder="菜单名称"
v-model="formData.menuName"
auto-complete="off" tabindex="1" type="text"></el-input>
<el-alert style="height: 30px;margin-top: 3px;"
title="一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替"
type="warning">
</el-alert>
<el-alert style="height: 30px;margin-top: 3px;"
title="只可设置3个一级菜单,只可设置5个二级菜单"
type="warning">
</el-alert>
</el-form-item>
<el-form-item class="is-required" prop="menuType" label="菜单类型">
<el-radio-group v-model="formData.menuType" size="medium">
<el-radio label="">菜单</el-radio>
<el-radio label="view">链接</el-radio>
<el-radio label="click">点击事件</el-radio>
<el-radio label="miniprogram">小程序</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="formData.menuType=='view'">
<el-autocomplete
style="width: 250px;"
:fetch-suggestions="queryChannel"
placeholder="请输入标题"
@select="handleChannelSelect"
>
<span slot="prepend">搜索栏目</span>
</el-autocomplete>
<el-autocomplete
style="width: 250px;"
:fetch-suggestions="queryArticle"
placeholder="请输入标题"
@select="handleArticleSelect"
>
<span slot="prepend">搜索文章</span>
</el-autocomplete>
</el-form-item>
<el-form-item class="is-required" v-if="formData.menuType=='view'" prop="url" label="跳转链接">
<el-input placeholder="网址"
v-model="formData.url"
auto-complete="off" tabindex="3" type="text"></el-input>
<el-checkbox v-model="checked1" @change="checkedChange1">网页oauth2.0</el-checkbox>
<el-checkbox v-model="checked2" @change="checkedChange2">应用oauth2.0</el-checkbox>
</el-form-item>
<el-form-item class="is-required" v-if="formData.menuType=='miniprogram'" prop="url" label="url">
<el-input placeholder="小程序URL"
v-model="formData.url"
auto-complete="off" tabindex="3" type="text"></el-input>
</el-form-item>
<el-form-item class="is-required" v-if="formData.menuType=='miniprogram'" prop="appid" label="appid">
<el-input placeholder="小程序appid"
v-model="formData.appid"
auto-complete="off" tabindex="4" type="text"></el-input>
</el-form-item>
<el-form-item class="is-required" v-if="formData.menuType=='miniprogram'" prop="pagepath" label="pagepath">
<el-input placeholder="小程序的页面路径"
v-model="formData.pagepath"
auto-complete="off" tabindex="5" type="text"></el-input>
</el-form-item>
<el-form-item v-if="formData.menuType=='click'" class="is-required" label="绑定事件" prop="menuKey">
<el-select v-model="formData.menuKey" placeholder="请选择关键词回复">
<el-option
v-for="item in keyList"
:key="item.id"
:label="item.value"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doAdd">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="修改菜单"
:visible.sync="editDialogVisible"
:close-on-click-modal="false"
width="50%">
<el-form :model="formData" ref="editForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="parentId" label="上级菜单" label-width="80px">
<el-cascader v-if="!isAddFromSub"
style="width: 100%"
tabindex="1"
:options="menuOptions"
:props="props"
v-model="parentMenu"
placeholder="不选择则为顶级"
></el-cascader>
<el-input v-if="isAddFromSub" type="text" v-model="formData.parentName" :disabled="true"></el-input>
</el-form-item>
<el-form-item prop="menuName" label="菜单名称">
<el-input maxlength="100" placeholder="菜单名称"
v-model="formData.menuName"
auto-complete="off" tabindex="1" type="text"></el-input>
<el-alert style="height: 30px;margin-top: 3px;"
title="一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替"
type="warning">
</el-alert>
<el-alert style="height: 30px;margin-top: 3px;"
title="只可设置3个一级菜单,只可设置5个二级菜单"
type="warning">
</el-alert>
</el-form-item>
<el-form-item class="is-required" prop="menuType" label="菜单类型">
<el-radio-group v-model="formData.menuType" size="medium">
<el-radio label="">菜单</el-radio>
<el-radio label="view">链接</el-radio>
<el-radio label="click">点击事件</el-radio>
<el-radio label="miniprogram">小程序</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="formData.menuType=='view'">
<el-autocomplete
style="width: 250px;"
:fetch-suggestions="queryChannel"
placeholder="请输入标题"
@select="handleChannelSelect"
>
<span slot="prepend">搜索栏目</span>
</el-autocomplete>
<el-autocomplete
style="width: 250px;"
:fetch-suggestions="queryArticle"
placeholder="请输入标题"
@select="handleArticleSelect"
>
<span slot="prepend">搜索文章</span>
</el-autocomplete>
</el-form-item>
<el-form-item class="is-required" v-if="formData.menuType=='view'" prop="url" label="跳转链接">
<el-input placeholder="网址"
v-model="formData.url"
auto-complete="off" tabindex="3" type="text"></el-input>
<el-checkbox v-model="checked1" @change="checkedChange1">网页oauth2.0</el-checkbox>
<el-checkbox v-model="checked2" @change="checkedChange2">应用oauth2.0</el-checkbox>
</el-form-item>
<el-form-item class="is-required" v-if="formData.menuType=='miniprogram'" prop="url" label="url">
<el-input placeholder="小程序URL"
v-model="formData.url"
auto-complete="off" tabindex="3" type="text"></el-input>
</el-form-item>
<el-form-item class="is-required" v-if="formData.menuType=='miniprogram'" prop="appid" label="appid">
<el-input placeholder="小程序appid"
v-model="formData.appid"
auto-complete="off" tabindex="4" type="text"></el-input>
</el-form-item>
<el-form-item class="is-required" v-if="formData.menuType=='miniprogram'" prop="pagepath" label="pagepath">
<el-input placeholder="小程序的页面路径"
v-model="formData.pagepath"
auto-complete="off" tabindex="5" type="text"></el-input>
</el-form-item>
<el-form-item v-if="formData.menuType=='click'" class="is-required" label="绑定事件" prop="menuKey">
<el-select v-model="formData.menuKey" placeholder="请选择关键词回复">
<el-option
v-for="item in keyList"
:key="item.id"
:label="item.value"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doEdit">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="菜单排序"
:visible.sync="sortDialogVisible"
width="50%">
<el-tree
ref="sortMenuTree"
:data="sortMenuData"
draggable
:allow-drop="sortAllowDrop"
node-key="id"
:props="defaultProps"
>
<span class="custom-tree-node" slot-scope="scope">
<span>{{ scope.node.label }}</span>
</span>
</el-tree>
<span slot="footer" class="dialog-footer">
<el-button @click="sortDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doSort">确 定</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
var self = this;
var validateUrl = function (rule, value, callback) {
if ((self.formData.menuType == 'view' || self.formData.menuType == 'miniprogram') && self.formData.url == "") {
callback(new Error('请输入正确的URL路径'));
} else {
callback();
}
};
var validateK = function (rule, value, callback) {
if (self.formData.menuType == 'click' && (typeof(self.formData.menuKey) == "undefined" || self.formData.menuKey == "")) {
callback(new Error('请选择关键词'));
} else {
callback();
}
};
var validateA = function (rule, value, callback) {
if (self.formData.menuType == 'miniprogram' && (typeof(self.formData.appid) == "undefined" || self.formData.appid == "")) {
callback(new Error('请输入正确的 appid'));
} else {
callback();
}
};
var validateP = function (rule, value, callback) {
if (self.formData.menuType == 'miniprogram' && (typeof(self.formData.pagepath) == "undefined" || self.formData.pagepath == "")) {
callback(new Error('请输入正确的 pagepath'));
} else {
callback();
}
};
return {
wxConfigs: wxConfigs,
addDialogVisible: false,
editDialogVisible: false,
sortDialogVisible:false,
isAddFromSub: false,
checked1: false,
checked2: false,
selectData: [],
pageForm: {
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending"
},
tableData: [],//后台取出的数据
tableKey:"",
formData: {},
formRules: {
menuName: [
{required: true, message: '菜单名称', trigger: 'blur'}
],
url: [
{required: false, message: '链接', trigger: 'blur'},
{validator: validateUrl, trigger: ['blur', 'change']}
],
menuKey: [
{required: false, message: '绑定关键词', trigger: 'blur'},
{validator: validateK, trigger: ['blur', 'change']}
],
appid: [
{required: false, message: '小程序的appid', trigger: 'blur'},
{validator: validateA, trigger: ['blur', 'change']}
],
pagepath: [
{required: false, message: '小程序的pagepath', trigger: 'blur'},
{validator: validateP, trigger: ['blur', 'change']}
]
},
menuOptions: [],
parentMenu: [],
keyList: [],
sortMenuData: [],
defaultProps: {
children: 'children',
label: 'label'
},
props: {
lazy: true,
checkStrictly:true,
multiple:false,
lazyLoad: function (node, resolve) {
var url = base + "/platform/wx/conf/menu/tree";
$.post(url, {pid: node.value,wxid:"<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"}, function (data) {
if (data.code == 0) {
resolve(data.data);
}
}, "json");
}
}
}
},
methods: {
initTreeTable: function () {
var self = this;
var url = base + "/platform/wx/conf/menu/child";
$.post(url, {pid: "",wxid:"<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"}, function (data) {
if (data.code == 0) {
self.tableData = data.data;
self.tableKey=+new Date();
}
}, "json");
},
loadChild: function (tree, treeNode, resolve) {
var url = base + "/platform/wx/conf/menu/child";
$.post(url, {pid: tree.id,wxid:"<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"}, function (data) {
if (data.code == 0) {
resolve(data.data);
}
}, "json");
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
openAdd: function () {
var self = this;
self.addDialogVisible = true;
self.isAddFromSub = false;
self.formData = {
id: "",
parentId: "",
parentName: "",
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
menuType: "",
url: ""
};//打开新增窗口,表单先清空
if (self.$refs["addForm"])
self.$refs["addForm"].resetFields();
self.menuOptions=[];
self.parentMenu=[];
self.queryKeyword();
},
doAdd: function () {
var self = this;
var url = base + "/platform/wx/conf/menu/addDo";
self.$refs["addForm"].validate(function (valid) {
if (valid) {//表单验证通过
if (!self.isAddFromSub) {//如果不是添加子菜单,则从级联选择框取父节点ID
self.formData.parentId = self.parentMenu[self.parentMenu.length - 1] || "";
}
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.addDialogVisible = false;
self.initTreeTable();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
doEdit: function () {
var self = this;
var url = base + "/platform/wx/conf/menu/editDo";
self.$refs["editForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.editDialogVisible = false;
self.initTreeTable();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
delMore: function () {
var self = this;
if (self.selectData.length == 0) {
self.$message({
message: "请选择消息",
type: 'warning'
});
return false;
}
var ids = [];
self.selectData.forEach(function (val) {
ids.push(val.id);
});
self.$confirm('您确定要删除选中的 ' + ids.length + ' 条数据? ', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/conf/menu/delete", {ids: ids.toString()}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.initTreeTable();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
},
dropdownCommand: function (command) {//监听下拉框事件
var self = this;
if ("add" == command.type) {
self.openAdd();
self.formData.parentId = command.id;
self.formData.parentName = command.name;
self.isAddFromSub = true;
}
if ("edit" == command.type) {
$.post(base + "/platform/wx/conf/menu/edit/" + command.id, {}, function (data) {
if (data.code == 0) {
self.formData = data.data;//加载后台表单数据
self.editDialogVisible = true;//打开编辑窗口
self.queryKeyword();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
if ("delete" == command.type) {
self.$confirm('此操作将删除: ' + command.name, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/conf/menu/delete/" + command.id, {}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.initTreeTable();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
}
},
queryChannel: function (queryString, cb) {
$.post(base + "/platform/wx/reply/news/channel_data", {
searchName: "name",
searchKeyword: queryString,
pageNumber: 1,
pageSize: 10,
pageOrderName: "createdAt",
pageOrderBy: "descending"
}, function (data) {
if (data.code == 0) {
var res = [];
data.data.list.forEach(function (o) {
res.push({value: o.name, id: o.id})
});
cb(res);
}
}, "json");
},
handleChannelSelect: function (val) {
var domain = "${AppDomain!}";
this.formData.url = domain + base + "/public/wx/cms/channel/" + val.id;
},
queryArticle: function (queryString, cb) {
$.post(base + "/platform/wx/reply/news/article_data", {
searchName: "title",
searchKeyword: queryString,
pageNumber: 1,
pageSize: 10,
pageOrderName: "createdAt",
pageOrderBy: "descending"
}, function (data) {
if (data.code == 0) {
var res = [];
data.data.list.forEach(function (o) {
res.push({value: o.title, id: o.id})
});
cb(res);
}
}, "json");
},
handleArticleSelect: function (val) {
var domain = "${AppDomain!}";
this.formData.url = domain + base + "/public/wx/cms/article/" + val.id;
},
checkedChange1: function (val) {
if (this.checked1) {
var str = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.appid!}<!--#}#-->&redirect_uri=$s&response_type=code&scope=snsapi_base&state=11624317#wechat_redirect";
this.formData.url = str.replace("$s", encodeURIComponent(this.formData.url));
} else {
var url = this.formData.url;
var str = url.substring(url.indexOf("redirect_uri=") + 13, url.indexOf("&response_type="));
this.formData.url = decodeURIComponent(str);
}
},
checkedChange2: function (val) {
if (this.checked2) {
var str = "${AppDomain!}${base!}/public/wechat/<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->/oauth?goto_url=$s";
this.formData.url = str.replace("$s", this.formData.url);
} else {
var url = this.formData.url;
this.formData.url = url.substring(url.indexOf("goto_url=") + 9);
}
},
queryKeyword: function () {
var self = this;
$.post(base + "/platform/wx/conf/menu/keywordData", {wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"}, function (data) {
if (data.code == 0) {
var res = [];
data.data.forEach(function (o) {
res.push({value: o.keyword, id: o.keyword})
});
self.keyList = res;
}
}, "json");
},
pushMenu: function () {
var self=this;
self.$confirm('确定要将菜单推送到微信平台?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/conf/menu/pushMenu", { wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.initTreeTable();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
},
//排序树加载
sortMenuLoad: function () {
var self = this;
$.post(base + "/platform/wx/conf/menu/sort", {wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"}, function (data) {
if (data.code == 0) {
self.sortMenuData = data.data;
}
}, "json");
},
//排序树控制不可跨级拖拽
sortAllowDrop: function (moveNode, inNode, type) {
if (moveNode.data.parentId == inNode.data.parentId) {
return type == 'prev';
}
},
//打开排序功能
openSort: function () {
this.sortDialogVisible = true;
this.sortMenuLoad();
},
//递归获取所有的ID值
getTreeIds: function (ids, data) {
var self = this;
data.forEach(function (obj) {
ids.push(obj.id);
if (obj.children && obj.children.length > 0) {
self.getTreeIds(ids, obj.children);
}
});
},
//提交排序后的数据
doSort: function () {
var self = this;
var ids = [];
self.getTreeIds(ids, self.sortMenuData);
$.post(base + "/platform/wx/conf/menu/sortDo", {wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",ids: ids.toString()}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.sortDialogVisible = false;
self.initTreeTable();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
change: function (val) {
window.location.href = "${base}/platform/wx/conf/menu/index/" + val;
}
},
created: function () {
this.initTreeTable();
}
});
</script>
<!--#
}
#-->
@@ -1,673 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.el-upload input[type=file] {
display: none;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 80px;
height: 80px;
line-height: 80px;
text-align: center;
}
.avatar {
width: 80px;
height: 80px;
display: block;
}
</style>
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="pull-right mt5">
<el-button size="medium"
@click="window.location='${base!}/platform/wx/msg/mass/news/<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->'">
<i class="ti-book"></i> 图文素材
</el-button>
<el-button size="medium" @click="openSend"><i class="ti-export"></i> 群发消息</el-button>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column label="群发名称" header-align="left" prop="name">
</el-table-column>
<el-table-column label="群发类型" header-align="left" prop="type" width="120">
<template slot-scope="scope">
<span v-if="scope.row.type=='image'">图片</span>
<span v-if="scope.row.type=='news'">图文消息</span>
<span v-if="scope.row.type=='text'">文本消息</span>
</template>
</el-table-column>
<el-table-column label="发送范围" header-align="left" prop="id"
:show-overflow-tooltip="true" width="120">
<template slot-scope="scope">
<span v-if="scope.row.scope=='some'">部分会员</span>
<span v-if="scope.row.scope=='all'">全部会员</span>
</template>
</el-table-column>
<el-table-column label="发送状态" header-align="left" prop="id"
:show-overflow-tooltip="true" width="120">
<template slot-scope="scope">
<span v-if="scope.row.massSend">
<span v-if="scope.row.massSend.status==1">成功</span>
<span v-if="scope.row.massSend.status!=1">失败</span>
</span>
</template>
</el-table-column>
<el-table-column label="发送日志" header-align="left" prop="id"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.massSend">{{scope.row.massSend.errMsg}}</span>
</template>
</el-table-column>
<el-table-column sortable label="群发时间" header-align="center" align="center" prop="createdAt">
<template slot-scope="scope">
{{formatAt(scope.row.createdAt)}}
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
<el-dialog
title="群发消息"
:visible.sync="sendDialogVisible"
width="60%">
<el-form :model="formData" ref="dialogForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="name" label="群发名称">
<el-input maxlength="255" placeholder="群发名称"
v-model="formData.name"
auto-complete="off" tabindex="1" type="text"></el-input>
</el-form-item>
<el-form-item class="is-required" prop="type" label="群发类型">
<el-radio-group v-model="formData.type" size="medium">
<el-radio label="text">纯文字</el-radio>
<el-radio label="image">图片</el-radio>
<el-radio label="news">图文消息</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item class="is-required" v-if="formData.type=='news'" prop="newsids" label="图文消息">
<el-button size="mini" @click="openNews">选择图文</el-button>
<el-button size="mini" @click="clearNews">清除图文</el-button>
<el-tree style="padding-top: 8px;"
:data="newsTreeData"
:allow-drop="sortAllowDrop"
node-key="id"
default-expand-all
:expand-on-click-node="false"
draggable>
<span class="custom-tree-node" slot-scope="node">
<span>{{ node.data.label }}</span>
<span>
<el-button
type="text"
size="mini"
@click="remove(node)">
Delete
</el-button>
</span>
</span>
</el-tree>
<el-alert
v-if="newsTreeData.length>0"
style="padding:10px;height: 22px;"
title="已选图文可拖拽排序"
type="success"
:closable="false">
</el-alert>
</el-form-item>
<el-form-item v-if="formData.type=='image'" prop="picurl" label="发送图片(2M以内)">
<el-upload
class="avatar-uploader"
tabindex="5"
action="${base}/platform/wx/msg/mass/uploadImage/<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"
name="Filedata"
:before-upload="beforeImageUpload"
:show-file-list="false"
:on-success="function(resp,file,fileList){return handlePicSuccess(resp,file,fileList,'picurl')}">
<img v-if="formData.picurl" :src="formData.picurl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item class="is-required" v-if="formData.type=='text'" label="发送内容" prop="content">
<el-input type="textarea" v-model="formData.content"></el-input>
</el-form-item>
<el-form-item class="is-required" prop="scope" label="发送范围">
<el-radio-group v-model="formData.scope" size="medium">
<el-radio label="all">全部会员</el-radio>
<el-radio label="some">部分会员</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item class="is-required" v-if="formData.scope=='some'" label="选择会员" prop="receivers">
<el-button size="mini" @click="openSel">选择会员</el-button>
<el-input style="margin-top: 5px;" type="textarea" v-model="formData.receivers"></el-input>
<el-alert style="margin-top: 5px;"
title="openid必须2个以上,1万个以内并且使用英文,符号分割"
type="success">
</el-alert>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="sendDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doSend" :disabled="sendBtnDisabled">发 送</el-button>
</span>
</el-dialog>
<el-dialog
title="选择会员"
:visible.sync="selDialogVisible"
width="70%">
<div class="btn-group tool-button">
<el-input placeholder="请输入内容" v-model="pageForm2.searchKeyword" @keyup.enter.native="doSearch2">
<el-select v-model="pageForm2.searchName" slot="prepend" placeholder="查询类型" style="width: 120px;">
<el-option label="昵称" value="nickname"></el-option>
<el-option label="openid" value="openid"></el-option>
</el-select>
<el-button slot="append" icon="el-icon-search" @click="doSearch2"></el-button>
</el-input>
</div>
<el-table
:data="tableData2"
@sort-change='pageOrder2'
size="small"
header-align="center"
style="width: 100%;padding-top: 5px;"
:default-sort="{prop: 'subscribeAt', order: 'descending'}"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="35">
</el-table-column>
<el-table-column label="会员openid" header-align="left" prop="openid" width="222">
</el-table-column>
<el-table-column label="昵称" header-align="left" prop="nickname"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<img v-if="scope.row.headimgurl!=''" :src="scope.row.headimgurl" width="30" height="30">
<span>{{scope.row.nickname}}</span>
</template>
</el-table-column>
<el-table-column label="性别" header-align="left" prop="sex"
:show-overflow-tooltip="true" width="80">
<template slot-scope="scope">
<span v-if="scope.row.sex==1"></span>
<span v-if="scope.row.sex==2"></span>
<span v-if="scope.row.sex==0">未知</span>
</template>
</el-table-column>
<el-table-column label="区域" header-align="left" prop="id"
:show-overflow-tooltip="true">
<template slot-scope="scope">
{{scope.row.country}} - {{scope.row.province}} - {{scope.row.city}}
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="pageSizeChange2"
@current-change="pageNumberChange2"
:current-page="pageForm2.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm2.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm2.totalCount">
</el-pagination>
<span slot="footer" class="dialog-footer">
<el-button @click="selDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doSel">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="选择图文消息"
:visible.sync="newsDialogVisible"
width="50%">
<el-table
:data="tableData3"
@sort-change='pageOrder3'
size="small"
header-align="center"
style="width: 100%;padding-top: 5px;"
:default-sort="{prop: 'subscribeAt', order: 'descending'}"
@selection-change="handleSelectionChangeNews"
>
<el-table-column
type="selection"
width="35">
</el-table-column>
<el-table-column label="标题" header-align="left" prop="title" :show-overflow-tooltip="true">
</el-table-column>
<el-table-column sortable label="添加时间" header-align="center" align="center" prop="createdAt">
<template slot-scope="scope">
{{formatAt(scope.row.createdAt)}}
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="pageSizeChange3"
@current-change="pageNumberChange3"
:current-page="pageForm3.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm3.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm3.totalCount">
</el-pagination>
<span slot="footer" class="dialog-footer">
<el-button @click="newsDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doNews">确 定</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
var self = this;
var validateText = function (rule, value, callback) {
if (self.formData.type == "text" && self.formData.content == "") {
callback(new Error('请输入纯文本内容'));
} else {
callback();
}
};
var validateSome = function (rule, value, callback) {
if (self.formData.scope == "some" && self.formData.receivers.length == 0) {
callback(new Error('请输入选择会员或输入会员openid'));
} else if (self.formData.scope == "some" && self.formData.receivers.length < 2) {
callback(new Error('openid必须大于2个'));
} else {
callback();
}
};
var validateNews = function (rule, value, callback) {
if (self.formData.type == "news" && self.newsTreeData.length == 0) {
callback(new Error('请选择图文消息'));
} else {
callback();
}
};
var validatePic = function (rule, value, callback) {
if (self.formData.type == "image" && self.formData.picurl == "") {
callback(new Error('请上传图片'));
} else {
callback();
}
};
return {
wxConfigs: wxConfigs,
sendDialogVisible: false,
selDialogVisible: false,
newsDialogVisible: false,
sendBtnDisabled: false,
pageForm: {
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending",
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
},
pageForm2: {
searchName: "nickname",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "subscribeAt",
pageOrderBy: "descending",
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
},
pageForm3: {
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending",
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
},
tableData: [],
tableData2: [],
tableData3: [],
formData: {},
formRules: {
name: [
{required: true, message: '群发名称', trigger: 'blur'}
],
content: [
{required: false, message: '文本内容', trigger: 'blur'},
{validator: validateText, trigger: ['blur', 'change']}
],
receivers: [
{required: false, message: '文本内容', trigger: 'blur'},
{validator: validateSome, trigger: ['blur', 'change']}
],
newsids: [
{required: false, message: '图文消息', trigger: 'blur'},
{validator: validateNews, trigger: ['blur', 'change']}
],
picurl: [
{required: false, message: '图片', trigger: 'blur'},
{validator: validatePic, trigger: ['blur', 'change']}
],
},
selectData: [],
selectNews: [],
newsTreeData: []
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/msg/mass/massData", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
doSearch: function () {
this.pageForm.pageNumber = 1;
this.pageData();
},
pageOrder2: function (column) {//按字段排序
this.pageForm2.pageOrderName = column.prop;
this.pageForm2.pageOrderBy = column.order;
this.pageData2();
},
pageNumberChange2: function (val) {//页码更新操作
this.pageForm2.pageNumber = val;
this.pageData2();
},
pageSizeChange2: function (val) {//分页大小更新操作
this.pageForm2.pageSize = val;
this.pageData2();
},
pageData2: function () {//加载分页数据
var self = this;
$.post(base + "/platform/wx/user/data", self.pageForm2, function (data) {
if (data.code == 0) {
self.tableData2 = data.data.list;
self.pageForm2.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
doSearch2: function () {
this.pageForm2.pageNumber = 1;
this.pageData2();
},
pageOrder3: function (column) {//按字段排序
this.pageForm3.pageOrderName = column.prop;
this.pageForm3.pageOrderBy = column.order;
this.pageData3();
},
pageNumberChange3: function (val) {//页码更新操作
this.pageForm3.pageNumber = val;
this.pageData3();
},
pageSizeChange3: function (val) {//分页大小更新操作
this.pageForm3.pageSize = val;
this.pageData3();
},
pageData3: function () {//加载分页数据
var self = this;
$.post(base + "/platform/wx/msg/mass/newsData/<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->", self.pageForm3, function (data) {
if (data.code == 0) {
self.tableData3 = data.data.list;
self.pageForm3.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
handlePicSuccess: function (response, file, fileList, attrName) {
if (response.code == 0) {
// 对象属性直接赋值不会触发试图更新,采用 Vue.set 、this.$set或者Object.assign({}this.obj)创建新对象
// 或者也可以定义一个 refresh 属性 ,当数据发生改变时,该属性同时变化,也会触发视图更新
// this.formData.site_logo =response.data;
this.$set(this.formData, "picurl", response.data.picurl);
this.$set(this.formData, "media_id", response.data.id);
} else {
this.$message({
message: response.msg,
type: 'error'
});
this.$set(this.formData, "picurl", "");
this.$set(this.formData, "media_id", "");
}
},
beforeImageUpload: function (file) {
var isLt2M = file.size / 1024 / 1024 < 2;
if ("image/jpeg" != file.type && "image/png" != file.type) {
this.$message.error('上传图片只能是 JPG 或 PNG 格式');
return false;
}
if (!isLt2M) {
this.$message.error('上传图片大小不能超过 2MB');
return false;
}
return true;
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
handleSelectionChangeNews: function (val) {
this.selectNews = val;
},
//排序树控制不可跨级拖拽
sortAllowDrop: function (moveNode, inNode, type) {
if (moveNode.data.parentId == inNode.data.parentId) {
return type == 'prev';
}
},
openSel: function () {
this.selDialogVisible = true;
this.pageData2();
},
doSel: function () {
var self = this;
self.selDialogVisible = false;
if (self.selectData && self.selectData.length > 0) {
self.selectData.forEach(function (o) {
self.formData.receivers.push(o.openid);
});
}
},
openNews: function () {
this.newsDialogVisible = true;
this.pageData3();
},
doNews: function () {
var self = this;
self.newsDialogVisible = false;
if (self.selectNews && self.selectNews.length > 0) {
self.selectNews.forEach(function (o) {
self.formData.newsids.push(o.id);
self.newsTreeData.push({id: o.id, label: o.title});
});
}
},
clearNews: function () {
var self = this;
self.newsTreeData = [];
},
remove: function (node) {
var self = this;
var data=node.data;
//注意:对数组对象进行深度复制,否则原始对象不能进行删除操作
var temp = JSON.parse(JSON.stringify(self.newsTreeData));
var index = temp.findIndex(function (o) {
return o.id == data.id;
});
temp.splice(index, 1);
self.newsTreeData = temp;
},
openSend: function () {
this.formData = {
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
type: "text",
content: "",
scope: "all",
receivers: [],
picurl: "",
newsids: []
};
if (this.$refs["dialogForm"])
this.$refs["dialogForm"].resetFields();
this.sendDialogVisible = true;
this.sendBtnDisabled = false;
},
doSend: function () {
var self = this;
var url = base + "/platform/wx/msg/mass/sendDo";
self.$refs["dialogForm"].validate(function (valid) {
if (valid) {//表单验证通过
self.newsTreeData.forEach(function (o) {
self.formData.newsids.push(o.id);
});
self.formData.receivers = self.formData.receivers.toString();
self.formData.newsids = self.formData.newsids.toString();
self.sendBtnDisabled = true;
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.sendDialogVisible = false;
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
self.sendBtnDisabled = false;
}, "json");
}
});
},
change: function (val) {
window.location.href = "${base}/platform/wx/msg/mass/" + val;
}
},
created: function () {
this.pageData();
}
});
</script>
<!--#
}
#-->
@@ -1,415 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.note {
width: 100%;
height: 320px;
}
.el-upload input[type=file] {
display: none;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 80px;
height: 80px;
line-height: 80px;
text-align: center;
}
.avatar {
width: 80px;
height: 80px;
display: block;
}
</style>
<link href="${base!}/assets/platform/plugins/umeditor/themes/default/css/umeditor.min.css" type="text/css"
rel="stylesheet">
<script src="${base!}/assets/platform/plugins/umeditor/umeditor.configwx.js"></script>
<script src="${base!}/assets/platform/plugins/umeditor/umeditor.js"></script>
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<el-button size="medium" @click="window.location='${base!}/platform/wx/msg/mass/${wxid!}'"><i
class="el-icon-back"></i> 返回
</el-button>
</div>
<div class="pull-right mt5">
<el-button size="medium" @click="openAdd"><i class="el-icon-plus"></i> 新建图文</el-button>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column label="" header-align="left" prop="picurl"
:show-overflow-tooltip="true" width="56">
<template slot-scope="scope">
<img v-if="scope.row.picurl!=''" :src="'${AppFileDomain!}'+scope.row.picurl" width="30" height="30">
</template>
</el-table-column>
<el-table-column label="标题" header-align="left" prop="title" :show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="作者" header-align="left" prop="author" :show-overflow-tooltip="true" width="120">
</el-table-column>
<el-table-column sortable label="添加时间" header-align="center" align="center" prop="createdAt">
<template slot-scope="scope">
{{formatAt(scope.row.createdAt)}}
</template>
</el-table-column>
<el-table-column
prop="id"
label="操作"
width="120">
<template slot-scope="scope">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'view',id:scope.row.id}">
预览
</el-dropdown-item>
<el-dropdown-item
:command="{type:'delete',id:scope.row.id,title:scope.row.title}">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
<el-dialog
title="新建图文"
:visible.sync="addDialogVisible"
width="60%">
<el-form :model="formData" ref="addForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="title" label="标题">
<el-input maxlength="255" placeholder="标题"
v-model="formData.title"
auto-complete="off" tabindex="1" type="text"></el-input>
</el-form-item>
<el-form-item prop="author" label="作者">
<el-input maxlength="50" placeholder="作者"
v-model="formData.author"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="picurl" label="缩略图(64kb以内)">
<el-upload
class="avatar-uploader"
tabindex="5"
action="${base}/platform/wx/msg/mass/uploadThumb/${wxid!}"
name="Filedata"
:show-file-list="false"
:before-upload="beforeImageUpload"
:on-success="function(resp,file,fileList){return handlePicSuccess(resp,file,fileList,'picurl')}">
<img v-if="formData.picurl" :src="'${AppFileDomain!}'+formData.picurl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item prop="digest" label="摘要">
<el-input type="textarea" v-model="formData.digest"></el-input>
</el-form-item>
<el-form-item prop="content_source_url" label="原文链接">
<el-checkbox v-model="checkedSourceUrl">原文链接</el-checkbox>
<el-input v-if="checkedSourceUrl" maxlength="50" placeholder="原文链接"
v-model="formData.url"
auto-complete="off" tabindex="2" type="text"></el-input>
</el-form-item>
<el-form-item prop="show_cover_pic" label="显示封面">
<el-checkbox v-model="formData.show_cover_pic" true-label="1" false-label="0">显示封面</el-checkbox>
<el-alert v-if="formData.show_cover_pic=='1'"
title="会自动使用文章中第一张图片作为封面图"
type="info"
close-text="知道了">
</el-alert>
</el-form-item>
<el-form-item prop="show_cover_pic" label="打开评论">
<el-checkbox v-model="formData.need_open_comment" true-label="1" false-label="0">打开评论</el-checkbox>
</el-form-item>
<el-form-item prop="show_cover_pic" label="粉丝评论">
<el-checkbox v-model="formData.only_fans_can_comment" true-label="1" false-label="0">粉丝才可评论</el-checkbox>
</el-form-item>
<el-form-item prop="content" label="文章内容">
<!--一个页面中不能出现两个umeditor对象,所以新建和修改用同一个dialog来做吧-->
<script type="text/plain" id="content" class="note"></script>
<!---->
<el-alert style="margin-top: 5px;"
title="注意:具备微信支付权限的公众号,可以使用a标签,其他公众号不能使用"
type="info"
close-text="知道了">
</el-alert>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false"> 取 消 </el-button>
<el-button type="primary" @click="doAdd"> 确 定 </el-button>
</span>
</el-dialog>
<el-dialog
title="预览图文"
:visible.sync="viewDialogVisible"
width="60%">
<el-row style="text-align: center">
<h4><img v-if="formData.picurl" :src="'${AppFileDomain!}'+formData.picurl" width="30" height="30" /> {{formData.title}}</h4>
</el-row>
<el-row>
<span>作者:{{formData.author}}</span>
</el-row>
<el-row style="margin-top: 5px !important;margin-bottom: 5px !important;border-bottom: 1px solid #DDD;">
</el-row>
<el-row>
<span v-html="formData.content"></span>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button @click="viewDialogVisible = false"> 关 闭 </el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
return {
addDialogVisible: false,
viewDialogVisible:false,
checkedSourceUrl:false,
pageForm: {
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending",
wxid: "${wxid!}",
},
tableData: [],
formData: {},
formRules: {
title: [
{required: true, message: '标题', trigger: 'blur'}
],
picurl: [
{required: true, message: '缩略图', trigger: 'blur'}
],
},
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/msg/mass/newsData/${wxid!}", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
doSearch: function () {
this.pageForm.pageNumber = 1;
this.pageData();
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
handlePicSuccess: function (response, file, fileList, attrName) {
if (response.code == 0) {
// 对象属性直接赋值不会触发试图更新,采用 Vue.set 、this.$set或者Object.assign({}this.obj)创建新对象
// 或者也可以定义一个 refresh 属性 ,当数据发生改变时,该属性同时变化,也会触发视图更新
// this.formData.site_logo =response.data;
this.$set(this.formData, "picurl", response.data.picurl);
this.$set(this.formData, "thumb_media_id", response.data.id);
} else {
this.$message({
message: response.msg,
type: 'error'
});
this.$set(this.formData, "picurl", "");
this.$set(this.formData, "thumb_media_id", "");
}
},
beforeImageUpload:function(file) {
var isLt2M = file.size / 1024 < 64;
if ("image/jpeg"!=file.type&&"image/png"!=file.type) {
this.$message.error('缩略图只能是 JPG 或 PNG 格式');
return false;
}
if (!isLt2M) {
this.$message.error('缩略图大小不能超过 64KB');
return false;
}
return true;
},
openAdd: function (obj) {
var self = this;
self.addDialogVisible = true;
if (self.$refs["addForm"])
self.$refs["addForm"].resetFields();
self.formData= {
wxid: self.pageForm.wxid,
show_cover_pic:"0",
digest:""
};
UM.getEditor("content");
setTimeout(function () {
UM.getEditor("content").setContent("", false);
}, 200);
},
doAdd: function () {
var self = this;
var url = base + "/platform/wx/msg/mass/addDo";
self.$refs["addForm"].validate(function (valid) {
if (valid) {//表单验证通过
self.formData.content=UM.getEditor("content").getContent();
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.addDialogVisible = false;
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
dropdownCommand: function (command) {//监听下拉框事件
var self = this;
if ("view" == command.type) {
$.post(base + "/platform/wx/msg/mass/newsDetail/" + command.id, {}, function (data) {
if (data.code == 0) {
self.formData = data.data;//加载后台表单数据
self.viewDialogVisible = true;//打开编辑窗口
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
if ("delete" == command.type) {
self.$confirm('此操作将删除文章: ' + command.title, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/msg/mass/deleteNews/" + command.id, {}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
}
},
change: function (val) {
window.location.href = "${base}/platform/wx/msg/user/" + val;
}
},
created: function () {
this.pageData();
}
});
</script>
<!--#
}
#-->
@@ -1,240 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="btn-group tool-button mt5">
<el-input placeholder="请输入内容" v-model="pageForm.searchKeyword" @keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型" style="width: 120px;">
<el-option label="昵称" value="nickname"></el-option>
<el-option label="内容" value="content"></el-option>
</el-select>
<el-button slot="append" icon="el-icon-search" @click="doSearch"></el-button>
</el-input>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column type="expand">
<template slot-scope="scope">
<el-form label-position="left" inline class="el-table-expand" size="mini">
<el-form-item label="回复内容">
<span v-if="scope.row.replyId && scope.row.replyId!=''">{{ scope.row.reply.content }}</span>
</el-form-item>
<el-form-item label="回复时间">
<span v-if="scope.row.replyId && scope.row.replyId!=''">
{{ formatAt(scope.row.reply.createdAt) }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column label="昵称" header-align="left" prop="nickname"
:show-overflow-tooltip="true" width="180">
<template slot-scope="scope">
<span>{{scope.row.nickname}}</span>
</template>
</el-table-column>
<el-table-column label="消息类型" header-align="left" prop="type" width="80">
</el-table-column>
<el-table-column label="消息内容" header-align="left" prop="content"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="是否回复" header-align="left" prop="replyId"
:show-overflow-tooltip="true" width="120">
<template slot-scope="scope">
<span v-if="!scope.row.replyId || scope.row.replyId==''">未回复
<el-button size="mini" round @click="openReply(scope.row)">回复</el-button>
</span>
<span v-if="scope.row.replyId && scope.row.replyId!=''">已回复</span>
</template>
</el-table-column>
<el-table-column sortable label="接收时间" header-align="center" align="center" prop="createdAt">
<template slot-scope="scope">
{{formatAt(scope.row.createdAt)}}
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
<el-dialog
title="回复消息"
:visible.sync="replyDialogVisible"
width="40%">
<el-form :model="formData" ref="dialogForm" :rules="formRules" size="small" label-width="80px">
<el-form-item label="微信昵称">
{{formData.nickname}}
</el-form-item>
<el-form-item label="消息内容">
{{formData.msgContent}}
</el-form-item>
<el-form-item label="回复内容" prop="replyContent">
<el-input type="textarea" v-model="formData.replyContent"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="replyDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doReply">回 复</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
return {
wxConfigs: wxConfigs,
replyDialogVisible: false,
pageForm: {
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending",
wxid: "${wxConfig.id!}",
},
tableData: [],
formData: {
msgid: "",
replyContent: "",
msgContent: "",
openid:"",
nickname:""
},
formRules: {
replyContent: [
{required: true, message: '回复内容', trigger: 'blur'}
],
},
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/msg/user/data", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
doSearch: function () {
this.pageForm.pageNumber = 1;
this.pageData();
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
openReply: function (obj) {
this.replyDialogVisible = true;
this.formData.msgid = obj.id;
this.formData.msgContent = obj.content;
this.formData.openid = obj.openid;
this.formData.nickname = obj.nickname;
},
doReply: function () {
var self = this;
var url = base + "/platform/wx/msg/user/replyDo/" + self.pageForm.wxid;
self.$refs["dialogForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.replyDialogVisible = false;
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
change: function (val) {
window.location.href = "${base}/platform/wx/msg/user/" + val;
}
},
created: function () {
this.pageData();
}
})
;
</script>
<!--#
}
#-->
@@ -1,134 +0,0 @@
<%
layout("/layouts/platform.html"){
%>
<script src="${base}/assets/plugins/jquery.qrcode.min.js"></script>
<header class="header navbar bg-white shadow">
<div class="btn-group tool-button">
<a class="btn btn-primary navbar-btn" href="${base}/platform/wx/conf/account" data-pjax id="goback"><i class="ti-angle-left"></i> 返回</a>
</div>
</header>
<div class="content-wrap">
<div class="wrapper" style="min-height:500px;">
<section class="panel panel-form">
<div class="row mb10">
<div class="col-lg-12">
<div class="row">
<div class="form-group">
<label class="col-sm-3 control-label" style="text-align: right">测试支付金额(单位:分)</label>
<div class="col-sm-7" style="padding-bottom: 5px;">
<input id="money" style="width: 150px;" type="text" class="form-control" value="1"
data-parsley-required="true"
data-parsley-type="integer">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-7" style="padding-bottom: 5px;">
<button id="pay" class="btn btn-primary">支付</button>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-7" style="padding-bottom: 5px;">
<div id="qrCode"></div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12" style="padding-bottom: 5px;">
<hr/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" style="text-align: right">测试红包金额(单位:分)</label>
<div class="col-sm-7" style="padding-bottom: 5px;">
<input id="redpack" style="width: 150px;" type="text" class="form-control" value="1"
data-parsley-required="true"
data-parsley-type="integer">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" style="text-align: right">关注此公众号的openid</label>
<div class="col-sm-7" style="padding-bottom: 5px;">
<input id="openid" style="width: 250px;" type="text" class="form-control" value="oeLLCvhCWOEqX-mXMhkRJtLgvASU"
data-parsley-required="true"
data-parsley-type="integer">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-7" style="padding-bottom: 5px;">
<button id="redpackBtn" class="btn btn-primary">发普通红包</button>
<button id="redpackGroupBtn" class="btn btn-primary">发裂变红包</button>
<button id="transfersBtn" class="btn btn-primary">向个人付款</button>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-7" style="padding-bottom: 5px;">
<div id="redpackTip"></div>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
</div>
<script language="JavaScript">
$(function () {
$("#pay").on("click", function () {
sublime.showLoadingbar($(".main-content"));
$.get(
"${base}/platform/wx/conf/account/paytest/payWxpay?money=" + $("#money").val(),
function (result) {
if (result.code == 0) {
$("#qrCode").html("");
$("#qrCode").qrcode({width: 200, height: 200, text: result.data});
} else {
$("#qrCode").html("微信支付不可用,请使用其他支付方式");
}
sublime.closeLoadingbar($(".main-content"));
}, 'json'
);
});
$("#redpackBtn").on("click", function () {
sublime.showLoadingbar($(".main-content"));
$.get(
"${base}/platform/wx/conf/account/paytest/redpack?redpack=" + $("#redpack").val()+"&openid="+$("#openid").val(),
function (result) {
$("#redpackTip").html(result.msg);
sublime.closeLoadingbar($(".main-content"));
}, 'json'
);
});
$("#redpackGroupBtn").on("click", function () {
sublime.showLoadingbar($(".main-content"));
$.get(
"${base}/platform/wx/conf/account/paytest/redpackGroup?redpack=" + $("#redpack").val()+"&openid="+$("#openid").val(),
function (result) {
$("#redpackTip").html(result.msg);
sublime.closeLoadingbar($(".main-content"));
}, 'json'
);
});
$("#transfersBtn").on("click", function () {
sublime.showLoadingbar($(".main-content"));
$.get(
"${base}/platform/wx/conf/account/paytest/transfers?redpack=" + $("#redpack").val()+"&openid="+$("#openid").val(),
function (result) {
$("#redpackTip").html(result.msg);
sublime.closeLoadingbar($(".main-content"));
}, 'json'
);
});
});
</script>
<%}%>
@@ -1,416 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.el-upload input[type=file] {
display: none;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 80px;
height: 80px;
line-height: 80px;
text-align: center;
}
.avatar {
width: 80px;
height: 80px;
display: block;
}
</style>
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="btn-group tool-button mt5">
<el-button size="medium" @click="openAdd">
<i class="ti-plus"></i>
新建图片
</el-button>
</div>
<div class="pull-right offscreen-right mt5">
<el-button size="medium" @click="delMore" type="danger" :disabled="selectData.length==0">
<i class="el-icon-delete"></i>
删除
</el-button>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
@selection-change="handleSelectionChange"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column
type="selection"
width="35">
</el-table-column>
<el-table-column label="图片" header-align="left" prop="picurl"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<img v-if="scope.row.picurl!=''" :src="'${AppFileDomain!}'+scope.row.picurl" width="50" height="50">
</template>
</el-table-column>
<el-table-column label="MediaId" header-align="left" prop="mediaId"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column
prop="id"
label="操作"
width="120">
<template slot-scope="scope">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'edit',id:scope.row.id}">
修改
</el-dropdown-item>
<el-dropdown-item
:command="{type:'delete',id:scope.row.id,picurl:scope.row.picurl}">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
<el-dialog
title="新建图片"
:visible.sync="addDialogVisible"
width="30%">
<el-form :model="formData" ref="addForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="picurl" label="发送图片(2M以内)">
<el-upload
class="avatar-uploader"
tabindex="5"
action="${base}/platform/wx/msg/mass/uploadImage/<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"
name="Filedata"
:before-upload="beforeImageUpload"
:show-file-list="false"
:on-success="function(resp,file,fileList){return handlePicSuccess(resp,file,fileList,'picurl')}">
<img v-if="formData.picurl" :src="'${AppFileDomain!}'+formData.picurl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doAdd">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="修改图片"
:visible.sync="editDialogVisible"
width="40%">
<el-form :model="formData" ref="editForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="picurl" label="发送图片(2M以内)">
<el-upload
class="avatar-uploader"
tabindex="5"
action="${base}/platform/wx/msg/mass/uploadImage/<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"
name="Filedata"
:before-upload="beforeImageUpload"
:show-file-list="false"
:on-success="function(resp,file,fileList){return handlePicSuccess(resp,file,fileList,'picurl')}">
<img v-if="formData.picurl" :src="'${AppFileDomain!}'+formData.picurl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doEdit">确 定</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
return {
wxConfigs: wxConfigs,
addDialogVisible: false,
editDialogVisible: false,
selectData: [],
pageForm: {
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending"
},
tableData: [],
formData: {
id: "",
},
formRules: {
picurl: [
{required: true, message: '图片', trigger: 'blur'}
]
},
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/reply/img/data", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
openAdd: function () {
var self = this;
self.addDialogVisible = true;
self.formData = {
id: "",
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
mediaId:""
};//打开新增窗口,表单先清空
if (self.$refs["addForm"])
self.$refs["addForm"].resetFields();
},
doAdd: function () {
var self = this;
var url = base + "/platform/wx/reply/img/addDo";
self.$refs["addForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.addDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
doEdit: function () {
var self = this;
var url = base + "/platform/wx/reply/img/editDo";
self.$refs["editForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.editDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
delMore: function () {
var self = this;
if (self.selectData.length == 0) {
self.$message({
message: "请选择消息",
type: 'warning'
});
return false;
}
var ids = [];
self.selectData.forEach(function (val) {
ids.push(val.id);
});
self.$confirm('您确定要删除选中的 ' + ids.length + ' 条数据? ', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/reply/img/delete", {ids: ids.toString()}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
},
dropdownCommand: function (command) {//监听下拉框事件
var self = this;
if ("edit" == command.type) {
$.post(base + "/platform/wx/reply/img/edit/" + command.id, {}, function (data) {
if (data.code == 0) {
self.formData = data.data;//加载后台表单数据
self.editDialogVisible = true;//打开编辑窗口
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
if ("delete" == command.type) {
self.$confirm('此操作将删除图片: ' + command.picurl, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/reply/img/delete/" + command.id, {}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
}
},
handlePicSuccess: function (response, file, fileList, attrName) {
if (response.code == 0) {
// 对象属性直接赋值不会触发试图更新,采用 Vue.set 、this.$set或者Object.assign({}this.obj)创建新对象
// 或者也可以定义一个 refresh 属性 ,当数据发生改变时,该属性同时变化,也会触发视图更新
// this.formData.site_logo =response.data;
this.$set(this.formData, "picurl", response.data.picurl);
this.$set(this.formData, "mediaId", response.data.id);
} else {
this.$set(this.formData, "picurl", "");
this.$set(this.formData, "mediaId", "");
}
},
beforeImageUpload: function (file) {
var isLt2M = file.size / 1024 / 1024 < 2;
if ("image/jpeg" != file.type && "image/png" != file.type) {
this.$message.error('上传图片只能是 JPG 或 PNG 格式');
return false;
}
if (!isLt2M) {
this.$message.error('上传图片大小不能超过 2MB');
return false;
}
return true;
},
change: function (val) {
window.location.href = "${base}/platform/wx/reply/img/index/" + val;
}
},
created: function () {
this.pageData();
}
});
</script>
<!--#
}
#-->
@@ -1,573 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.el-upload input[type=file] {
display: none;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 80px;
height: 80px;
line-height: 80px;
text-align: center;
}
.avatar {
width: 80px;
height: 80px;
display: block;
}
</style>
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="btn-group tool-button mt5">
<el-button size="medium" @click="openAdd">
<i class="ti-plus"></i>
新建图文
</el-button>
</div>
<div class="pull-right offscreen-right mt5">
<el-button size="medium" @click="delMore" type="danger" :disabled="selectData.length==0">
<i class="el-icon-delete"></i>
删除
</el-button>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
@selection-change="handleSelectionChange"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column
type="selection"
width="35">
</el-table-column>
<el-table-column label="标题" header-align="left" prop="title"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="描述" header-align="left" prop="description"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="图片" header-align="left" prop="picUrl2"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<img v-if="scope.row.picUrl2!=''" :src="'${AppFileDomain!}'+scope.row.picUrl2" width="50" height="50">
</template>
</el-table-column>
<el-table-column label="跳转链接" header-align="left" prop="url"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column
prop="id"
label="操作"
width="120">
<template slot-scope="scope">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'edit',id:scope.row.id}">
修改
</el-dropdown-item>
<el-dropdown-item
:command="{type:'delete',id:scope.row.id,title:scope.row.title}">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
<el-dialog
title="新建图文"
:visible.sync="addDialogVisible"
width="50%">
<el-form :model="formData" ref="addForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="title" label="标题">
<el-input maxlength="100" placeholder="标题"
v-model="formData.title"
auto-complete="off" tabindex="1" type="text"></el-input>
</el-form-item>
<el-form-item prop="description" label="描述">
<el-input type="textarea" v-model="formData.description" tabindex="2"></el-input>
</el-form-item>
<el-form-item prop="picUrl2" label="上传图片(2M以内)">
<el-upload
class="avatar-uploader"
tabindex="5"
action="${base}/platform/wx/reply/news/uploadImage/<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"
name="Filedata"
:before-upload="beforeImageUpload"
:show-file-list="false"
:on-success="function(resp,file,fileList){return handlePicSuccess(resp,file,fileList,'picUrl2')}">
<img v-if="formData.picUrl2" :src="'${AppFileDomain!}'+formData.picUrl2" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item>
<el-autocomplete
style="width: 250px;"
v-model="channelId"
:fetch-suggestions="queryChannel"
placeholder="请输入标题"
@select="handleChannelSelect"
>
<span slot="prepend">搜索栏目</span>
</el-autocomplete>
<el-autocomplete
style="width: 250px;"
v-model="articleId"
:fetch-suggestions="queryArticle"
placeholder="请输入标题"
@select="handleArticleSelect"
>
<span slot="prepend">搜索文章</span>
</el-autocomplete>
</el-form-item>
<el-form-item prop="url" label="跳转链接">
<el-input placeholder="网址"
v-model="formData.url"
auto-complete="off" tabindex="3" type="text"></el-input>
</el-form-item>
<el-form-item>
<el-alert
title="请确保系统参数 AppDomain 为公网可访问域名或IP"
type="warning">
</el-alert>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doAdd">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="修改图文"
:visible.sync="editDialogVisible"
width="40%">
<el-form :model="formData" ref="editForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="title" label="标题">
<el-input maxlength="100" placeholder="标题"
v-model="formData.title"
auto-complete="off" tabindex="1" type="text"></el-input>
</el-form-item>
<el-form-item prop="description" label="描述">
<el-input type="textarea" v-model="formData.description" tabindex="2"></el-input>
</el-form-item>
<el-form-item prop="picUrl2" label="上传图片(2M以内)">
<el-upload
class="avatar-uploader"
tabindex="5"
action="${base}/platform/wx/reply/news/uploadImage/<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"
name="Filedata"
:before-upload="beforeImageUpload"
:show-file-list="false"
:on-success="function(resp,file,fileList){return handlePicSuccess(resp,file,fileList,'picUrl2')}">
<img v-if="formData.picUrl2" :src="'${AppFileDomain!}'+formData.picUrl2" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item>
<el-autocomplete
style="width: 250px;"
v-model="channelId"
:fetch-suggestions="queryChannel"
placeholder="请输入标题"
@select="handleChannelSelect"
>
<span slot="prepend">搜索栏目</span>
</el-autocomplete>
<el-autocomplete
style="width: 250px;"
v-model="articleId"
:fetch-suggestions="queryArticle"
placeholder="请输入标题"
@select="handleArticleSelect"
>
<span slot="prepend">搜索文章</span>
</el-autocomplete>
</el-form-item>
<el-form-item prop="url" label="跳转链接">
<el-input placeholder="网址"
v-model="formData.url"
auto-complete="off" tabindex="3" type="text"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doEdit">确 定</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
var validateUrl = function (rule, value, callback) {
if (value != "" && (value.indexOf("http://") == 0 || value.indexOf("https://") == 0)) {
callback();
} else {
callback(new Error('请输入正确的URL路径'));
}
};
return {
wxConfigs: wxConfigs,
addDialogVisible: false,
editDialogVisible: false,
selectData: [],
channelId: "",
articleId: "",
pageForm: {
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending"
},
tableData: [],
formData: {
id: "",
},
formRules: {
title: [
{required: true, message: '标题', trigger: 'blur'}
],
description: [
{required: true, message: '描述', trigger: 'blur'}
],
picUrl: [
{required: true, message: '图片', trigger: 'blur'}
],
url: [
{required: true, message: '跳转链接', trigger: 'blur'},
{validator: validateUrl, trigger: ['blur', 'change']}
]
},
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/reply/news/data", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
formatAt: function (val) {
if (val > 0)
return moment(val * 1000).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
openAdd: function () {
var self = this;
self.addDialogVisible = true;
self.channelId = "";
self.articleId = "";
self.formData = {
id: "",
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
picUrl: "",
picUrl2: "",
url: ""
};//打开新增窗口,表单先清空
if (self.$refs["addForm"])
self.$refs["addForm"].resetFields();
},
doAdd: function () {
var self = this;
var url = base + "/platform/wx/reply/news/addDo";
self.$refs["addForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.addDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
doEdit: function () {
var self = this;
var url = base + "/platform/wx/reply/news/editDo";
self.$refs["editForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.editDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
delMore: function () {
var self = this;
if (self.selectData.length == 0) {
self.$message({
message: "请选择消息",
type: 'warning'
});
return false;
}
var ids = [];
self.selectData.forEach(function (val) {
ids.push(val.id);
});
self.$confirm('您确定要删除选中的 ' + ids.length + ' 条数据? ', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/reply/news/delete", {ids: ids.toString()}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
},
dropdownCommand: function (command) {//监听下拉框事件
var self = this;
if ("edit" == command.type) {
self.channelId = "";
self.articleId = "";
$.post(base + "/platform/wx/reply/news/edit/" + command.id, {}, function (data) {
if (data.code == 0) {
self.formData = data.data;//加载后台表单数据
self.editDialogVisible = true;//打开编辑窗口
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
if ("delete" == command.type) {
self.$confirm('此操作将删除图文: ' + command.title, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/reply/news/delete/" + command.id, {}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
}
},
handlePicSuccess: function (response, file, fileList, attrName) {
if (response.code == 0) {
// 对象属性直接赋值不会触发试图更新,采用 Vue.set 、this.$set或者Object.assign({}this.obj)创建新对象
// 或者也可以定义一个 refresh 属性 ,当数据发生改变时,该属性同时变化,也会触发视图更新
// this.formData.site_logo =response.data;
this.$set(this.formData, "picUrl", response.data.picurl);
this.$set(this.formData, "picUrl2", response.data.picurl2);
this.$set(this.formData, "mediaId", response.data.id);
} else {
this.$message({
message: response.msg,
type: 'error'
});
this.$set(this.formData, "picUrl", "");
this.$set(this.formData, "picUrl2", "");
this.$set(this.formData, "mediaId", "");
}
},
beforeImageUpload: function (file) {
var isLt2M = file.size / 1024 / 1024 < 2;
if ("image/jpeg" != file.type && "image/png" != file.type) {
this.$message.error('上传图片只能是 JPG 或 PNG 格式');
return false;
}
if (!isLt2M) {
this.$message.error('上传图片大小不能超过 2MB');
return false;
}
return true;
},
queryChannel: function (queryString, cb) {
$.post(base + "/platform/wx/reply/news/channel_data", {
searchName: "name",
searchKeyword: queryString,
pageNumber: 1,
pageSize: 10,
pageOrderName: "createdAt",
pageOrderBy: "descending"
}, function (data) {
if (data.code == 0) {
var res = [];
data.data.list.forEach(function (o) {
res.push({value: o.name, id: o.id})
});
cb(res);
}
}, "json");
},
handleChannelSelect: function (val) {
var domain = "${AppDomain!}";
this.formData.url = domain + base + "/public/wx/cms/channel/" + val.id;
},
queryArticle: function (queryString, cb) {
$.post(base + "/platform/wx/reply/news/article_data", {
searchName: "title",
searchKeyword: queryString,
pageNumber: 1,
pageSize: 10,
pageOrderName: "createdAt",
pageOrderBy: "descending"
}, function (data) {
if (data.code == 0) {
var res = [];
data.data.list.forEach(function (o) {
res.push({value: o.title, id: o.id})
});
cb(res);
}
}, "json");
},
handleArticleSelect: function (val) {
var domain = "${AppDomain!}";
this.formData.url = domain + base + "/public/wx/cms/article/" + val.id;
},
change: function (val) {
window.location.href = "${base}/platform/wx/reply/news/index/" + val;
}
},
created: function () {
this.pageData();
}
});
</script>
<!--#
}
#-->
@@ -1,349 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="btn-group tool-button mt5">
<el-button size="medium" @click="openAdd">
<i class="ti-plus"></i>
新建文本
</el-button>
</div>
<div class="pull-right offscreen-right mt5">
<el-button size="medium" @click="delMore" type="danger" :disabled="selectData.length==0">
<i class="el-icon-delete"></i>
删除
</el-button>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
@selection-change="handleSelectionChange"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column
type="selection"
width="35">
</el-table-column>
<el-table-column label="标题" header-align="left" prop="title"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="内容" header-align="left" prop="content"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column
prop="id"
label="操作"
width="120">
<template slot-scope="scope">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{type:'edit',id:scope.row.id}">
修改
</el-dropdown-item>
<el-dropdown-item
:command="{type:'delete',id:scope.row.id,title:scope.row.title}">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
<el-dialog
title="新建文本"
:visible.sync="addDialogVisible"
width="40%">
<el-form :model="formData" ref="addForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="title" label="标题">
<el-input maxlength="100" placeholder="标题"
v-model="formData.title"
auto-complete="off" tabindex="1" type="text"></el-input>
</el-form-item>
<el-form-item prop="content" label="内容">
<el-input type="textarea" v-model="formData.content" tabindex="2"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doAdd">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="修改文本"
:visible.sync="editDialogVisible"
width="40%">
<el-form :model="formData" ref="editForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="title" label="标题">
<el-input maxlength="100" placeholder="标题"
v-model="formData.title"
auto-complete="off" tabindex="1" type="text"></el-input>
</el-form-item>
<el-form-item prop="content" label="内容">
<el-input type="textarea" v-model="formData.content" tabindex="2"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doEdit">确 定</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
return {
wxConfigs: wxConfigs,
addDialogVisible: false,
editDialogVisible: false,
selectData: [],
pageForm: {
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending"
},
tableData: [],
formData: {
id: "",
},
formRules: {
title: [
{required: true, message: '标题', trigger: 'blur'}
],
content: [
{required: true, message: '内容', trigger: 'blur'}
]
},
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/reply/txt/data", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
openAdd: function () {
var self = this;
self.addDialogVisible = true;
self.formData = {
id: "",
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
};//打开新增窗口,表单先清空
if (self.$refs["addForm"])
self.$refs["addForm"].resetFields();
},
doAdd: function () {
var self = this;
var url = base + "/platform/wx/reply/txt/addDo";
self.$refs["addForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.addDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
doEdit: function () {
var self = this;
var url = base + "/platform/wx/reply/txt/editDo";
self.$refs["editForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.editDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
delMore: function () {
var self = this;
if (self.selectData.length == 0) {
self.$message({
message: "请选择消息",
type: 'warning'
});
return false;
}
var ids = [];
self.selectData.forEach(function (val) {
ids.push(val.id);
});
self.$confirm('您确定要删除选中的 ' + ids.length + ' 条数据? ', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/reply/txt/delete", {ids: ids.toString()}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
},
dropdownCommand: function (command) {//监听下拉框事件
var self = this;
if ("edit" == command.type) {
$.post(base + "/platform/wx/reply/txt/edit/" + command.id, {}, function (data) {
if (data.code == 0) {
self.formData = data.data;//加载后台表单数据
self.editDialogVisible = true;//打开编辑窗口
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
if ("delete" == command.type) {
self.$confirm('此操作将删除: ' + command.title, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/reply/txt/delete/" + command.id, {}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
}
},
change: function (val) {
window.location.href = "${base}/platform/wx/reply/txt/index/" + val;
}
},
created: function () {
this.pageData();
}
});
</script>
<!--#
}
#-->
@@ -1,316 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="btn-group tool-button mt5">
<el-button size="medium" @click="openAdd">
<i class="ti-plus"></i>
添加模板
</el-button>
</div>
<div class="pull-right offscreen-right mt5">
<el-button size="medium" @click="delMore" type="danger" :disabled="selectData.length==0">
<i class="el-icon-delete"></i>
删除
</el-button>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
@selection-change="handleSelectionChange"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column
type="selection"
width="35">
</el-table-column>
<el-table-column label="模板编号" header-align="left" prop="id"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="template_id" header-align="left" prop="template_id"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column
prop="id"
label="操作"
width="120">
<template slot-scope="scope">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
:command="{type:'delete',id:scope.row.id}">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
<el-dialog
title="添加模板"
:visible.sync="addDialogVisible"
width="40%">
<el-form :model="formData" ref="addForm" :rules="formRules" size="small" label-width="80px">
<el-form-item prop="id" label="模板编号">
<el-input maxlength="100" placeholder="模板编号"
v-model="formData.id"
auto-complete="off" tabindex="1" type="text"></el-input>
<el-alert style="margin-top: 3px;"
title="填写微信公众号后台模板库里的模板编号,如 TM00001,注意一定要从这里添加,而非模板库页面手动添加"
type="warning">
</el-alert>
<el-alert style="margin-top: 3px;"
title="添加成功后到“模板列表”里同步模板"
type="warning">
</el-alert>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doAdd">确 定</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
return {
wxConfigs: wxConfigs,
addDialogVisible: false,
editDialogVisible: false,
selectData: [],
pageForm: {
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending"
},
tableData: [],
formData: {
},
formRules: {
id: [
{required: true, message: '模板编号', trigger: 'blur'}
]
},
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/tpl/id/data", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
openAdd: function () {
var self = this;
self.addDialogVisible = true;
self.formData = {
id: "",
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
};//打开新增窗口,表单先清空
if (self.$refs["addForm"])
self.$refs["addForm"].resetFields();
},
doAdd: function () {
var self = this;
var url = base + "/platform/wx/tpl/id/addDo";
self.$refs["addForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.addDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
doEdit: function () {
var self = this;
var url = base + "/platform/wx/tpl/id/editDo";
self.$refs["editForm"].validate(function (valid) {
if (valid) {//表单验证通过
$.post(url, self.formData, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.editDialogVisible = false;
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
});
},
delMore: function () {
var self = this;
if (self.selectData.length == 0) {
self.$message({
message: "请选择消息",
type: 'warning'
});
return false;
}
var ids = [];
self.selectData.forEach(function (val) {
ids.push(val.id);
});
self.$confirm('您确定要删除选中的 ' + ids.length + ' 条数据? ', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/tpl/id/delete", {ids: ids.toString(),wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
},
dropdownCommand: function (command) {//监听下拉框事件
var self = this;
if ("delete" == command.type) {
self.$confirm('确定要删除模板 '+command.id+'?此操作不可恢复', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/tpl/id/delete/" + command.id, {wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
}
},
change: function (val) {
window.location.href = "${base}/platform/wx/tpl/id/index/" + val;
}
},
created: function () {
this.pageData();
}
});
</script>
<!--#
}
#-->
@@ -1,167 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="pull-right offscreen-right mt5">
<el-button size="medium" @click="getTpl">
<i class="el-icon-download"></i>
同步模板
</el-button>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column label="template_id" header-align="left" prop="template_id"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="模板标题" header-align="left" prop="title"
:show-overflow-tooltip="true" width="150">
</el-table-column>
<el-table-column label="所属行业" header-align="left" prop="primary_industry"
:show-overflow-tooltip="true">
<template slot-scope="scope">
{{scope.row.primary_industry}} - {{scope.row.deputy_industry}}
</template>
</el-table-column>
<el-table-column label="模板示例" header-align="left" prop="example"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="模板内容" header-align="left" prop="content"
:show-overflow-tooltip="true">
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
return {
wxConfigs: wxConfigs,
pageForm: {
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending"
},
tableData: [],
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/tpl/list/data", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
getTpl:function(){
var self = this;
self.$confirm('您确定要同步模板?确定后请稍作等待.. ', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/tpl/list/getDo", {wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->"}, function (data) {
if (data.code == 0) {
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
},
change: function (val) {
window.location.href = "${base}/platform/wx/tpl/list/index/" + val;
}
},
created: function () {
this.pageData();
}
});
</script>
<!--#
}
#-->
@@ -1,250 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="btn-group tool-button mt5">
<el-input placeholder="请输入内容" v-model="pageForm.searchKeyword" @keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型" style="width: 120px;">
<el-option label="昵称" value="nickname"></el-option>
<el-option label="openid" value="openid"></el-option>
</el-select>
<el-button slot="append" icon="el-icon-search" @click="doSearch"></el-button>
</el-input>
</div>
<div class="pull-right offscreen-right mt5">
<el-button size="medium" @click="delMore" type="danger" :disabled="selectData.length==0">
<i class="el-icon-delete"></i>
删除
</el-button>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
@selection-change="handleSelectionChange"
:default-sort="{prop: 'createdAt', order: 'descending'}"
>
<el-table-column
type="selection"
width="35">
</el-table-column>
<el-table-column label="openid" header-align="left" prop="openid"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="微信昵称" header-align="left" prop="nickname"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="发送内容" header-align="left" prop="content"
:show-overflow-tooltip="true">
</el-table-column>
<el-table-column label="发送状态" header-align="left" prop="status"
:show-overflow-tooltip="true" width="100">
<template slot-scope="scope">
<span v-if="scope.row.status==1">发送成功</span>
<span v-if="scope.row.status==2">发送失败</span>
</template>
</el-table-column>
<el-table-column sortable label="发送时间" header-align="center" align="center" prop="createdAt">
<template slot-scope="scope">
{{formatAt(scope.row.createdAt)}}
</template>
</el-table-column>
<el-table-column
prop="id"
label="操作"
width="120">
<template slot-scope="scope">
<el-dropdown @command="dropdownCommand">
<el-button size="mini">
<i class="ti-settings"></i>
<span class="ti-angle-down"></span>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
:command="{type:'delete',id:scope.row.id}">
删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
return {
wxConfigs: wxConfigs,
selectData: [],
pageForm: {
wxid: "<!--#if(!isEmpty(wxConfig)){#-->${wxConfig.id!}<!--#}#-->",
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "createdAt",
pageOrderBy: "descending"
},
tableData: [],
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/tpl/log/data", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
doSearch:function(){
this.pageForm.pageSize = 1;
this.pageData();
},
formatAt: function (val) {
if (val > 0)
return moment(val).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
delMore: function () {
var self = this;
if (self.selectData.length == 0) {
self.$message({
message: "请选择消息",
type: 'warning'
});
return false;
}
var ids = [];
self.selectData.forEach(function (val) {
ids.push(val.id);
});
self.$confirm('您确定要删除选中的 ' + ids.length + ' 条数据? ', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/tpl/log/delete", {ids: ids.toString()}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
},
dropdownCommand: function (command) {//监听下拉框事件
var self = this;
if ("delete" == command.type) {
self.$confirm('确定删除吗?' , '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: function (a, b) {
if ("confirm" == a) {//确认后再执行
$.post(base + "/platform/wx/tpl/log/delete/" + command.id, {}, function (data) {
if (data.code == 0) {
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
}
}
});
}
},
change: function (val) {
window.location.href = "${base}/platform/wx/tpl/log/index/" + val;
}
},
created: function () {
this.pageData();
}
});
</script>
<!--#
}
#-->
@@ -1,229 +0,0 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-row class="header navbar bg-white shadow">
<div class="btn-group tool-button mt5">
<span>微信公众号:</span>
<el-select size="medium" v-model="pageForm.wxid" placeholder="请选择" @change="change">
<el-option
v-for="item in wxConfigs"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="btn-group tool-button mt5">
<el-input placeholder="请输入内容" v-model="pageForm.searchKeyword" @keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" placeholder="查询类型" style="width: 120px;">
<el-option label="昵称" value="nickname"></el-option>
<el-option label="openid" value="openid"></el-option>
</el-select>
<el-button slot="append" icon="el-icon-search" @click="doSearch"></el-button>
</el-input>
</div>
<div class="pull-right offscreen-right mt5">
<el-button size="medium" @click="openUp">
<i class="el-icon-download"></i>
同步会员资料
</el-button>
</div>
</el-row>
<el-row class="el-table-container">
<el-table
:data="tableData"
@sort-change='pageOrder'
size="small"
header-align="center"
style="width: 100%"
:default-sort="{prop: 'subscribeAt', order: 'descending'}"
>
<el-table-column label="会员openid" header-align="left" prop="openid" width="222">
</el-table-column>
<el-table-column label="昵称" header-align="left" prop="nickname"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<img v-if="scope.row.headimgurl!=''" :src="scope.row.headimgurl" width="30" height="30">
<span>{{scope.row.nickname}}</span>
</template>
</el-table-column>
<el-table-column label="性别" header-align="left" prop="sex"
:show-overflow-tooltip="true" width="80">
<template slot-scope="scope">
<span v-if="scope.row.sex==1"></span>
<span v-if="scope.row.sex==2"></span>
<span v-if="scope.row.sex==0">未知</span>
</template>
</el-table-column>
<el-table-column label="区域" header-align="left" prop="id"
:show-overflow-tooltip="true">
<template slot-scope="scope">
{{scope.row.country}} - {{scope.row.province}} - {{scope.row.city}}
</template>
</el-table-column>
<el-table-column label="是否关注" header-align="left" prop="subscribe"
:show-overflow-tooltip="true" width="80">
<template slot-scope="scope">
<i v-if="!scope.row.subscribe" class="fa fa-circle text-danger ml5"></i>
<i v-if="scope.row.subscribe" class="fa fa-circle text-success ml5"></i>
</template>
</el-table-column>
<el-table-column sortable label="关注时间" header-align="center" align="center" prop="subscribeAt">
<template slot-scope="scope">
{{formatAt(scope.row.subscribeAt)}}
</template>
</el-table-column>
</el-table>
</el-row>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-sizes="[10, 20, 30, 50]"
:page-size="pageForm.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageForm.totalCount">
</el-pagination>
</el-row>
<el-dialog
title="同步用户资料"
:visible.sync="upDialogVisible"
width="40%">
<el-row>
<el-alert
title="微信公众号后台配置好接入地址之后,只需做一次手动同步操作即可"
type="success">
</el-alert>
</el-row>
<el-row style="padding-top:5px;text-align: center">
<el-progress type="circle" :percentage="progressNum" :status="progressStatus"></el-progress>
</el-row>
<span slot="footer" class="dialog-footer">
<el-button @click="upDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="doUp">同 步</el-button>
</span>
</el-dialog>
</div>
<script>
new Vue({
el: "#app",
data: function () {
var wxConfigs = [];
<!--#for(o in wxList){#-->
wxConfigs.push({value: "${o.id!}", label: "${o.appname!}"});
<!--#}#-->
return {
wxConfigs: wxConfigs,
upDialogVisible: false,
pageForm: {
searchName: "",
searchKeyword: "",
pageNumber: 1,
pageSize: 10,
totalCount: 0,
pageOrderName: "subscribeAt",
pageOrderBy: "descending",
wxid: "${wxConfig.id!}",
},
tableData: [],
progressNum: 0,
progressStatus: ""
}
},
methods: {
pageOrder: function (column) {//按字段排序
this.pageForm.pageOrderName = column.prop;
this.pageForm.pageOrderBy = column.order;
this.pageData();
},
pageNumberChange: function (val) {//页码更新操作
this.pageForm.pageNumber = val;
this.pageData();
},
pageSizeChange: function (val) {//分页大小更新操作
this.pageForm.pageSize = val;
this.pageData();
},
pageData: function () {//加载分页数据
var self = this;
sublime.showLoadingbar();//显示loading
$.post(base + "/platform/wx/user/data", self.pageForm, function (data) {
sublime.closeLoadingbar();//关闭loading
if (data.code == 0) {
self.tableData = data.data.list;
self.pageForm.totalCount = data.data.totalCount;
} else {
self.$message({
message: data.msg,
type: 'error'
});
}
}, "json");
},
doSearch: function () {
this.pageForm.pageNumber = 1;
this.pageData();
},
formatAt: function (val) {
if (val > 0)
return moment(val*1000).format("YYYY-MM-DD HH:mm");
return "";
},
handleSelectionChange: function (val) {
this.selectData = val;
},
openUp: function () {
this.upDialogVisible = true;
},
doUp: function () {
var self = this;
var t = setInterval(function () {
self.progressNum += 10;
if (self.progressNum >= 100) {
window.clearInterval(t);
}
}, 400);
var url = base + "/platform/wx/user/down/" + self.pageForm.wxid;
$.post(url, {}, function (data) {
if (data.code == 0) {
self.progressStatus = "success";
self.upDialogVisible = false;
self.$message({
message: data.msg,
type: 'success'
});
self.pageData();
} else {
self.$message({
message: data.msg,
type: 'error'
});
self.progressStatus = "exception";
}
}, "json");
},
change: function (val) {
window.location.href = "${base}/platform/wx/user/index/" + val;
}
},
created: function () {
this.pageData();
}
})
;
</script>
<!--#
}
#-->