wjx 1 天之前
父节点
当前提交
2d1eb3d298
共有 3 个文件被更改,包括 325 次插入63 次删除
  1. 14 0
      src/api/accounts/corpWeChat.js
  2. 52 52
      src/views/accounts/corpWechat/index.vue
  3. 259 11
      src/views/accounts/corpWechat/modalCorp.vue

+ 14 - 0
src/api/accounts/corpWeChat.js

@@ -239,4 +239,18 @@ export function getProviderAuth(params) {
         method: 'GET',
         params
     })
+}
+
+
+/**
+ * 上传图片
+ * @param {filePrefix: corp_info/corp_icp/, suffix: jpg/png} params 
+ * @returns 
+ */
+export function uploadImageApi(params) {
+    return request({
+        url: '/corp/corp/media/formUpload',
+        method: 'GET',
+        params
+    })
 }

+ 52 - 52
src/views/accounts/corpWechat/index.vue

@@ -47,27 +47,24 @@
                 <div style="padding-top: 9px;font-size: 12px;margin-left: 5px">服务商(点击授权):</div>
             </el-col>
             <el-col :span="1.5" v-for="item in providerList" :key="item.id">
-                <el-button size="mini" @click="getCode(item.id)">{{ item.proxyName }}</el-button>
+                <el-button size="mini" @click="getCode(item.id)">{{ item.providerName }}</el-button>
             </el-col>
             <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
         </el-row>
 
         <el-table :data="corpList" v-loading="loading" size="mini">
-            <el-table-column label="企微名称" prop="corpName" width="150" align="center" fixed="left"
-                :show-overflow-tooltip="true" />
-            <el-table-column label="企微ID" prop="originCorpId" align="center" width="150" />
-            <el-table-column label="应用类型" prop="applicationType" align="center" width="150">
-
-                <template slot-scope="scope">{{ scope.row.applicationType | filterApplicationType }}</template>
+            <el-table-column label="企微名称" prop="corpName" width="200" fixed="left"
+                :show-overflow-tooltip="true">
+                <template slot-scope="scope">
+                    <div>{{scope.row.corpName}}</div>
+                    <div>{{scope.row.originCorpId}}</div>
+                </template>
             </el-table-column>
-            <el-table-column label="用户规模" prop="corpUserMax" align="center" width="100" />
             <el-table-column label="授权方企业类型" prop="corpType" align="center" width="150">
-
                 <template slot-scope="scope">{{ scope.row.corpType | filterCorpType }}</template>
             </el-table-column>
-            <el-table-column label="认证到期时间" prop="verifiedEndTime" align="center" width="120" />
+            <el-table-column label="认证到期时间" prop="verifiedEndTime" align="center" width="135" />
             <el-table-column label="授权状态" prop="authStatus" align="center" width="120">
-
                 <template slot-scope="scope">
                     <el-tag type="success" v-if="scope.row.authStatus === 1">成功授权</el-tag>
                     <el-tag type="danger" v-else>取消授权</el-tag>
@@ -80,56 +77,27 @@
                     <el-tag type="danger" v-else>配置失败</el-tag>
                 </template>
             </el-table-column>
-            <el-table-column label="回调地址" prop="externalUserCallbackUrl" width="200" :show-overflow-tooltip="true">
-                <template slot-scope="scope">
-                    <a style="color: #1890ff;" @click="copy(scope.row.externalUserCallbackUrl)">{{
-            scope.row.externalUserCallbackUrl }}</a>
-                </template>
-            </el-table-column>
-            <el-table-column label="Token" prop="externalUserToken" width="150" :show-overflow-tooltip="true">
-
-                <template slot-scope="scope">
-                    <a style="color: #1890ff;" @click="copy(scope.row.externalUserToken)">{{ scope.row.externalUserToken
-                        }}</a>
-                </template>
-            </el-table-column>
-            <el-table-column label="AESKey" prop="externalUserAesKey" width="150" :show-overflow-tooltip="true">
-
-                <template slot-scope="scope">
-                    <a style="color: #1890ff;" @click="copy(scope.row.externalUserAesKey)">{{
-            scope.row.externalUserAesKey
-        }}</a>
-                </template>
-            </el-table-column>
-            <el-table-column label="会话存档Secret" prop="msgAuditSecret" width="150" :show-overflow-tooltip="true">
-                <template slot-scope="scope">
-                    <div v-if="scope.row.msgAuditSecret">{{ scope.row.msgAuditSecret }}</div>
-                    <div v-else>--</div>
-                </template>
-            </el-table-column>
-            <el-table-column label="授权时间" prop="createTime" width="130" :show-overflow-tooltip="true" />
-            <el-table-column label="用户分组" prop="sysUserGroupList" width="150" :show-overflow-tooltip="true">
+            <el-table-column label="授权信息" prop="externalUserCallbackUrl" width="300" :show-overflow-tooltip="true">
                 <template slot-scope="scope">
-                    <div v-if="scope.row.sysUserGroupList"><span v-for="(item, index) in scope.row.sysUserGroupList"
-                            :key="item.id"><i v-if="index > 0">,</i>{{ item.groupName }}</span></div>
-                    <div v-else>--</div>
+                    <div class="table-row">回调地址:<a style="color: #1890ff;" v-if="scope.row.agentCallbackUrl" @click="copy(scope.row.externalUserCallbackUrl)">{{scope.row.agentCallbackUrl}}</a><span v-else>--</span></div>
+                    <div class="table-row">Token:<a style="color: #1890ff;" v-if="scope.row.token" @click="copy(scope.row.externalUserToken)">{{scope.row.token}}</a><span v-else>--</span></div>
+                    <div class="table-row">AESKey:<a style="color: #1890ff;" v-if="scope.row.encodingAesKey" @click="copy(scope.row.encodingAesKey)">{{scope.row.encodingAesKey}}</a><span v-else>--</span></div>
                 </template>
             </el-table-column>
+            <el-table-column label="授权时间" prop="createTime" width="135" :show-overflow-tooltip="true" />
             <el-table-column label="备注" prop="remark" width="250" :show-overflow-tooltip="true" />
             <el-table-column label="操作" width="200" class-name="small-padding fixed-width" fixed="right">
-
                 <template slot-scope="scope">
                     <div v-if="scope.row.authStatus === 1" class="czCell">
                         <el-button size="mini" type="text" icon="el-icon-edit"
                             @click="handleRefresh(scope.row)">修改</el-button>
-                        <el-button size="mini" type="text" icon="el-icon-setting"
+                        <!-- <el-button size="mini" type="text" icon="el-icon-setting"
                             @click="setSecretHandle(scope.row)">配置密钥</el-button>
                         <el-button size="mini" v-if="scope.row.corpId" type="text" icon="el-icon-setting"
-                            @click="setSessionHandle(scope.row)">配置会话存档</el-button>
+                            @click="setSessionHandle(scope.row)">配置会话存档</el-button> -->
                         <template v-if="scope.row.configStatus === 'SUCCESS'">
                             <el-dropdown style="margin-left: 7px;">
-                                <el-button class="el-dropdown-link" size="mini" type="text">更多<i
-                                        class="el-icon-arrow-down el-icon--right"></i></el-button>
+                                <el-button class="el-dropdown-link" size="mini" type="text">更多<i class="el-icon-arrow-down el-icon--right"></i></el-button>
                                 <el-dropdown-menu slot="dropdown">
                                     <el-dropdown-item><el-button size="mini" type="text" icon="el-icon-refresh"
                                             @click="handleSync(scope.row)">同步所有</el-button></el-dropdown-item>
@@ -231,11 +199,11 @@ export default {
     },
     methods: {
         getCode(id) {
-            getProviderAuth({ sysProxyId: id }).then(res => {
+            getProviderAuth({ providerId: id }).then(res => {
                 this.codeVisible = true
                 this.$nextTick(() => {
                     const canvas = this.$refs.qrcodeCanvas;
-                    QRCode.toCanvas(canvas, res.data.qrCodeURL, { width: 200 }, function (error) {
+                    QRCode.toCanvas(canvas, res.data, { width: 200 }, function (error) {
                         if (error) console.error('------->', error);
                         console.log('QR code generated successfully!');
                     });
@@ -319,9 +287,30 @@ export default {
             //     loading.close()
             //     this.getList()
             // }).catch(() => loading.close())
-            const { originCorpId, corpId, corpFullName, corpName } = row
+            const { originCorpId, corpId, corpFullName, corpName, bookAgentIdMap, bookAgentId, msgAuditSecret, msgAuditSeq, openAppId, openAppName, remark } = row
             this.corpVisible = true
-            this.corpData = { originCorpId, corpId, corpFullName, corpName }
+            
+            this.corpData = { 
+                originCorpId, 
+                corpId, 
+                corpFullName, 
+                corpName,
+                bookAgentIdMap: [],
+                bookAgentId,
+                msgAuditSecret,
+                msgAuditSeq,
+                openAppId,
+                openAppName,
+                remark
+            }
+            if (bookAgentIdMap && Object.keys(bookAgentIdMap).length > 0) {
+                this.corpData.bookAgentIdMap = Object.keys(bookAgentIdMap).map(key => {
+                    return {
+                        bookCityId: key,
+                        bookAgentId: bookAgentIdMap[key]
+                    }
+                })
+            }
             this.corpTitle = '修改企业'
         },
         /** 配置密钥 */
@@ -377,4 +366,15 @@ export default {
         margin-left: 0;
     }
 }
+.table-row {
+    display: flex;
+    
+    a {
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        display: inline-block;
+        flex: 1;
+    }
+}
 </style>

+ 259 - 11
src/views/accounts/corpWechat/modalCorp.vue

@@ -1,10 +1,9 @@
 <template>
     <div>
-        <el-dialog :title="modalTitle" :visible.sync="visible" width="500px" :before-close="onClose">
-            <el-form :model="queryParams" :rules="rules" ref="queryParamsCorpModify" label-position="left"
-                label-width="100px">
+        <el-dialog :title="modalTitle" :visible.sync="visible" width="600px" :before-close="onClose">
+            <el-form :model="queryParams" :rules="rules" ref="queryParamsCorpModify" label-position="top">
                 <el-form-item label="企业ID" prop="originCorpId">
-                    <el-input v-model="queryParams.originCorpId" placeholder="请输入企业ID" clearable size="small" />
+                    <el-input v-model="queryParams.originCorpId" :disabled="!!queryParams.corpId" placeholder="请输入企业ID" clearable size="small" />
                 </el-form-item>
                 <el-form-item label="企业简称" prop="corpName">
                     <el-input v-model="queryParams.corpName" placeholder="请输入企业简称" clearable size="small" />
@@ -12,6 +11,92 @@
                 <el-form-item label="企业全称" prop="corpFullName">
                     <el-input v-model="queryParams.corpFullName" placeholder="请输入企业全称" clearable size="small" />
                 </el-form-item>
+                <template v-if="queryParams.corpId">
+                    <!-- 修改 -->
+                    <el-form-item label="当前在投的书城企微应用ID" prop="bookAgentId">
+                        <el-input v-model="queryParams.bookAgentId" placeholder="请输入当前在投的书城企微应用ID" clearable size="small" oninput="value=value.replace(/[^\d]/g,'')" />
+                    </el-form-item>
+                    <el-form-item label="书城企微应用ID">
+                        <el-form :model="item" :rules="rulesBookCityType" ref="bookCityType" label-width="80px" label-position="top"
+                            v-for="(item, index) in queryParams.bookAgentIdMap" :key="index">
+                            <el-row :gutter="20">
+                                <el-col :span="8">
+                                    <el-form-item label="书城" prop="bookCityId">
+                                        <el-select v-model="item.bookCityId" size="small" placeholder="选择书城" filterable clearable>
+                                            <el-option v-for="item in bookCity" :disabled="item.disabled" :key="item.id"
+                                                :label="item.platformName" :value="item.platformKey" />
+                                        </el-select>
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="12">
+                                    <el-form-item label="书城应用ID" prop="bookAgentId">
+                                        <el-input v-model.number="item.bookAgentId" placeholder="请输入书城应用ID" clearable
+                                            size="small" />
+                                    </el-form-item>
+                                </el-col>
+                                <el-col :span="2">
+                                    <div style="margin-top: 42px">
+                                        <el-button @click.prevent="removeResource(index)" type="text" icon="el-icon-delete"
+                                            style="color: red; margin-left: 10px"></el-button>
+                                    </div>
+                                </el-col>
+                            </el-row>
+                        </el-form>
+                        <el-button type="text" icon="el-icon-plus" @click="addResource">新增书城</el-button>
+                    </el-form-item>
+                    <el-form-item label="会话存档密钥" prop="msgAuditSecret">
+                        <el-input v-model="queryParams.msgAuditSecret" placeholder="请输入会话存档密钥" clearable size="small" />
+                    </el-form-item>
+                    <el-form-item label="会话存档Seq" prop="msgAuditSeq">
+                        <el-input v-model="queryParams.msgAuditSeq" placeholder="请输入会话存档Seq" clearable size="small" />
+                    </el-form-item>
+                    <el-form-item label="开放平台绑定的小程序/公众号名字" prop="openAppName">
+                        <el-input v-model="queryParams.openAppName" placeholder="请输入开放平台绑定的小程序/公众号的AppId" clearable size="small" />
+                    </el-form-item>
+                    <el-form-item label="开放平台绑定的小程序/公众号的AppId" prop="openAppId">
+                        <el-input v-model="queryParams.openAppId" placeholder="请输入开放平台绑定的小程序/公众号的AppId" clearable size="small" />
+                    </el-form-item>
+                </template>
+                <template v-else>
+                    <el-form-item label="应用类型" prop="authType">
+                        <el-radio-group v-model="queryParams.authType">
+                            <el-radio label="SELF_BUILT">自建应用</el-radio>
+                            <el-radio label="INTERNAL">内部应用</el-radio>
+                            <el-radio label="AUTH_PROVIDER">服务商代开发应用</el-radio>
+                        </el-radio-group>
+                    </el-form-item>
+                    <el-form-item label="应用ID" prop="agentId">
+                        <el-input v-model="queryParams.agentId" placeholder="请输入应用ID" clearable size="small" oninput="value=value.replace(/[^\d]/g,'')" />
+                    </el-form-item>
+                    <el-form-item label="应用密钥" prop="agentSecret">
+                        <el-input v-model="queryParams.agentSecret" placeholder="请输入应用密钥" clearable size="small" />
+                    </el-form-item>
+                    <template v-if="queryParams.authType === 'SELF_BUILT'">
+                        <el-form-item label="企微请求代理地址" prop="proxyUrl">
+                            <el-input v-model="queryParams.proxyUrl" placeholder="请输入企微请求代理地址" clearable size="small" />
+                        </el-form-item>
+                        <el-form-item label="备案的域名" prop="domain">
+                            <el-input v-model="queryParams.domain" placeholder="请输入备案的域名" clearable size="small" />
+                        </el-form-item>
+                        <el-form-item label="域名备案查询截图" prop="domainBeianImgUrl">
+                            <el-upload
+                                class="avatar-uploader"
+                                action=""
+                                :show-file-list="false"
+                                :http-request="handleUpload"
+                                :before-upload="beforeUpload"
+                                accept="image/jpeg,image/png,image/jpg"
+                            >
+                                <img v-if="queryParams.domainBeianImgUrl" :src="queryParams.domainBeianImgUrl" class="avatar">
+                                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+                            </el-upload>
+                        </el-form-item>
+                    </template>
+                </template>
+                
+                <el-form-item label="企业备注" prop="remark">
+                    <el-input v-model="queryParams.remark" placeholder="请输入企业备注" clearable size="small" />
+                </el-form-item>
             </el-form>
             <span slot="footer" class="dialog-footer">
                 <el-button @click="onClose()">取 消</el-button>
@@ -22,14 +107,31 @@
 </template>
 
 <script>
-import { addCorpApi, editCorpApi } from "@/api/accounts/corpWeChat";
+import { addCorpApi, editCorpApi, uploadImageApi } from "@/api/accounts/corpWeChat";
+import axios from 'axios';
+import { getBookPlatInfoAll } from "@/api/accounts/bookCity";
 export default {
     data() {
         return {
             queryParams: {
                 corpFullName: null,
                 corpName: null,
-                originCorpId: null
+                originCorpId: null,
+                authType: 'SELF_BUILT',
+                agentId: null,
+                agentSecret: null,
+                proxyUrl: null,
+                domain: null,
+                domainBeianImgUrl: null,
+                remark: null
+            },
+            rulesBookCityType: {
+                bookCityId: [
+                    { required: true, message: '请选择书城', trigger: 'change' }
+                ],
+                bookAgentId: [
+                    { required: true, message: '请输入书城应用ID', trigger: 'change' }
+                ]
             },
             rules: {
                 corpFullName: [
@@ -40,9 +142,20 @@ export default {
                 ],
                 corpName: [
                     { required: true, message: '请输入企业简称', trigger: 'blur' }
+                ],
+                authType: [
+                    { required: true, message: '请选择应用类型', trigger: 'blur' }
+                ],
+                agentId: [
+                    { required: true, message: '请输入应用ID', trigger: 'blur' }
+                ],
+                agentSecret: [
+                    { required: true, message: '请输入应用密钥', trigger: 'blur' }
                 ]
             },
-            loading: false
+            loading: false,
+            bookCity: [],
+            bookCityCS: [],
         }
     },
     props: {
@@ -64,18 +177,66 @@ export default {
             handler(val) {
                 if (val && Object.keys(val).length > 0) {
                     this.queryParams = val
+                    this.queryParams.bookAgentIdMap = val.bookAgentIdMap || []
                 } else {
                     this.queryParams = {
                         corpFullName: null,
                         corpName: null,
-                        originCorpId: null
+                        originCorpId: null,
+                        authType: 'SELF_BUILT',
+                        agentId: null,
+                        agentSecret: null,
+                        proxyUrl: null,
+                        domain: null,
+                        domainBeianImgUrl: null,
+                        remark: null
                     }
                 }
             },
             immediate: true,
         },
+        'queryParams.bookAgentIdMap': {
+            handler(val) {
+                if (val && val.length > 0) {
+                    let data = this.bookCityCS.map(item => {
+                        if (val.some(i => i.bookCityId === item.platformKey)) {
+                            return { ...item, disabled: true }
+                        }
+                        return { ...item, disabled: false }
+                    })
+                    this.bookCity = data
+                } else {
+                    this.bookCity = this.bookCityCS
+                }
+            },
+            deep: true,
+            immediate: false,
+        }
+    },
+    created() {
+        this.getAllData()
     },
     methods: {
+        /** 新增用户 */
+        addResource() {
+            let oldData = JSON.parse(JSON.stringify(this.queryParams.bookAgentIdMap))
+            oldData.push({
+                bookCityId: null,
+                bookAgentId: null
+            })
+            this.queryParams.bookAgentIdMap = oldData
+        },
+         /** 删除用户 */
+        removeResource(index) {
+            this.queryParams.bookAgentIdMap.splice(index, 1)
+        },
+        getAllData() {
+            // 获取所有书城
+            getBookPlatInfoAll().then(res => {
+                this.bookCity = res.data
+                this.bookCityCS = res.data
+            })
+        },
         onClose() {
             this.$emit("onClose");
         },
@@ -85,9 +246,23 @@ export default {
                     this.loading = true
                     let data = null
                     if (this.modifyData && this.modifyData.corpId) {
-                        data = await editCorpApi({ ...this.queryParams, corpId: this.modifyData.corpId })
+                        let params = JSON.parse(JSON.stringify(this.queryParams))
+                        // 新增应用时,bookAgentIdMap 为空
+                        if (params.bookAgentIdMap && params.bookAgentIdMap.length > 0) {
+                            
+                            let bookAgentIdMap = {}
+                            params.bookAgentIdMap.forEach(item => {
+                                bookAgentIdMap[item.bookCityId] = item.bookAgentId
+                            })
+                            params.bookAgentIdMap = bookAgentIdMap
+                        }
+                        data = await editCorpApi({ ...params, corpId: this.modifyData.corpId }).catch(err => {
+                            this.loading = false
+                        })
                     } else {
-                        data = await addCorpApi(this.queryParams)
+                        data = await addCorpApi(this.queryParams).catch(err => {
+                            this.loading = false
+                        })
                     }
 
                     this.loading = false
@@ -102,7 +277,80 @@ export default {
                 }
             })
         },
+        async handleUpload(option) {
+            const file = option.file;
+            const suffix = file.name.substring(file.name.lastIndexOf('.') + 1);
+            try {
+                const res = await uploadImageApi({ filePrefix: 'corp_info/corp_icp/', suffix: 'image/' + suffix });
+                if (res.code === 200 && res.data) {
+                    const data = res.data;
+                    const formData = new FormData();
+                    
+                    for (let key in data) {
+                        if (key !== 'host' && key !== 'ossUrl' && key !== 'domain') {
+                            formData.append(key, data[key]);
+                        }
+                    }
+                    formData.append('file', file);
+                    
+                    const uploadUrl = data.ossUrl;
+                    
+                    const uploadRes = await axios.post(uploadUrl, formData, {
+                        headers: { 'Content-Type': 'multipart/form-data' }
+                    });
+                    // Depending on what is returned by the OSS or common upload
+                    if (uploadRes.data.data) {
+                        this.queryParams.domainBeianImgUrl = uploadRes.data.data;
+                        this.$message.success('上传成功');
+                    } else {
+                        this.$message.error('上传失败');
+                    }
+                } else {
+                    this.$message.error(res.msg || '获取上传凭证失败');
+                }
+            } catch (error) {
+                console.error(error);
+                this.$message.error('上传失败');
+            }
+        },
+        beforeUpload(file) {
+            const isImage = file.type.indexOf("image/") !== -1;
+            if (!isImage) {
+                this.$message.error("文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件。");
+            }
+            const isLt10M = file.size / 1024 / 1024 < 10;
+            if (!isLt10M) {
+                this.$message.error("上传图片大小不能超过 10MB!");
+            }
+            return isImage && isLt10M;
+        }
 
     }
 }
-</script>
+</script>
+
+<style scoped>
+.avatar-uploader ::v-deep .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+}
+.avatar-uploader ::v-deep .el-upload:hover {
+    border-color: #409EFF;
+}
+.avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+}
+.avatar {
+    width: 100px;
+    height: 100px;
+    display: block;
+}
+</style>