🐛 Fixing a bug. 修改微信账号管理和粉丝管理

This commit is contained in:
aeizzz 2023-02-24 14:04:20 +08:00
parent 5e500600b1
commit c4cebf4fe5
23 changed files with 592 additions and 473 deletions

View File

@ -19,7 +19,7 @@ import request from '/@/utils/request';
export function fetchList(query) {
return request({
url: '/mp/wx-account-fans/page',
url: '/admin/wx-account-fans/page',
method: 'get',
params: query
})
@ -27,7 +27,7 @@ export function fetchList(query) {
export function addObj(obj) {
return request({
url: '/mp/wx-account-fans',
url: '/admin/wx-account-fans',
method: 'post',
data: obj
})
@ -35,28 +35,28 @@ export function addObj(obj) {
export function sync(appId) {
return request({
url: '/mp/wx-account-fans/sync/' + appId,
url: '/admin/wx-account-fans/sync/' + appId,
method: 'post'
})
}
export function getObj(id) {
return request({
url: '/mp/wx-account-fans/' + id,
url: '/admin/wx-account-fans/' + id,
method: 'get'
})
}
export function delObj(id) {
export function delObjs(id) {
return request({
url: '/mp/wx-account-fans/' + id,
url: '/admin/wx-account-fans/' + id,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/mp/wx-account-fans',
url: '/admin/wx-account-fans',
method: 'put',
data: obj
})

View File

@ -19,7 +19,7 @@ import request from '/@/utils/request';
export function fetchList(query) {
return request({
url: '/mp/wx-account/page',
url: '/admin/wx-account/page',
method: 'get',
params: query
})
@ -27,7 +27,7 @@ export function fetchList(query) {
export function addObj(obj) {
return request({
url: '/mp/wx-account',
url: '/admin/wx-account',
method: 'post',
data: obj
})
@ -35,35 +35,35 @@ export function addObj(obj) {
export function getObj(id) {
return request({
url: '/mp/wx-account/' + id,
url: '/admin/wx-account/' + id,
method: 'get'
})
}
export function generateQr(appid) {
return request({
url: '/mp/wx-account/qr/' + appid,
url: '/admin/wx-account/qr/' + appid,
method: 'post'
})
}
export function clearQuota(appid) {
return request({
url: '/mp/wx-account/clear-quota/' + appid,
url: '/admin/wx-account/clear-quota/' + appid,
method: 'post'
})
}
export function delObj(id) {
export function delObjs(id) {
return request({
url: '/mp/wx-account/' + id,
url: '/admin/wx-account/' + id,
method: 'delete'
})
}
export function putObj(obj) {
return request({
url: '/mp/wx-account',
url: '/admin/wx-account',
method: 'put',
data: obj
})
@ -71,14 +71,14 @@ export function putObj(obj) {
export function fetchAccountList() {
return request({
url: '/mp/wx-account/list',
url: '/admin/wx-account/list',
method: 'get'
})
}
export function fetchStatistics(q) {
return request({
url: '/mp/wx-account/statistics',
url: '/admin/wx-account/statistics',
method: 'get',
params: q
})

View File

@ -139,11 +139,8 @@ const getMenuData = () => {
})
};
const showembedded = ref(false)
watch(() => state.ruleForm.path, (val) => {
if (val.startsWith('http')) {
showembedded.value = true
@ -154,13 +151,12 @@ watch(() => state.ruleForm.path, (val) => {
})
const dataRules = reactive({
menType: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
parentId: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
name: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
path: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
permission: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
sortOrder: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
keepAlive: [{ required: true, message: "姓名不能为空", trigger: "blur" }]
menType: [{ required: true, message: "菜单类型不能为空", trigger: "blur" }],
parentId: [{ required: true, message: "上级菜单不能为空", trigger: "blur" }],
name: [{ required: true, message: "菜单不能为空", trigger: "blur" }],
path: [{ required: true, message: "路径不能为空", trigger: "blur" }],
permission: [{ required: true, message: "权限代码不能为空", trigger: "blur" }],
sortOrder: [{ required: true, message: "排序不能为空", trigger: "blur" }]
})
//
const openDialog = (type: string, row?: any) => {

View File

@ -1,416 +0,0 @@
<template>
<div class="app-container">
<doc-alert title="公众号接入" url="https://doc.iocoder.cn/mp/account/" />
<!-- 搜索工作栏 -->
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="ElIconSearch" @click="handleQuery"
>搜索</el-button
>
<el-button :icon="ElIconRefresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作工具栏 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
:icon="ElIconPlus"
size="mini"
@click="handleAdd"
v-hasPermi="['mp:account:create']"
>新增
</el-button>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<!-- 列表 -->
<el-table v-loading="loading" :data="list">
<el-table-column label="名称" align="center" prop="name" />
<el-table-column
label="微信号"
align="center"
prop="account"
width="180"
/>
<el-table-column label="appId" align="center" prop="appId" width="180" />
<!-- <el-table-column label="appSecret" align="center" prop="appSecret" width="180"/>-->
<!-- <el-table-column label="token" align="center" prop="token"/>-->
<!-- <el-table-column label="消息加解密密钥" align="center" prop="aesKey"/>-->
<el-table-column
label="服务器地址(URL)"
align="center"
prop="appId"
width="360"
>
<template v-slot="scope">
{{ 'http://服务端地址/mp/open/' + scope.row.appId }}
</template>
</el-table-column>
<el-table-column label="二维码" align="center" prop="qrCodeUrl">
<template v-slot="scope">
<img
v-if="scope.row.qrCodeUrl"
:src="scope.row.qrCodeUrl"
alt="二维码"
style="height: 100px"
/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<!-- <el-table-column label="创建时间" align="center" prop="createTime" width="180">-->
<!-- <template v-slot="scope">-->
<!-- <span>{{ parseTime(scope.row.createTime) }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template v-slot="scope">
<el-button
size="mini"
type="text"
:icon="ElIconEdit"
@click="handleUpdate(scope.row)"
v-hasPermi="['mp:account:update']"
>修改
</el-button>
<el-button
size="mini"
type="text"
:icon="ElIconDelete"
@click="handleDelete(scope.row)"
v-hasPermi="['mp:account:delete']"
>删除
</el-button>
<el-button
size="mini"
type="text"
:icon="ElIconRefresh"
@click="handleGenerateQrCode(scope.row)"
v-hasPermi="['mp:account:qr-code']"
>生成二维码
</el-button>
<el-button
size="mini"
type="text"
:icon="ElIconShare"
@click="handleCleanQuota(scope.row)"
v-hasPermi="['mp:account:clear-quota']"
>清空 API 配额
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 对话框(添加 / 修改) -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item label="名称" prop="name">
<el-input v-model="form.name" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="微信号" prop="account">
<template v-slot:label>
<span>
<el-tooltip
content="在微信公众平台mp.weixin.qq.com的菜单 [设置与开发 - 公众号设置 - 账号详情] 中能找到「微信号」"
placement="top"
>
<el-icon><el-icon-question /></el-icon>
</el-tooltip>
微信号
</span>
</template>
<el-input v-model="form.account" placeholder="请输入微信号" />
</el-form-item>
<el-form-item label="appId" prop="appId">
<template v-slot:label>
<span>
<el-tooltip
content="在微信公众平台mp.weixin.qq.com的菜单 [设置与开发 - 公众号设置 - 基本设置] 中能找到「开发者ID(AppID)」"
placement="top"
>
<el-icon><el-icon-question /></el-icon>
</el-tooltip>
appId
</span>
</template>
<el-input v-model="form.appId" placeholder="请输入公众号 appId" />
</el-form-item>
<el-form-item label="appSecret" prop="appSecret">
<template v-slot:label>
<span>
<el-tooltip
content="在微信公众平台mp.weixin.qq.com的菜单 [设置与开发 - 公众号设置 - 基本设置] 中能找到「开发者密码(AppSecret)」"
placement="top"
>
<el-icon><el-icon-question /></el-icon>
</el-tooltip>
appSecret
</span>
</template>
<el-input
v-model="form.appSecret"
placeholder="请输入公众号 appSecret"
/>
</el-form-item>
<el-form-item label="token" prop="token">
<el-input v-model="form.token" placeholder="请输入公众号token" />
</el-form-item>
<el-form-item label="消息加解密密钥" prop="aesKey">
<el-input v-model="form.aesKey" placeholder="请输入消息加解密密钥" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
type="textarea"
v-model="form.remark"
placeholder="请输入备注"
/>
</el-form-item>
</el-form>
<template v-slot:footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script>
import {
Question as ElIconQuestion,
Search as ElIconSearch,
Refresh as ElIconRefresh,
Plus as ElIconPlus,
Edit as ElIconEdit,
Delete as ElIconDelete,
Share as ElIconShare,
} from '@element-plus/icons'
import {
clearAccountQuota,
createAccount,
deleteAccount,
generateAccountQrCode,
getAccount,
getAccountPage,
updateAccount,
} from '@/api/mp/account'
export default {
data() {
return {
//
loading: true,
//
showSearch: true,
//
total: 0,
//
list: [],
//
title: '',
//
open: false,
//
queryParams: {
pageNo: 1,
pageSize: 10,
name: null,
account: null,
appId: null,
},
//
form: {},
//
rules: {
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
account: [
{ required: true, message: '公众号账号不能为空', trigger: 'blur' },
],
appId: [
{ required: true, message: '公众号 appId 不能为空', trigger: 'blur' },
],
appSecret: [
{ required: true, message: '公众号密钥不能为空', trigger: 'blur' },
],
token: [
{ required: true, message: '公众号 token 不能为空', trigger: 'blur' },
],
},
ElIconSearch,
ElIconRefresh,
ElIconPlus,
ElIconEdit,
ElIconDelete,
ElIconShare,
}
},
components: {
ElIconQuestion,
},
name: 'MpAccount',
created() {
this.getList()
},
methods: {
/** 查询列表 */
getList() {
this.loading = true
//
let params = { ...this.queryParams }
//
getAccountPage(params).then((response) => {
this.list = response.data.list
this.total = response.data.total
this.loading = false
})
},
/** 取消按钮 */
cancel() {
this.open = false
this.reset()
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
name: undefined,
account: undefined,
appId: undefined,
appSecret: undefined,
token: undefined,
aesKey: undefined,
remark: undefined,
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRangeCreateTime = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加公众号账号'
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id
getAccount(id).then((response) => {
this.form = response.data
this.open = true
this.title = '修改公众号账号'
})
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return
}
//
if (this.form.id != null) {
updateAccount(this.form).then(() => {
this.$modal.msgSuccess('修改成功')
this.open = false
this.getList()
})
return
}
//
createAccount(this.form).then(() => {
this.$modal.msgSuccess('新增成功')
this.open = false
this.getList()
})
})
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id
this.$modal
.confirm('是否确认删除公众号账号编号为"' + row.name + '"的数据项?')
.then(function () {
return deleteAccount(id)
})
.then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
})
.catch(() => {})
},
/** 生成二维码的按钮操作 */
handleGenerateQrCode(row) {
const id = row.id
this.$modal
.confirm('是否确认生成公众号账号编号为"' + row.name + '"的二维码?')
.then(function () {
return generateAccountQrCode(id)
})
.then(() => {
this.getList()
this.$modal.msgSuccess('生成二维码成功')
})
.catch(() => {})
},
/** 清空二维码 API 配额的按钮操作 */
handleCleanQuota(row) {
const id = row.id
this.$modal
.confirm(
'是否确认清空生成公众号账号编号为"' + row.name + '"的 API 配额?'
)
.then(function () {
return clearAccountQuota(id)
})
.then(() => {
this.$modal.msgSuccess('清空 API 配额成功')
})
.catch(() => {})
},
},
}
</script>

View File

@ -152,7 +152,6 @@ import {
CircleCheck as ElIconCircleCheck,
CirclePlus as ElIconCirclePlus,
} from '@element-plus/icons'
import { $on, $off, $once, $emit } from '../../utils/gogocodeTransfer'
import WxNews from '@/views/mp/components/wx-news/main.vue'
import WxVoicePlayer from '@/views/mp/components/wx-voice-play/main.vue'
import WxVideoPlayer from '@/views/mp/components/wx-video-play/main.vue'

View File

@ -0,0 +1,22 @@
export default {
fans: {
index: 'index',
importwxAccountFansTip: 'import WxAccountFans',
id: 'id',
openid: 'openid',
subscribeStatus: 'subscribeStatus',
subscribeTime: 'subscribeTime',
nickname: 'nickname',
gender: 'gender',
language: 'language',
country: 'country',
province: 'province',
city: 'city',
tagIds: 'tagIds',
headimgUrl: 'headimgUrl',
remark: 'remark',
wxAccountId: 'wxAccountId',
wxAccountName: 'wxAccountName',
wxAccountAppid: 'wxAccountAppid'
}
}

View File

@ -0,0 +1,22 @@
export default {
fans: {
index: '序号',
importwxAccountFansTip: '导入微信公众号粉丝表',
id: '主键',
openid: '用户标识',
subscribeStatus: '订阅状态',
subscribeTime: '订阅时间',
nickname: '昵称',
gender: '性别',
language: '语言',
country: '国家',
province: '省份',
city: '城市',
tagIds: '分组ID',
headimgUrl: ' headimgUrl',
remark: '备注',
wxAccountId: '微信公众号ID',
wxAccountName: '微信公众号',
wxAccountAppid: '公众号appid'
}
}

View File

@ -0,0 +1,170 @@
<template>
<div class="layout-padding">
<el-card class="layout-padding-auto">
<el-row v-show="showSearch" class="mb8">
<el-form ref="queryRef" :inline="true" :model="state.queryForm" @keyup.enter="getDataList">
<el-form-item :label="$t('fans.nickname')" prop="nickname">
<el-input v-model="state.queryForm.nickname"
style="max-width: 180px"/>
</el-form-item>
<el-form-item :label="$t('fans.wxAccountName')" prop="wxAccountAppid">
<el-select v-model="state.queryForm.wxAccountAppid" :placeholder="$t('fans.wxAccountName')" clearable class="w100">
<el-option v-for="item in accountList" :key="item.appid" :label="item.name" :value="item.appid"/>
</el-select>
</el-form-item>
<el-form-item class="ml2">
<el-button formDialogRef icon="search" type="primary" @click="getDataList">
{{ $t('common.queryBtn') }}
</el-button>
<el-button formDialogRef icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }}</el-button>
<el-button formDialogRef icon="Sort" @click="asyncFans" v-auth="'mp_wxaccountfans_sync'">同步</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="mb8" style="width: 100%">
<el-button v-auth="'mp_fans_export'" class="ml10" formDialogRef icon="Download" type="primary"
@click="exportExcel">
{{ $t('common.exportBtn') }}
</el-button>
<el-button v-auth="'mp_fans_del'" :disabled="multiple" class="ml10" formDialogRef icon="Delete"
type="primary" @click="handleDelete(selectObjs)">
{{ $t('common.delBtn') }}
</el-button>
<right-toolbar v-model:showSearch="showSearch" class="ml10" style="float: right;margin-right: 20px"
@queryTable="getDataList"></right-toolbar>
</div>
</el-row>
<el-table v-loading="state.loading" :data="state.dataList" style="width: 100%"
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
<el-table-column align="center" type="selection" width="60"/>
<el-table-column :label="t('fans.index')" type="index" width="80"/>
<el-table-column :label="t('fans.id')" prop="id" show-overflow-tooltip/>
<el-table-column :label="t('fans.openid')" prop="openid" show-overflow-tooltip/>
<el-table-column :label="t('fans.subscribeStatus')" prop="subscribeStatus" show-overflow-tooltip/>
<el-table-column :label="t('fans.subscribeTime')" prop="subscribeTime" show-overflow-tooltip/>
<el-table-column :label="t('fans.nickname')" prop="nickname" show-overflow-tooltip/>
<el-table-column :label="t('fans.gender')" prop="gender" show-overflow-tooltip/>
<el-table-column :label="t('fans.language')" prop="language" show-overflow-tooltip/>
<el-table-column :label="t('fans.tagIds')" prop="tagIds" show-overflow-tooltip/>
<el-table-column :label="t('fans.remark')" prop="remark" show-overflow-tooltip/>
<el-table-column :label="t('fans.wxAccountName')" prop="wxAccountName" show-overflow-tooltip/>
<el-table-column :label="$t('common.action')" width="150">
<template #default="scope">
<el-button v-auth="'mp_fans_edit'" text type="primary"
@click="formDialogRef.openDialog(scope.row.id)">{{ $t('common.editBtn') }}
</el-button>
<el-button v-auth="'sys_fans_del'" text type="primary" @click="handleDelete([scope.row.id])">{{
$t('common.delBtn')
}}
</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle"/>
</el-card>
</div>
</template>
<script lang="ts" name="systemWxAccountFans" setup>
import {BasicTableProps, useTable} from "/@/hooks/table";
import {delObjs, fetchList, sync} from "/@/api/mp/wx-account-fans";
import { fetchAccountList } from '/@/api/mp/wx-account'
import {useMessage, useMessageBox} from "/@/hooks/message";
import {useI18n} from "vue-i18n";
//
const {t} = useI18n()
//
//
const formDialogRef = ref()
//
const queryRef = ref()
const showSearch = ref(true)
//
const selectObjs = ref([]) as any
const multiple = ref(true)
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {},
pageList: fetchList,
createdIsNeed: false
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
downBlobFile
} = useTable(state)
const accountList = ref([])
const getAccountList = () => {
fetchAccountList().then(res => {
accountList.value = res.data
if(accountList.value.length > 0){
state.queryForm.wxAccountAppid = accountList.value[0].appid
getDataList()
}
})
}
watch(() => state.queryForm.wxAccountAppid,() => {
getDataList()
})
const asyncFans = () => {
if(state.queryForm.wxAccountAppid){
sync(state.queryForm.wxAccountAppid).then(() => {
useMessage().success("已开始从微信同步粉丝信息,建议等待后查询")
getDataList()
})
}else{
useMessage().error("请选择公众号")
}
}
onMounted(() => {
getAccountList()
})
//
const resetQuery = () => {
//
queryRef.value.resetFields()
//
selectObjs.value = []
getDataList()
}
// excel
const exportExcel = () => {
downBlobFile('/mp/fans/export', state.queryForm, 'fans.xlsx')
}
//
const handleSelectionChange = (objs: any) => {
objs.forEach((val: any) => {
selectObjs.value.push(val.id)
});
multiple.value = !objs.length
}
//
const handleDelete = (ids: string[]) => {
useMessageBox().confirm(t('common.delConfirmText'))
.then(() => {
delObjs(ids).then(() => {
getDataList(false);
useMessage().success(t('common.delSuccessText'));
}).catch((err: any) => {
useMessage().error(err.msg)
})
})
};
</script>

View File

@ -0,0 +1,161 @@
<template>
<el-drawer v-model="visible" :title="form.id ? $t('common.editBtn') : $t('common.addBtn')" size="50%">
<el-form ref="dataFormRef" v-loading="loading" :model="form" :rules="dataRules" formDialogRef label-width="90px">
<el-row :gutter="24">
<el-col :span="24" class="mb20">
<el-form-item :label="t('account.name')" prop="name">
<el-input v-model="form.name" :placeholder="t('account.inputNameTip')"/>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item :label="t('account.account')" prop="account">
<el-input v-model="form.account" :placeholder="t('account.inputAccountTip')"/>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item :label="t('account.appid')" prop="appid">
<el-input v-model="form.appid" :placeholder="t('account.inputAppidTip')"/>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item :label="t('account.appsecret')" prop="appsecret">
<el-input v-model="form.appsecret" :placeholder="t('account.inputAppsecretTip')"/>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item :label="t('account.url')" prop="url">
<el-input v-model="form.url" :placeholder="t('account.inputUrlTip')"/>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item :label="t('account.token')" prop="token">
<el-input v-model="form.token" :placeholder="t('account.inputTokenTip')"/>
</el-form-item>
</el-col>
<el-col :span="24" class="mb20">
<el-form-item :label="t('account.aeskey')" prop="aeskey">
<el-input v-model="form.aeskey" :placeholder="t('account.inputAeskeyTip')"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">{{ $t('common.cancelButtonText') }}</el-button>
<el-button type="primary" @click="onSubmit">{{ $t('common.confirmButtonText') }}</el-button>
</span>
</template>
</el-drawer>
</template>
<script lang="ts" name="WxAccountDialog" setup>
// /
import {useMessage} from "/@/hooks/message";
import {addObj, getObj, putObj} from '/@/api/mp/wx-account'
import {useI18n} from "vue-i18n"
const emit = defineEmits(['refresh']);
const {t} = useI18n();
//
const dataFormRef = ref();
const visible = ref(false)
const loading = ref(false)
//
//
const form = reactive({
id: '',
name: '',
account: '',
appid: '',
appsecret: '',
url: '',
token: '',
aeskey: ''
});
//
const dataRules = ref({
name: [{required: true, message: '名称不能为空', trigger: 'blur'}],
account: [{required: true, message: '微信号不能为空', trigger: 'blur'}],
appid: [{required: true, message: 'appid不能为空', trigger: 'blur'}],
appsecret: [{required: true, message: '密钥不能为空', trigger: 'blur'}],
url: [{required: true, message: 'url不能为空', trigger: 'blur'}],
token: [{required: true, message: 'token不能为空', trigger: 'blur'}],
aeskey: [{required: true, message: '加密密钥不能为空', trigger: 'blur'}]
})
//
const openDialog = (id: string) => {
visible.value = true
form.id = ''
//
if (dataFormRef.value) {
dataFormRef.value.resetFields()
}
// wxAccount
if (id) {
form.id = id
getwxAccountData(id)
}
};
//
const onSubmit = () => {
dataFormRef.value.validate((valid: boolean) => {
if (!valid) {
return false
}
//
if (form.id) {
loading.value = true
putObj(form).then(() => {
useMessage().success(t('common.editSuccessText'))
visible.value = false //
emit('refresh')
}).catch((err: any) => {
useMessage().error(err.msg)
}).finally(() => {
loading.value = false
})
} else {
loading.value = true
addObj(form).then(() => {
useMessage().success(t('common.addSuccessText'))
visible.value = false //
emit('refresh')
}).catch((err: any) => {
useMessage().error(err.msg)
}).finally(() => {
loading.value = false
})
}
})
}
//
const getwxAccountData = (id: string) => {
//
loading.value = true
getObj(id).then((res: any) => {
Object.assign(form, res.data)
}).finally(() => {
loading.value = false
})
};
//
defineExpose({
openDialog
});
</script>

View File

@ -0,0 +1,24 @@
export default {
account: {
index: 'index',
importwxAccountTip: 'import WxAccount',
id: 'id',
name: 'name',
account: 'account',
appid: 'appid',
appsecret: 'appsecret',
url: 'url',
token: 'token',
aeskey: 'aeskey',
qrUrl: 'qrUrl',
inputIdTip: 'input id',
inputNameTip: 'input name',
inputAccountTip: 'input account',
inputAppidTip: 'input appid',
inputAppsecretTip: 'input appsecret',
inputUrlTip: 'input url',
inputTokenTip: 'input token',
inputAeskeyTip: 'input aeskey',
inputQrUrlTip: 'input qrUrl',
}
}

View File

@ -0,0 +1,24 @@
export default {
account: {
index: '序号',
importwxAccountTip: '导入公众号账户表',
id: '主键',
name: '名称',
account: '微信号',
appid: 'appid',
appsecret: '密钥',
url: ' url',
token: 'token',
aeskey: '加密密钥',
qrUrl: '图片',
inputIdTip: '请输入主键',
inputNameTip: '请输入名称',
inputAccountTip: '请输入微信号',
inputAppidTip: '请输入appid',
inputAppsecretTip: '请输入密钥',
inputUrlTip: '请输入 url',
inputTokenTip: '请输入token',
inputAeskeyTip: '请输入加密密钥',
inputQrUrlTip: '请输入图片',
}
}

View File

@ -0,0 +1,140 @@
<template>
<div class="layout-padding">
<el-card class="layout-padding-auto">
<el-row v-show="showSearch" class="mb8">
<el-form ref="queryRef" :inline="true" :model="state.queryForm">
<el-form-item :label="$t('account.name')" prop="name">
<el-input v-model="state.queryForm.name" :placeholder="t('account.inputNameTip')"
style="max-width: 180px"/>
</el-form-item>
<el-form-item :label="$t('account.account')" prop="account">
<el-input v-model="state.queryForm.account" :placeholder="t('account.inputAccountTip')"
style="max-width: 180px"/>
</el-form-item>
<el-form-item class="ml2">
<el-button formDialogRef icon="search" type="primary" @click="getDataList">
{{ $t('common.queryBtn') }}
</el-button>
<el-button formDialogRef icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }}</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="mb8" style="width: 100%">
<el-button v-auth="'mp_wxaccount_add'" class="ml10" formDialogRef icon="folder-add" type="primary"
@click="formDialogRef.openDialog()">
{{ $t('common.addBtn') }}
</el-button>
<el-button v-auth="'mp_wxaccount_export'" class="ml10" formDialogRef icon="Download" type="primary"
@click="exportExcel">
{{ $t('common.exportBtn') }}
</el-button>
<el-button v-auth="'mp_wxaccount_del'" :disabled="multiple" class="ml10" formDialogRef icon="Delete"
type="primary" @click="handleDelete(selectObjs)">
{{ $t('common.delBtn') }}
</el-button>
<right-toolbar v-model:showSearch="showSearch" class="ml10" style="float: right;margin-right: 20px"
@queryTable="getDataList"></right-toolbar>
</div>
</el-row>
<el-table v-loading="state.loading" :data="state.dataList" style="width: 100%"
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
<el-table-column align="center" type="selection" width="60"/>
<el-table-column :label="t('account.index')" type="index" width="80"/>
<el-table-column :label="t('account.name')" prop="name" show-overflow-tooltip/>
<el-table-column :label="t('account.account')" prop="account" show-overflow-tooltip/>
<el-table-column :label="t('account.appid')" prop="appid" show-overflow-tooltip/>
<el-table-column :label="t('account.appsecret')" prop="appsecret" show-overflow-tooltip/>
<el-table-column :label="t('account.url')" prop="url" show-overflow-tooltip/>
<el-table-column :label="t('account.token')" prop="token" show-overflow-tooltip/>
<el-table-column :label="t('account.aeskey')" prop="aeskey" show-overflow-tooltip/>
<el-table-column :label="t('account.qrUrl')" prop="qrUrl" show-overflow-tooltip/>
<el-table-column :label="$t('common.action')" width="150">
<template #default="scope">
<el-button v-auth="'mp_wxaccount_edit'" text type="primary"
@click="formDialogRef.openDialog(scope.row.id)">{{ $t('common.editBtn') }}
</el-button>
<el-button v-auth="'mp_wxaccount_del'" text type="primary" @click="handleDelete([scope.row.id])">{{
$t('common.delBtn')
}}
</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle"/>
</el-card>
<!-- 编辑新增 -->
<form-dialog ref="formDialogRef" @refresh="getDataList(false)"/>
</div>
</template>
<script lang="ts" name="systemWxAccount" setup>
import {BasicTableProps, useTable} from "/@/hooks/table";
import {delObjs, fetchList} from "/@/api/mp/wx-account";
import {useMessage, useMessageBox} from "/@/hooks/message";
import {useI18n} from "vue-i18n";
//
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
const {t} = useI18n()
//
//
const formDialogRef = ref()
//
const queryRef = ref()
const showSearch = ref(true)
//
const selectObjs = ref([]) as any
const multiple = ref(true)
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {},
pageList: fetchList
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
downBlobFile
} = useTable(state)
//
const resetQuery = () => {
//
queryRef.value.resetFields()
//
selectObjs.value = []
getDataList()
}
// excel
const exportExcel = () => {
downBlobFile('/pigx/account/export', state.queryForm, 'account.xlsx')
}
//
const handleSelectionChange = (objs: any) => {
objs.forEach((val: any) => {
selectObjs.value.push(val.id)
});
multiple.value = !objs.length
}
//
const handleDelete = (ids: string[]) => {
useMessageBox().confirm(t('common.delConfirmText'))
.then(() => {
delObjs(ids).then(() => {
getDataList(false);
useMessage().success(t('common.delSuccessText'));
}).catch((err: any) => {
useMessage().error(err.msg)
})
})
};
</script>

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,7 +1,5 @@
<template>
<div class="app-container">
<doc-alert title="公众号菜单" url="https://doc.iocoder.cn/mp/menu/" />
<!-- 搜索工作栏 -->
<el-form
ref="queryForm"
@ -249,18 +247,11 @@
</template>
<script>
import {
Plus as ElIconPlus,
CircleCheck as ElIconCircleCheck,
Search as ElIconSearch,
Refresh as ElIconRefresh,
Delete as ElIconDelete,
} from '@element-plus/icons'
import WxReplySelect from '@/views/mp/components/wx-reply/main.vue'
import WxNews from '@/views/mp/components/wx-news/main.vue'
import WxMaterialSelect from '@/views/mp/components/wx-material-select/main.vue'
import { deleteMenu, getMenuList, saveMenu } from '@/api/mp/menu'
import { getSimpleAccounts } from '@/api/mp/account'
// import WxReplySelect from '/@/views/mp/components/wx-reply/main.vue'
import WxNews from '/@/views/mp/components/wx-news/main.vue'
// import WxMaterialSelect from '/@/views/mp/components/wx-material-select/main.vue'
import { deleteMenu, getMenuList, saveObj } from '/@/api/mp/wx-menu'
import { getSimpleAccounts } from '/@/api/mp/wx-account'
export default {
data() {
@ -412,12 +403,6 @@ export default {
...item,
}
if (item.type === 'click' || item.type === 'scancode_waitmsg') {
delete menu
delete menu
delete menu
delete menu
delete menu
delete menu
menu.reply = {
type: item.replyMessageType,
accountId: item.accountId,
@ -508,14 +493,6 @@ export default {
// name
if (!item.children || item.children.length <= 0) {
item['children'] = []
delete item
delete item
delete item
delete item
delete item
delete item
delete item
delete item
//
this.showConfigureContent = false
}
@ -566,7 +543,7 @@ export default {
.confirm('确定要保证并发布该菜单吗?')
.then(() => {
this.loading = true
return saveMenu(this.accountId, this.convertMenuFormList())
return saveObj(this.accountId, this.convertMenuFormList())
})
.then(() => {
this.getList()