开发之前一定要作的几点
1.添加浙里办钉钉对接群 群号 34143965(有什么不定的地方就大胆问群里的几个负责人)
2.问钉钉群里面得的老师要开发流程相关文件 和开发注意事项(浙里办适老化 对ui有一定要求,要支持正常模式和适老化模式切换功能,所以得有两套ui。)
3.叫业主部门将IRS-应用发布子系统开一个账号给前端(给你注册一个浙政钉账号,属于业主政府部门下面),业主是irs主系统,开发商是子系统。
4.如果需要单点登录(一般都要)的话就要 在业主的irs系统 http://irs.zj.gov.cn/workbench/myresource/applicationsystem 上提交获取用户信息的工单
这时候要看你开发的h5是针对这里办 法人用户 还是 个人用户 申请对应的工单就行。这一步是要业主去操作(内网系统)。
5下载这里办专用的开发测试工具(测试你开发的软件,该环境有一些api可供使用,需要使用你的浙政钉账号登录,然后使用 浙里办app 手机和电脑处于同一个局域网 扫码进行腰马合一测试) Windows版本https://gov-bus.oss-cn-hangzhou.aliyuncs.com/upload/MVPBuilder/ZWEuropeSetup.exehttps://gov-bus.oss-cn-hangzhou.aliyuncs.com/upload/MVPBuilder/ZWEuropeSetup.exe
6.在准备工作时就可以先进行代码开发(代码开发完成后再进行上线的相关配置)
7.一定要在 IRS-应用发布子系统 上开发,不要用政务中台,那个已经弃用了,到时候没人给你上线。
准备工作完成
开发正式开始
1.引入JSBridge
在浙里办的微应用中,很多地方需要使用到浙里办的一些封装API功能,也就是JSBridge,且所有JSBridgeAPI均支持Promise回调
在public/index.html中引入
在App.vue中进行全局初始化
onLaunch: function() {
console.log('App Launch')
ZWJSBridge.onReady(() => {
console.log('初始化完成后,执行bridge方法')
})
},
这样就可以使用这里办的一些api了,这些api只有在这里办专用的开发测试工具上和正式/测试环境才能使用
2.环境要求
开发商工作台支持基于类React语法的 Rax应用 和 自定义 两种方式完成应用代码开发。
我用的是vue(也就是自定义开发)
由于浙里办的微应用是必须前后端分离,且前端文件需要部署到浙里办服务器上的,所以需要前端项目支持 rpm run build 命令,所以不能使用 Hbuilder X直接构建项目,需要如下命令构建
如果你是使用Hbuilder X编辑则需要在命令行创建应用
// 安装脚手架
npm install -g @vue/cli
// 新建项目
vue create -p dcloudio/uni-preset-vue 项目名字
3.更改打包目录
由于浙里办编译默认输出位置是build,但是uniapp的构建命令默认输出位置是dist;所以修改uniapp的构建命令输出位置,将pakeage.json中的scripts属性
UNI_OUTPUT_DIR='build'
由于前端项目部署在浙里办服务器上,所以还需要对manifest.json文件进行如下修改
"h5" : {
"publicPath" : "./",
"router" : {
"mode" : "hash",
"base" : "./"
}
}
由于浙里办微应用需要对支付宝浙里办小程序与浙里办APP进行双端适配,而不同环境下的单点登录跳转链接也不同,所以需要进行应用环境的检测
1.判断当前是 浙里办App还是 支付宝浙里办小程序 从而进行不同的回调地址 登录
这里面的接入码是上面 准备工作4 提到的单点登录工单返回材料
AKey是接入码
SKey是接入密码
这里只用到了AKey
单点登录工单可以看我另一篇文章(等我更新)
回调地址是要业主在IRS上创建应用 并且上传代码后才能有
如果需要可看我另外一篇文章https://blog.csdn.net/qq_44766377/article/details/123481066https://blog.csdn.net/qq_44766377/article/details/123481066
isLoad: () => {
if (bIsAlipayMini) {
window.location.href = "https://puser.zjzwfw.gov.cn/sso/alipay.do?action=ssoLogin&servicecode=接入代码&goto=附带跳转地址,以sp参数返回";
} else {
window.location.href = "https://puser.zjzwfw.gov.cn/sso/mobile.do?action=oauth&scope=1&servicecode=接入代码&goto=附带跳转地址,以sp参数返回";
}
}
我这里面的接入码和回调地址已经做过处理,没用的只是演示一下
回调地址 第二个https就是每个应用唯一的回调地址 分为测试地址和正式地址 正式地址上线的时候要改为正式的
当你的应用版本发生变化或者变更到正式环境,就需要更改 代码里面的回调地址 和 服务器端的回调地址 两个地方的回调要统一才能正常访问
服务端回调地址更改找钉钉群里面的 人修改
isLoad(){
console.log('跳转了',this.bIsAlipayMini)
if (this.bIsAlipayMini) {
window.location.href = "https://puser.zjzwfw.gov.cn/sso/alipay.do?action=ssoLogin&servicecode=99227ff499aa260aee23788b7522073f&goto=https://mapi.zjzwfw.gov.cn/web/mgop/gov-open/zj/12345689/reserved/index.html";
} else {
window.location.href = "https://puser.zjzwfw.gov.cn/sso/mobile.do?action=oauth&scope=1&servicecode=99227ff499aa260aee23788b7522073f&goto=https://mapi.zjzwfw.gov.cn/web/mgop/gov-open/zj/123456789/reserved/index.html";
}
},
2.解决二次回退问题
// 浙里办APP判断页面进入状态
watchApp(){
window.onpageshow = (event) => {
if (event.persisted || (window.performance && window.performance.navigation.type == 2)) {
ZWJSBridge.close();
}
this.isLoad();
}
},
// 支付宝浙里办小程序判断页面进入状态
watchApply(){
window.onpageshow = (event) => {
if (event.persisted || (window.performance && (window.performance.navigation.type == 1 || window.performance.navigation.type == 0))) {
this.isLoad();
} else {
my.navigateBack();
}
}
},
3.获取回调后的ticket参数
getQuery(name){
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
let r = window.location.search.substr(1).match(reg);
if (r != null){
console.log('ticket',r)
return unescape(r[2]);
}
return null;
},
4.调用上边的方法 先获取到当前设备处于什么运行平台(支付宝 / 浙里办)然后再去判断是否处于登录状态 执行 第三步是否返回参数 如果没有登录就 执行登录 第一步 登录
登陆后会再次执行一次 init这个方法,这是候我们已经拿到 ticket参数了 所以就进入 第二步 解决回退
这就是单点登录的基本过程
init(){
this.sUserAgent = window.navigator.userAgent.toLowerCase();
this.bIsDtDreamApp = this.sUserAgent.indexOf("dtdreamweb") > -1; // 浙里办APP
this.bIsAlipayMini = this.sUserAgent.indexOf('miniprogram') > -1 && this.sUserAgent.indexOf('alipay') > -1;
if (this.getQuery('ticket') == null && this.ticket == "") {
uni.showLoading({
title: '登录中',
mask: true
});
if (this.bIsAlipayMini) {
this.watchApply();
}else{
this.watchApp();
}
} else {
this.ticket = this.getQuery('ticket');
uni.reLaunch({
url: `./index?ticket=${this.ticket}`,
})
}
},
在获取用户信息之前还得先在IRS子系统上配置 RPC网关接口(这个接口适用于获取用户信息的)
api注册好之后我们就来调用
getTonkenAndUserInfo: (data) => {
return new Promise((resolve, reject) => {
that.$mgop({
api: '刚刚注册api的名字',
host: 'https://mapi.zjzwfw.gov.cn/', //固定地址
data: data,
dataType: 'JSON',
type: 'POST', //注册的方法
appKey: '8864654654dfskglk', //appKEY要到irs上查看 这里我乱写的
onSuccess: res => {
if (res.data.result && res.data.result == 0) {
resolve(res.data);
}
},
onFail: err => {
reject(err);
}
});
})
},
getTonkenAndUserInfoParams: (method = 'ticketValidation', token = '') => {
let mTime = that.$timeFormat(new Date(), 'yyyymmddhhMMss');
let data = {
method: method,
servicecode: '接入码', //就是上边提到的AKey
time: mTime, //时间
sign: md5Libs.md5(`接入码接入密码${mTime}`), //接入码和接入密码不用分隔开 (这里是要用到md5加密)
datatype: 'json'
}
if (token == '') {
data.st = that.ticket;
} else {
data.token = token;
}
return data;
},
时间格式化方法我是单独放一个js文件,注册到全局(这个方法要多次使用)
// 时间格式化
export const timeFormat = (dateTime = null, fmt = 'yyyy-mm-dd') => {
// 如果为null,则格式化当前时间
if (!dateTime) dateTime = Number(new Date());
// 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式
if (dateTime.toString().length == 10) dateTime *= 1000;
let date = new Date(dateTime);
let ret;
let opt = {
"y+": date.getFullYear().toString(), // 年
"m+": (date.getMonth() + 1).toString(), // 月
"d+": date.getDate().toString(), // 日
"h+": date.getHours().toString(), // 时
"M+": date.getMinutes().toString(), // 分
"s+": date.getSeconds().toString() // 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
};
for (let k in opt) {
ret = new RegExp("(" + k + ")").exec(fmt);
if (ret) {
fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
};
};
return fmt;
}
调用获取信息方法
这里面包括了一点埋点的代码
this.getTonkenAndUserInfo(this.getTonkenAndUserInfoParams()).then(data => {
return that.getTonkenAndUserInfo(that.getTonkenAndUserInfoParams('getUserInfo', data.token));
}).then(data => {
console.info(data);
that.userInfo = data;
// 保存到vuex
this.$store.state.userinfo.name = data.username
this.$store.state.userinfo.userId = data.userid
this.$store.state.userinfo.mobile = data.mobile
console.log('用户信息',data)
// 通过自带的api来获取埋点信息
ZWJSBridge.getUserType({}).then(res => {
that.userType = res.userType
ZWJSBridge.getLocation({}).then(res => {
that.longitude = res.longitude
that.latitude = res.latitude
that.aplus()
}).catch(err => {
console.log('获取用户定错误',err)
})
}).catch(err => {
console.log('获取用户类型错误',err)
})
}).catch(err => {
console.log(err);
});
},
还有一件事就是在你这个项目的所有接口都得通过这个网关,所以除了和这个获取用户信息接口,其他的接口都得自己注册上去
这个可以叫后台小伙伴去弄,因为后台可能比较熟悉
设置完成API以后,点击上线即可在前端使用网关API进行调用。上线后如需修改,点击升级即可重新编辑。
使用注册的接口
npm i --save @aligov/[email protected]
引入
import { mgop } from '@aligov/jssdk-mgop';
我这里是在main.js中注册了全局pai
// 引用安装网关依赖
import { mgop } from '@aligov/jssdk-mgop';
Vue.prototype.$mgop = mgop
使用(get和post没啥大区别)
post
this.$mgop({
api: 'mgop.stsc.yff.merchangAddCS', //IRS上注册的api名称
host: 'https://mapi.zjzwfw.gov.cn/', //固定地址
data: this.information, //你要传递的参数
dataType: 'JSON',
type: 'POST', //方法
appKey: '7gdfsdfgsdopc', //appkey
onSuccess: res => {
uni.showToast({
title: '提交成功',
duration: 500
});
},
onFail: err => {
console.log(res)
}
});
},
get
this.$mgop({
api: 'mgop.stsc.yff.merchantTypesCS', //api名称
host: 'https://mapi.zjzwfw.gov.cn/', //固定地址
data: {}, //参数 没有就不传
dataType: 'JSON',
type: 'GET', //方法
appKey: '7gsdaadgc', // appkey
onSuccess: res => {
})
},
onFail: err => {
console.log(res)
}
});
首先在public/index.html中引入埋点的api脚本,为防止出现https://https://这种双协议头调用,除脚本自身外,还需先填写基础PV日志的埋点函数,如果不需要单点登录采集用户数据则不需要最后的BLOCK,其他均为固定值,照抄就行。
页面PV日志采集,aplus函数在取得用户经纬度、用户数据、用户类型等数据后再进行调用。如没有单点登录获取用户数据,则仅需要留’aplus.sendPV’这一个。
aplus(){
console.log('埋点执行')
console.log('longitude',that.longitude)
console.log('latitude',that.latitude)
console.log('userType',that.userType)
aplus_queue.push({
'action': 'aplus.sendPV',
'arguments': [{
is_auto: false
}, {
miniAppId: '54464624121', //appid
miniAppName: '项目名称', //项目的名称
long: that.longitude,
lati: that.latitude,
userType: that.userType,
}]
});
aplus_queue.push({
action: "aplus.setMetaInfo",
arguments: ["_user_nick", that.userInfo.username]
});
aplus_queue.push({
action: "aplus.setMetaInfo",
arguments: ["_user_id", that.userInfo.userid]
});
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['_hold', 'START']
});
console.log('埋点执行完成')
},
调用
调用之前得先采集一些数据这些数据就可以用JSBridge的api来获取
埋点的代码我是放在了成功获取到用户信息之后执行的(认真阅读的话,应该知道上面有提过)
// 通过自带的api来获取埋点信息
ZWJSBridge.getUserType({}).then(res => {
that.userType = res.userType
ZWJSBridge.getLocation({}).then(res => {
that.longitude = res.longitude
that.latitude = res.latitude
that.aplus()
}).catch(err => {
console.log('获取用户定错误',err)
})
}).catch(err => {
console.log('获取用户类型错误',err)
})
}).catch(err => {
console.log(err);
});
项目上线前必须将代码 直接弄为压缩包上传到开发商工作台
上传时要先将回调地址改为测试地址 改为测试的回调地址
测试地址获得方式
列如就是测试地址 将地址复制 拼接到回调地址后面
支付宝端地址
https://puser.zjzwfw.gov.cn/sso/alipay.do?action=ssoLogin&servicecode=AK(单点登录拿到的) &goto= 测试地址
这里办App地址
https://puser.zjzwfw.gov.cn/sso/mobile.do?action=oauth&scope=1&servicecode= AK(单点登录拿到的 &goto= 测试地址
改为
回调地址修改完成后 接下来 代码打包 不是 npm run build打包 是直接打包( node_modules不用打包 没用的文件也可以不用打包)
上传代码
点击更新代码 输入版本号 将压缩包拖入 点击提交
上传完成之后即可
通过 预览的二维码查看效果
上线之前得先准备材料这些个材料 模板的向钉钉群里的对接人员要(logo 二维码 自测录屏 代码 这几个是自己准备)
logo就是项目的logo要求是好像200kb以下
代码就是项目代码的压缩包(不要node-modules)
二维码是最终代码部署到IRS上后的那个二维码(到时候就知道了)
自测录屏,这里办app 支付宝这里办小程序 苹果和和安卓 共四个视频
找到 服务侧应用发布
点击提交审批
根据业务信息填写吧
再把文件提价上去
这个工单是要走流程的
如果某一个流程不过关,就要重新整改,必须在两天之内整改,否则就要重新上线
在代码配置完成后 总要测试一下的,这时候就要找到群里面的对接人找他配置回调地址。将AKey和SKey还有回调地址给他。这样以后你在IRS平台上传的代码就能够成功登录。
还有就是回调地分为测试地址和正式地址,上线前记得吧地址改为正式地址,代码和 叫对接人员都要改为正式地址。 再对接人员那,回调地址是可以多次修改的根据你的测试地址来修改 ,来不停的查看页面效果。
我知道的大概就这些。 心累。
最后感谢大佬