|
|
@@ -315,6 +315,8 @@
|
|
|
<el-button v-if="scope.row.userType !== '00'" size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['company:user:edit']">修改</el-button>
|
|
|
<el-button v-if="scope.row.userType !== '00'" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['company:user:remove']">删除</el-button>
|
|
|
<el-button size="mini" type="text" icon="el-icon-key" @click="handleResetPwd(scope.row)" v-hasPermi="['company:user:resetPwd']">重置密码</el-button>
|
|
|
+ <el-button size="mini" type="text" icon="el-icon-bell" @click="handleWxMpSubscribe(scope.row)">通知订阅</el-button>
|
|
|
+ <el-button size="mini" type="text" icon="el-icon-s-promotion" @click="handleWxMpPush(scope.row)">推送消息</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
@@ -856,6 +858,50 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-drawer>
|
|
|
+
|
|
|
+ <!-- 通知订阅二维码弹窗 -->
|
|
|
+ <el-dialog title="微信通知订阅" :visible.sync="subscribeDialogVisible" width="400px" :before-close="handleSubscribeDialogClose" center>
|
|
|
+ <div v-if="subscribeLoading" style="text-align: center; padding: 20px;">
|
|
|
+ <i class="el-icon-loading" style="font-size: 32px;"></i>
|
|
|
+ <p>正在生成二维码...</p>
|
|
|
+ </div>
|
|
|
+ <div v-else-if="subscribeQrCodeUrl" style="text-align: center;">
|
|
|
+ <p style="margin-bottom: 10px; color: #606266;">请员工使用微信扫描以下二维码</p>
|
|
|
+ <p style="margin-bottom: 10px; font-size: 12px; color: #909399;">扫描后关注公众号,即可绑定通知服务</p>
|
|
|
+ <img :src="subscribeQrCodeUrl" style="width: 260px; height: 260px; border: 1px solid #ebeef5; border-radius: 4px;" />
|
|
|
+ <div style="margin-top: 15px;">
|
|
|
+ <el-tag v-if="subscribeStatus && subscribeStatus.bound" type="success">已绑定公众号</el-tag>
|
|
|
+ <el-tag v-else-if="subscribeStatus && !subscribeStatus.bound" type="info">等待扫码关注</el-tag>
|
|
|
+ <el-tag v-if="subscribeStatus && subscribeStatus.mpSubscribed === 1" type="success" style="margin-left: 5px;">已订阅通知</el-tag>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-else style="text-align: center; padding: 20px; color: #f56c6c;">
|
|
|
+ <p>二维码生成失败,请重试</p>
|
|
|
+ </div>
|
|
|
+ <span slot="footer" class="dialog-footer">
|
|
|
+ <el-button size="small" @click="handleSubscribeDialogClose">关 闭</el-button>
|
|
|
+ <el-button size="small" type="primary" @click="refreshSubscribeStatus" :loading="subscribeStatusLoading">刷新状态</el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 推送订阅消息对话框 -->
|
|
|
+ <el-dialog title="推送订阅消息" :visible.sync="pushDialogVisible" width="400px" center>
|
|
|
+ <el-form ref="pushForm" :model="pushForm" :rules="pushRules" label-width="80px">
|
|
|
+ <el-form-item label="员工">
|
|
|
+ <span>{{ pushForm.nickName }}</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="消息类型">
|
|
|
+ <el-tag size="small">个微AI转人工</el-tag>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="客户姓名" prop="customerName">
|
|
|
+ <el-input v-model="pushForm.customerName" placeholder="请输入客户姓名" maxlength="20"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <span slot="footer" class="dialog-footer">
|
|
|
+ <el-button size="small" @click="pushDialogVisible = false">取 消</el-button>
|
|
|
+ <el-button size="small" type="primary" @click="submitPushMessage" :loading="pushLoading">推 送</el-button>
|
|
|
+ </span>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -882,6 +928,8 @@ import {
|
|
|
analyseCompanyUserInfo
|
|
|
} from "@/api/company/companyUser";
|
|
|
import { getToken } from "@/utils/auth";
|
|
|
+import { generateSubscribeQrcode, getSubscribeStatus, pushSubscribeMessage } from "@/api/wechat";
|
|
|
+import { getTenantCode } from "@/utils/auth";
|
|
|
import { treeselect } from "@/api/company/companyDept";
|
|
|
import Treeselect from "@riophae/vue-treeselect";
|
|
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
|
|
@@ -902,6 +950,19 @@ export default {
|
|
|
components: {selectDoctor, Treeselect ,selectUser, AiSipCallUser, VoiceCollectDialog},
|
|
|
data() {
|
|
|
return {
|
|
|
+ // 微信通知订阅相关
|
|
|
+ subscribeDialogVisible: false,
|
|
|
+ subscribeLoading: false,
|
|
|
+ subscribeStatusLoading: false,
|
|
|
+ subscribeQrCodeUrl: null,
|
|
|
+ subscribeCurrentUserId: null,
|
|
|
+ subscribeStatus: null,
|
|
|
+ subscribeTimer: null,
|
|
|
+ // 推送订阅消息相关
|
|
|
+ pushDialogVisible: false,
|
|
|
+ pushLoading: false,
|
|
|
+ pushForm: { userId: null, nickName: '', customerName: '', type: '个微AI转人工' },
|
|
|
+ pushRules: { customerName: [{ required: true, message: '请输入客户姓名', trigger: 'blur' }] },
|
|
|
doctor: {
|
|
|
open: false,
|
|
|
title: '绑定医生'
|
|
|
@@ -1505,6 +1566,139 @@ export default {
|
|
|
.catch(() => {
|
|
|
});
|
|
|
},
|
|
|
+ /** 微信通知订阅 */
|
|
|
+ handleWxMpSubscribe(row) {
|
|
|
+ this.subscribeCurrentUserId = row.userId;
|
|
|
+ this.subscribeDialogVisible = true;
|
|
|
+ this.subscribeLoading = true;
|
|
|
+ this.subscribeQrCodeUrl = null;
|
|
|
+ this.subscribeStatus = null;
|
|
|
+ var tenantCode = getTenantCode();
|
|
|
+ // 先查询当前订阅状态
|
|
|
+ getSubscribeStatus(row.userId, tenantCode).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.subscribeStatus = res.data;
|
|
|
+ if (res.data && res.data.bound && res.data.mpSubscribed === 1) {
|
|
|
+ this.subscribeLoading = false;
|
|
|
+ this.subscribeQrCodeUrl = null;
|
|
|
+ this.$message.success('该员工已订阅通知');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 未绑定或未订阅,生成二维码
|
|
|
+ this.loadSubscribeQrCode(row.userId, tenantCode);
|
|
|
+ }).catch(() => {
|
|
|
+ this.loadSubscribeQrCode(row.userId, tenantCode);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ loadSubscribeQrCode(userId, tenantCode) {
|
|
|
+ this.subscribeLoading = true;
|
|
|
+ generateSubscribeQrcode(userId, tenantCode).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.subscribeQrCodeUrl = res.data;
|
|
|
+ this.subscribeLoading = false;
|
|
|
+ // 开始轮询绑定状态
|
|
|
+ this.startSubscribePolling(userId, tenantCode);
|
|
|
+ } else {
|
|
|
+ this.$message.error('生成二维码失败:' + res.msg);
|
|
|
+ this.subscribeLoading = false;
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+ this.$message.error('生成二维码失败');
|
|
|
+ this.subscribeLoading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ startSubscribePolling(userId, tenantCode) {
|
|
|
+ // 清除旧的轮询
|
|
|
+ if (this.subscribeTimer) {
|
|
|
+ clearInterval(this.subscribeTimer);
|
|
|
+ }
|
|
|
+ // 每5秒轮询一次绑定状态
|
|
|
+ this.subscribeTimer = setInterval(() => {
|
|
|
+ getSubscribeStatus(userId, tenantCode).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.subscribeStatus = res.data;
|
|
|
+ // 如果已绑定且已订阅,停止轮询
|
|
|
+ if (res.data && res.data.bound && res.data.mpSubscribed === 1) {
|
|
|
+ this.stopSubscribePolling();
|
|
|
+ this.$message.success('员工已成功订阅通知');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).catch(() => {});
|
|
|
+ }, 5000);
|
|
|
+ },
|
|
|
+ stopSubscribePolling() {
|
|
|
+ if (this.subscribeTimer) {
|
|
|
+ clearInterval(this.subscribeTimer);
|
|
|
+ this.subscribeTimer = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ refreshSubscribeStatus() {
|
|
|
+ if (!this.subscribeCurrentUserId) return;
|
|
|
+ this.subscribeStatusLoading = true;
|
|
|
+ var tenantCode = getTenantCode();
|
|
|
+ getSubscribeStatus(this.subscribeCurrentUserId, tenantCode).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.subscribeStatus = res.data;
|
|
|
+ if (res.data && res.data.bound && res.data.mpSubscribed === 1) {
|
|
|
+ this.$message.success('员工已成功订阅通知');
|
|
|
+ this.stopSubscribePolling();
|
|
|
+ } else {
|
|
|
+ this.$message.info('当前状态:' + (res.data.bound ? '已绑定公众号' : '未绑定'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ this.$message.error('查询状态失败');
|
|
|
+ }).finally(() => {
|
|
|
+ this.subscribeStatusLoading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ handleSubscribeDialogClose() {
|
|
|
+ this.stopSubscribePolling();
|
|
|
+ this.subscribeDialogVisible = false;
|
|
|
+ this.subscribeQrCodeUrl = null;
|
|
|
+ this.subscribeCurrentUserId = null;
|
|
|
+ this.subscribeStatus = null;
|
|
|
+ },
|
|
|
+ /** 推送订阅消息 */
|
|
|
+ handleWxMpPush(row) {
|
|
|
+ this.pushForm = {
|
|
|
+ userId: row.userId,
|
|
|
+ nickName: row.nickName || row.userName,
|
|
|
+ customerName: '',
|
|
|
+ type: '个微AI转人工'
|
|
|
+ };
|
|
|
+ this.pushDialogVisible = true;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.pushForm) {
|
|
|
+ this.$refs.pushForm.clearValidate();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ /** 提交推送消息 */
|
|
|
+ submitPushMessage() {
|
|
|
+ this.$refs.pushForm.validate(valid => {
|
|
|
+ if (!valid) return;
|
|
|
+ this.pushLoading = true;
|
|
|
+ var tenantCode = getTenantCode();
|
|
|
+ pushSubscribeMessage({
|
|
|
+ userId: this.pushForm.userId,
|
|
|
+ customerName: this.pushForm.customerName,
|
|
|
+ type: this.pushForm.type
|
|
|
+ }, tenantCode).then(res => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.$message.success(res.msg || '推送成功');
|
|
|
+ this.pushDialogVisible = false;
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg || '推送失败');
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ this.$message.error('推送请求失败');
|
|
|
+ }).finally(() => {
|
|
|
+ this.pushLoading = false;
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
/** 提交按钮 */
|
|
|
submitForm: function() {
|
|
|
|