/** * @Description: 将数据加密后存储到 sessionStorage * @Params: * - sessionStorageKey (String): 存储的键名 * - sessionStorageValue (Any): 需要加密存储的值 * @Return: void */ function setStorageEncryptData(sessionStorageKey, sessionStorageValue) { if (!sessionStorageKey || sessionStorageValue === undefined) { console.error("Invalid parameters for setStorageEncryptData"); return; } try { const encryptData = CryptoJS.AES.encrypt( JSON.stringify(sessionStorageValue), secretKey ).toString(); sessionStorage.setItem(sessionStorageKey, encryptData); } catch (error) { console.error("Error encrypting data:", error); } } var wx_code = "", ticket = "", //票据 accessToken = "", userInfo = {}, //用户信息 AppInfo = {}, //应用参数 deviceInfo = {}, //设备信息 errorCode = null, //错误码 responseText = "", //错误提示 rootDirLocation = ""; //本地文件路劲 // 1. 注册程序,获取设备信息等 /** * handleReady * @description wx.config => agentConfig 执行微信授权、注册应用 * @returns {返回类型} 返回描述 * @since 2023年10月11日 15:31:18 */ function handleReady() { const jsApiList = [ "IPW", "multiWindows_open", "multiWindows_close", "multiWindows_subscribe", "multiWindows_publish", "multiWindows_finish", "chooseImage", "scanQRCode", "hideOptionMenu", "shareWechatMessage", "shareAppMessage", "startAutoLBS", "stopAutoLBS", "onLocationChange", "onMenuShareAppMessage", "onMenuShareWechat", "previewFile", "openChatWithMsg", "ext_Database_Open", "ext_Database_Exec", "ext_Database_Query", "ext_Database_Close", "ext_ISCP_Init", "ext_ISCP_ConnectService", "ext_ISCP_RhConfig", "ext_ISCP_GetLocalPort", "ext_ISCP_RhConnectCtrl", "ext_ISCP_RhConnState", "ext_ISCP_RhLocalPortCtrl", "ext_ISCP_Close", "ext_ISCP_Status", "ext_screenControl_direction", "getLocation", "getZipAppDirectory", "multiWindows_open", "ext_DeviceInfo_GetInfo", "ext_DeviceInfo_version", "getAuthCode", "key", "setFloatWindow", //开启浮窗 "openChatWithMsg", //会话框 "shareAppMessage", //分享 "getZipAppDirectory", //获取h5包路径 "multiWindows_startWidget", //打开应用 2.0 "multiWindows_open", //打开窗口 2.0 'ext_FileManager_AppList',//获取应用缓存 'ext_Intent_Dial',//打电话 ] wx.config({ beta: true, // 调用wx.invoke形式的接口值时,该值必须为true。 debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: AppInfo.corpid, // 必填,政务微信的cropID timestamp: "1608692903", // 必填,生成签名的时间戳 nonceStr: "XKIvykvwOuAeIbl", // 必填,生成签名的随机串 signature: "ad0c077e6b5fbfe0c9e5394703d8262a3bc21fc3", // 必填,签名,见附录1 jsApiList, // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); return new Promise((resolve, reject) => { wx.ready(function () { console.log("准备:wx.config: ready"); wx.onHistoryBack(function (res) { return true; }); wx.invoke( "agentConfig", { agentid: AppInfo.agentid, // 必填,企业应用的agentid corpid: AppInfo.corpid, // 必填,企业微信的corpid timestamp: new Date().valueOf() / 1000, // 必填,生成签名的时间戳,int类型, 如 nonceStr: "", // 必填,生成签名的随机串 signature: "", // 必填,签名,见附录5 }, function (res) { if (res.err_msg != "agentConfig:ok") { responseText = res.err_msg || ""; return reject(4002); } wx.invoke("ext_DeviceInfo_GetInfo", { data: {} }, function (res) { if (res.err_msg === "ext_DeviceInfo_GetInfo:ok") { //成功处理 deviceInfo = { ...res }; sessionStorage.setItem("IPW_KEY", "939847C35AFF0A67"); } }); return resolve(); } ); window.uexOnload && window.uexOnload(0); }); }); } /** * getAuthCode * @desc 获取单点登录企业微信code * try catch 包裹, 如果新单点登录能获取wx_code 则使用新单点登录,否则使用URL参数获取 * @since 2023年09月27日 16:14:50 */ async function getAuthCode(variable) { try { // isAndroid() let code = await getAuthCodeNew(); return code; } catch (error) { console.log("单点登录失败,使用URL参数获取", error) } let query = window.location.search.substring(1); let vars = query.split("&"); console.log("单点登录获取code失败,使用微信跳转换取code", vars) for (let i = 0; i < vars.length; i++) { var pair = vars[i].split("="); if (pair[0] == variable) { return pair[1]; } } return ""; } /** * 获取i国网的code(授权码) 替换之前getWxCode()需要 重定向页面获取wx_code */ function getAuthCodeNew() { return new Promise((resolve, reject) => { wx.ready(function () { wx.invoke( "getAuthCode", { response_type: 'code', //固定值 scope: 'snsapi_base' //固定值 }, function (res) { if (res.err_msg === 'getAuthCode:ok') { wx_code = res.code; resolve(res.code) } else { reject(res) } } ); }); }); } function getWxCode() { let sURL = AppInfo.url_wxcode; sURL += "appid=" + AppInfo.corpid; sURL += "&redirect_uri=" + encodeURIComponent("zipapp://local.host/index.html"); sURL += "&response_type=code"; sURL += "&scope=SCOPE"; sURL += "&state=STATE"; sURL += "&agentid=" + AppInfo.agentid; sURL += "#wechat_redirect"; location.href = sURL; } /** * getIscPort * @desc 建立isc安全链接 * @returns {Promise} 安全链接端口号 * @since 2023年09月27日 16:34:55 */ function getIscPort() { return new Promise((resolve, reject) => { wx.invoke( "ext_ISCP_Init", { // 初始化交互安全平台 data: { iscpIP: AppInfo.iscpIP, }, }, function (res) { console.log("=======================建立安全链接", res); if (res.err_msg === "ext_ISCP_Init:ok") { var para = { ip: AppInfo.ip, //安全交互平台互联网ip,从对接方获取 port: AppInfo.iscpPort, //安全交互平台互联网port,从对接方获取 user: AppInfo.user, //当前登录用户id,可写死 appid: AppInfo.appId, //需要向安全交互平台申请 iscpIP: AppInfo.iscpIP, //链路唯一标识,自己生成(建议赋值为AgentID) }; wx.invoke( "ext_ISCP_ConnectService", { // 建立安全交互平台链接 data: para, }, function (res) { if (res.err_msg === "ext_ISCP_ConnectService:ok") { let _data = { ip: AppInfo.baseUrlIp, port: AppInfo.baseUrlPort, iscpIP: AppInfo.iscpIP, appid: AppInfo.appId, }; wx.invoke( "ext_ISCP_GetLocalPort", { // 转换端口 data: _data, }, function (res) { // '939847C35AFF0A67' if (res.err_msg === "ext_ISCP_GetLocalPort:ok") { AppInfo.result = res.result; sessionStorage.setItem("IPW_ISCP_PORT", AppInfo.result); // TyEvent4005.end(); console.log("=======ext_ISCP_GetLocalPort:ok", res); resolve(res.result); wx.invoke( "getZipAppDirectory", { type: "APP_ROOT_DIR", }, function (res) { console.log("getZipAppDirectory end", res); if (res.err_msg === "getZipAppDirectory:ok") { rootDirLocation = res.directory; sessionStorage.setItem( "ROOT_DIR_LOCATION", res.directory ); } else { console.log("getZipAppDirectory end 获取本地路径失败:", res) } } ); } else { responseText = JSON.stringify(res); reject(40055); } } ); } else { responseText = JSON.stringify(res); reject(4004); } } ); } else { responseText = JSON.stringify(res); reject(4003); } } ); }) } /** * getIscPortBefore * @desc 建立isc安全链接2 * @returns {Promise} 安全链接端口号2 * @since 2025年29月27日 16:34:55 */ function getIscPortBefore() { // 打印当前应用参数 console.log("开始建立安全链接AppInfo:", AppInfo); // 1. 获取 acl_id_list,优先取 AppInfo.aclIdList,否则默认 [1] const aclIdList = AppInfo.aclIdList || [1]; // 2. 获取 appId,agentid,iscpIP,iscpPort,ip,sport const appId = AppInfo.appId || "ipw"; const agentid = AppInfo.agentid; const iscpIP = AppInfo.iscpIP; const iscpPort = AppInfo.iscpPort; const ip = AppInfo.ip; const sport = AppInfo.iscpPort; // 3. 组装 businessServiceInfoList,每个 acl_id 对应一个 businessInfo const businessServiceInfoList = aclIdList.map(acl_id => ({ gateway_id: agentid, // 微应用唯一标识 acl_id, // 业务交互的id businessInfo: { sip: AppInfo.baseUrlIp, // 业务交互的ip 填 222.212.254.69? sport: AppInfo.baseUrlPort // 业务交互端口 填 20016? } })); // 4. 组装 gatewayServiceInfoList,包含所有 acl_id const gatewayServiceInfoList = [ { gatewayInfo: { ip: AppInfo.ip, // 安全接入网关ip地址 填: 222.212.254.69? port: AppInfo.iscpPort, // 安全接入网关端口 填 20016? resource: { acl_id_list: aclIdList, // 业务id集合 填 [1]? appId: appId // 资源名 填 "ipw"? }, type: 2 // 固定值 填2? // sslProfile 可选,后面动态添加 }, gateway_id: agentid // 微应用唯一标识 填 "ipw"? } ]; // 5. 如果 AppInfo.sslProfile 存在,添加到 gatewayInfo if (AppInfo.sslProfile) { gatewayServiceInfoList[0].gatewayInfo.sslProfile = AppInfo.sslProfile; } let dataParsms = { businessServiceInfoList: businessServiceInfoList, // 业务交互配置 gatewayServiceInfoList: gatewayServiceInfoList // 网关配置 } console.log("组装好的参数 dataParsms:", dataParsms); // 6. 调用微信接口建立安全链接 return new Promise((resolve, reject) => { wx.invoke( "ext_ISCP_RhConfig", { data: dataParsms // 传入组装好的参数 }, function (res) { // 打印返回结果 console.log("=======================融合版安全接入网关链接res", res); if (true) { //res.err_msg === "ext_ISCP_RhConfig:ok" // resolve(res.result); wx.invoke("ext_ISCP_RhConnectCtrl", { data: { "gatewayServiceId": agentid, "connCtrlType": 1 } }, function (res) { console.log("2ISCP 融合版 链接或断开 网关控制接口:", res); // res.err_msg === "ext_ISCP_RhConnectCtrl:ok" if (true) { // 成功处理 resolve(res.result); } else { responseText = JSON.stringify(res); reject(40056); } }); // 获取本地端口 // wx.invoke("ext_ISCP_RhLocalPortCtrl", { // data: { // "gatewayServiceId": 1, // "connCtrlType": "1" // } // }, function (res) { // console.log("22hLocalPort融合版安全接入网关链接成功Ctrl:", res); // resolve(res.result); // }) } else { responseText = JSON.stringify(res); console.log("融合版安全接入网关失败:", responseText); // reject(40057); } } ); }); } // 获取密钥信息 function getIsolationdmc() { return new Promise((resolve, reject) => { $.ajax({ type: "GET", url: "http://127.0.0.1:" + AppInfo.result + "/test.txt", success: function (res) { //更改路径之后接口返回的加密串末尾多了2个空格,导致无法解密,手动去掉 if (res) { var words = res.split(","); var myWords = mydecrypt(words[0], words[1].trim()); resolve(myWords); } else { responseText = JSON.stringify(res); reject(4006); } }, error: function (err) { console.log("生成秘钥失败:", err) responseText = JSON.stringify(err); reject(4006); }, }); }); } /** * handleLogin * @desc 用户单点登录 * 生产地址:https://id.sgcc.com.cn:10443/igwmobile/proxy/getUserByIgwCode * UAT地址:https://igw.isgcc.net:18443/proxy/getUserByIgwCode * @param {String} code - 第二部注册的code * @param {String} envType - 环境类型, prod 生产,uat 测试 * @returns {Promise} 用户信息加密串 * @since 2023年09月27日 16:42:56 */ function handleLogin(code, envType) { if (['production', 'uat'].indexOf(envType) === -1) return; // 执行登录 const URI_MAPPER = { production: 'https://id.sgcc.com.cn:10443/igwmobile/proxy/getUserByIgwCode', uat: 'https://igw.isgcc.net:18443/proxy/getUserByIgwCode' }; // 获取地址 const url = URI_MAPPER[envType]; return new Promise((resolve, reject) => { const data = { CODE: code, appId: AppInfo.agentid }; $.ajax({ type: 'POST', contentType: 'application/json;charset=UTF-8', //必须有 data: JSON.stringify(data), dataType: 'json', url: url, success: function (res) { const { code, message = '', data } = res; if (code === '100001') { // console.log('#IGW: handle-login ok : ', data); resolve(data); } else { console.log('#IGW: handle-login error : ', message); reject(3001); } }, error: function (err) { reject(3001); } }); }); } //通过安全交互平台认证之后调后端接口获取用户信息 function getUser() { if (!AppInfo.result) { alert("请先获取交互平台信息"); return; } var url = "http://127.0.0.1:" + AppInfo.result + "/igw-isc/isc/ipw"; return new Promise((resolve, reject) => { var params = { serviceTicket: "",//ticket 新版不传 nameCode: nameCode }; $.ajax({ type: "post", url: url, data: JSON.stringify(params), contentType: "application/json", dataType: "json", success: function (response) { console.log("getUser:", response) //token sessionStorage.setItem( "IPW_UC_TOKEN", response.data.ipwToken.resultValue.value ); // ! need delete //isc用户信息 setStorageEncryptData("IPW_ISC_ACCOUNTINFO_SECRET", response.data.iscInfo); sessionStorage.setItem( "IPW_ISC_ACCOUNTINFO", JSON.stringify(response.data.iscInfo) ); // TyEvent4007.end(); // TyEvenGetUserOther.end(); resolve({ userId: response.data.iscInfo.userId, account: response.data.iscInfo.account, }); }, error: function (response) { console.log("===============getUser response", response) let tempCode; if (response.responseJSON && response.responseJSON.code) { if (response.responseJSON.code === -1) { tempCode = 1001; response.responseText = "serviceTicket参数不能为空" } else { //3002 应该是response.responseJSON.code赋予的 tempCode = response.responseJSON.code; } // TyEvenGetUserOther.fail(); } else { // TyEvent4007.fail(); tempCode = 4007; //4007的响应体 特殊处理 responseText = JSON.stringify(response); reject(tempCode); } responseText = response.responseText ? response.responseText : response.status ? response.status : ""; reject(tempCode); }, }); }); } // 统一登录入口 async function onLogin(env) { //igw相关参数赋值 AppInfo = { agentid: env.VUE_APP_AGENTID, corpid: env.VUE_APP_CORPID, isc_appid: env.VUE_APP_ISCAPPID, isc_secret: env.VUE_APP_ISCSECRET, ip: env.VUE_APP_IP, iscpPort: env.VUE_APP_ISCPPORT, iscpIP: env.VUE_APP_TSCPIP, user: env.VUE_APP_USER, baseUrlIp: env.VUE_APP_BASEURLIP, baseUrlPort: env.VUE_APP_BASEURLPORT, appId: env.VUE_APP_APPID, url_wxcode: env.VUE_APP_URL_WXCODE, url_ticket: env.VUE_APP_URL_TICKET, url_accesstoken: env.VUE_APP_URL_ACCESSTOKEN, url_userinfo: env.VUE_APP_URL_USERINFO, result: "", url_serve_user: env.VUE_APP_SERVICE_USER }; return new Promise(async (resolve, reject) => { try { // 1. 注册程序,获取设备信息等 await handleReady(); // 2. 获取code wx_code = await getAuthCode("code"); if (wx_code) { // 3 .建立安全链接 await getIscPortBefore(); AppInfo.result = await getIscPort(); //获取密钥信息 const decryptedMq = await getIsolationdmc(); sessionStorage.setItem("YDZY_APP_ISOLATIONDMC", decryptedMq); //登录 获取加密信息 // userInfo = await getUser(); // 加密的用户信息 const encryptedUserInfo = await handleLogin(wx_code, env.NODE_ENV); resolve(encryptedUserInfo); } else { //获取wxcode getWxCode(); } } catch (error) { errorCode = error; reject(errorCode); } }); }