这个项目折磨了我挺长时间的,主要卡在上架浙里办的流程上,(网上也看了很多文章,但有的点地方还是解决不了,只能一步一坑的走啦)所以就记录一下吧。
说一下需要注意的点吧(其实也就那么三四点,相信你已经搜过很多文章了):
这埋点咋说呢,就按照这里提供的文档赋值粘贴过来就行了,替换一下你的项目名称和项目Apppid就好了。如果项目没有特定的需求,把基础埋点埋好就行了。
首先在入口文件index.html放入采集的SDK:
<script type="text/javascript" src="https://d.alicdn.com/alilog/mlog/aplus.js?id=202951085"></script>
//这个是引用浙里办提供的api ,注意版本是1.1.0的,注意更新。网上很多文章都是老文章了,都是1.0.1的。
<script type="text/javascript" src="https://assets.zjzwfw.gov.cn/assets/ZWJSBridge/1.1.0/zwjsbridge.js"></script>
然后把基础的埋点放到script中
<script>
//这个是调用浙里办的zwjsbridge.js api 先初始化
ZWJSBridge.onReady(() => {
console.log('初始化完成后,执行bridge方法',ZWJSBridge)
})
(function(w, d, s, q, i) {
w[q] = w[q] || [];
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s);
j.async = true;
j.id = "beacon-aplus";
j.src = "https://d.alicdn.com/alilog/mlog/aplus.js?id=202951085";
f.parentNode.insertBefore(j, f);
})(window, document, "script", "aplus_queue");
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['aplus-waiting', 'MAN']
});
aplus_queue.push({
action: "aplus.setMetaInfo",
arguments: ["aplus-rhost-v", "alog.zjzwfw.gov.cn"],
});
aplus_queue.push({
action: "aplus.setMetaInfo",
arguments: ["aplus-rhost-g", "alog.zjzwfw.gov.cn"],
});
aplus_queue.push({
action: "aplus.setMetaInfo",
arguments: ["appId", "60506758"],
});
aplus_queue.push({
action: "aplus.sendPV",
arguments: [
{ is_auto: false },
{
miniAppId: "20202xxxxxx",
miniAppName: "这里是你项目名",
},
],
});
</script>
就上面这一段就完成埋点任务了,如果需要采集用户信息的话,就在那个页面埋点:
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['_hold', 'BLOCK']
});
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['_user_nick', this.userName] //这个是用户名称的埋点
});
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['_user_id', this.userId] //这个是用户Id的埋点
});
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['_hold', 'START']
});
//说明一下:单页应用的 sendPV 调用需要置于 _hold:BLOCK 和 _hold:START 配置之间。
//就是说你要埋的点需要在BLOCK和START之间执行 先埋BLOCK 后埋START
//上面只是个示例,需要埋什么点,就在LOCK和START 之间埋就行
如何查看是否埋点成功,看控制台或者提供项目ID给对接群里的老师帮忙查看(这里说一下,做浙里办项目都需要去对接的,有问题就问里面老师就完了,别不好意思)

zwjsbridge.js的引用和初始化上面已经说了,因为像上传照片视频(上传到浙里办的服务器上)、跳转外部链接,需要用到他们提供的api,当然了,上传照片也可以喊自己家的后台写一个。不过直接用现成的不香嘛 。下面的照片就是部分的api。完整的api在提供的文档里。这里说一下调试,有些调试需要在浙里办提供的Debug工具上测试,这个到时候去对接群里下载,群文件都有。(用钉钉去搜群号添加,我在的3群人还没满,钉钉号(31419900)你们加的时候不知道有没有满,不过也不用担心,到时候业主提供的浙政钉的文件上都会有每个群的群号,自己去挨个加)

我觉得适老化是最简单的了吧。可以喊自己项目组的经理喊UI做两套图,自己照着画就好了,不然就是自己排版一下适老化版本的布局,需要自己去考虑一下,会花一点点时间(如果项目的页面比较多的话)。
<div :class="[$store.state.style + '-page']">
xxxx
xxxx
</div>
这里的$store.state.style就是走登录接口后使用ZWJSBridge.getUiStyle({}) 获取ui环境存全局,这项用vue2写的(用vuex存储)
ZWJSBridge.getUiStyle({}).then((result) => {
console.log('获取系统UI环境',result);
// result: {uiStyle: "normal"}
// result: {uiStyle: "elder"} //是适老化版本就是elder 正常版就是normal
this.$store.commit('getStyle',result.uiStyle)
}).catch((error) => {
});
接口数据的请求也是需要走浙里办那边的提供的rpc接口。这个就需要后端到浙里办开发商工作台配置了,前端就不用管了,负责走接口就完事了(这一步是直接借用了这位朋友的(乐语_miss))
首先呢需要安装一个依赖
npm i @aligov/jssdk-mgop --save
然后在request.js中操作:
import { mgop } from '@aligov/jssdk-mgop'
const mgopRequest = (payload) => {
return new Promise((resolve, reject) => {
// 仿照axios的传参方式
const data = Object.assign({}, {
api: payload.zwApi, // 必须,政务中台rpc接口的制定名字。例如‘mgop.xxx.app.login’
// host: 'https://mapi.zjzwfw.gov.cn/',// 固定为这个地址
dataType: 'JSON', // 目前官方只支持JSON格式
Headers: {
"Content-Type": "text/html;charset=utf-8"
},
data: payload.data, // 不管入参是query还是body都统一用data传入,到时候在工作台里配置即可
type: 'POST', // 和axios一样
// isBuffer: payload.isBuffer,
appKey: 'xxxxxxxxxxxxxxxxxx', // 必须,政务中台appKey, 系统申请之后大数据局发过来的excel里有
// 成功后的回调
onSuccess: data => {
// console.log(data.data)
resolve(data.data)
},
// 请求失败后的回调
onFail: err => {
console.log(err, 'err')
reject(err)
}
},
)
mgop(data)
})
}
export default {
mgopRequest
}
在api.js中走接口:
import api from "@/utils/request.js"
export function listApi(query) {
const data = {
//接口名称 这里就是后端在开发工作台配置好的接口,复制过来就ok,也可以叫后端的好朋友整理成文档给你
//这样方便,不然开发商工作台登录只能喊业主帮忙扫码进去,多累啊
zwApi: "mgop.xxxx.xxxx.xxxxx",
data: query
};
return api.mgopRequest(data)
}
在页面的使用:
import { listApi } from "@/api";
<script>
export default {
data(){
return{
params:{
content:'',
page:1,
}
}
},
created(){
this.getList()
},
methods:{
getList(){
listApi(this.params).then(res =>{
if (res.result) {
xxxx //请求成功后的操作
} else {
xxxx //请求失败后的操作
}
})
},
},
}
</script>
单点登录呢,如果不清楚流程可能会比较麻烦。但清楚也是很简单滴。
首页,进入浙里办环境后会先判断你是否处于登录状态,不是的话会跳到浙里办登录页,这里统一走他们的登录接口。已登录状态下直接跳项目首页里,这里呢,我需要一个过度页来处理登录过程。你也可以直接跳首页,但直接跳首页会导致你的首页会刷新两次,可能体验不是很好。所以需要一个过渡页,也就是空白页,在空白页进行登录的操作的时候,给个加载的loading,成功后再跳首页,这样会比较好。当然,这只是我自己个人的体验啦。具体看甲方的需求。具体代码:
过渡页(blank.vue)中:
<template>
<div></div>
</template>
<script>
import { ticketValidation,getPersonInfo,weChatTicket } from "@/api";
export default {
data() {
return {
bIsDtDreamApp :null,
bIsAlipayMini :null,
weChartApply :null,
};
},
created(){
let sUserAgent = window.navigator.userAgent.toLowerCase();
this.bIsDtDreamApp = sUserAgent.indexOf("dtdreamweb") > -1; // 浙里办APP
this.bIsAlipayMini = sUserAgent.indexOf('miniprogram') > -1 && sUserAgent.indexOf('alipay') > -1; //支付宝小程序
this.weChartApply = sUserAgent.indexOf('micromessenger') > -1 //微信小程序
//判断是否为第一次进入空白页,存储在全局alreadyLogin为true的话 就是说明不是第一次进入,反之则是第一次进入空白页 这个关于到二次回退的问题
if(this.$store.state.alreadyLogin){
ZWJSBridge.close() //不是第一次进入该页面则执行关闭操作回退到浙里办上。
}else{
this.getUrl() //第一次进入该页面,执行该方法
}
},
methods: {
getUrl(){
// 判断是否为有票据
if (!window.location.href.includes('ticket')) {
//判断环境
if (this.bIsAlipayMini) { //如果是在小程序环境下跳转下面的登录地址
window.location.replace("https://puser.zjzwfw.gov.cn/sso/alipay.do?action=ssoLogin&servicecode=xxxxxxx")
} else { //如果是在做这里版app环境下跳转下面的登录地址
window.location.replace("https://puser.zjzwfw.gov.cn/sso/mobile.do?action=oauth&scope=1&servicecode=xxxxxxxxx")
}
}else{ //有票据的情况下则是已登录过的,只要登录过,进入项目地址上都会有ticket票据,小程序的是ticketId
this.$store.commit('getLogin',true) //这个就是首次进入该页面后存储一个全局变量,以便于后面判断是否为第一次进改页面
if(this.weChartApply || this.bIsAlipayMini){ //然后执行 获取地址中的ticket或ticketId方法
this.getQuery('ticketId')
}else{
this.getQuery('ticket')
}
}
},
// 获取回调地址中的ticket
getQuery(sign){
var reg = new RegExp("(^|&)" + sign + "=([^&]*)(&|$)");
var search = window.location.href.substr(1).match(reg);
console.log('拿到了url',search);
console.log('拿到了url中的ticket',search[2]);
//拿到ticket或ticketId后,执行获取用户信息的接口(其实到这一步单点登录算是走完了)
//这边为什么还要判断呢,因为我们后端这边走app和小程序的登录分为两个接口,所以需要判断一下
//如果你的后端就只用一个接口就不用判断了,
if(this.weChartApply || this.bIsAlipayMini){ //所处环境
let sec = search[2].split('#')
this.getChatUserId(sec[0])
}else{
this.getUserId(search[2])
}
},
// 浙里办app获取用户信息
getUserId(ticket){
ticketValidation({st:ticket}).then(res =>{ //获取票证
console.log('票据信息',res);
this.getInfo(res)
})
},
// 小程序获取用户信息
getChatUserId(ticket){
weChatTicket({ticketId:ticket}).then(res =>{ //获取票证
this.getInfo(res)
})
},
getInfo(res){
if(res.result){
getPersonInfo({getUserId:res.data.user_id}).then(res =>{
this.$toast.loading({
message: "加载中...",
// forbidClick: true,
loadingType: "spinner",
duration: 0,
});
if(res.result){
window.sessionStorage.setItem("userInfo", JSON.stringify(res.data));
this.$router.push('/index')
ZWJSBridge.onReady(() => {
// 获取系统环境
ZWJSBridge.getUiStyle({}).then((result) => {
console.log('获取系统环境',result);
this.$store.commit('getStyle',result.uiStyle)
})
});
}else{
this.$router.go(-1)
}
this.$toast.clear();
})
}else{
this.$router.go(-1)
}
},
},
};
</script>
<style lang="less" scoped></style>
因为网上很多文章关于浙里办二次回退问题都是监听页面返回,然后根据判断来执行关闭操作的,相信大家也都看过。就是下面这个方法
window.addEventListener( "pageshow",function(){ xxxx },false)
但是呢,我这边使用这个监听方法,是没有作用的,就点返回按钮的时候function里的操作怎么都不执行。我也不知道是自己没用对呢,或者没监听到pageshow,还是其他啥问题,哈哈哈哈。所以只能想其他办法了。然后就想在单点登录走通后,使用vuex给存储一个全局变量,然后再回退到空白页时,根据存储的值来判断执行回退到浙里办上。
然后就是票据的问题,浙里办app上拿的是ticket,支付宝小程序正式环境下有ticket和ticketId,开发环境下是ticketId,微信小程序拿到的都是ticketId,所以小程序就可以统一都拿ticketId,这样比方便。并且支付宝小程序和微信小程序在开发阶段,项目没有正式上线前,进入小程序里的个人信息都是默认的debug_user_name名称。这是正常的,项目上线后就会拿到个人的真实信息。
好像就想到这了,上述如有不对或不足之处,欢迎大家批评指正。如有其他疑惑之处也可私我
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
我正在使用Postgres.app在OSX(10.8.3)上。我已经修改了我的PATH,以便应用程序的bin文件夹位于所有其他文件夹之前。Rammy:~phrogz$whichpg_config/Applications/Postgres.app/Contents/MacOS/bin/pg_config我已经安装了rvm并且可以毫无错误地安装pggem,但是当我需要它时我得到一个错误:Rammy:~phrogz$gem-v1.8.25Rammy:~phrogz$geminstallpgFetching:pg-0.15.1.gem(100%)Buildingnativeextension
前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我
我在我的rails应用程序中安装了来自github.com的acts_as_versioned插件,但有一段代码我不完全理解,我希望有人能帮我解决这个问题class_eval我知道block内的方法(或任何它是什么)被定义为类内的实例方法,但我在插件的任何地方都找不到定义为常量的CLASS_METHODS,而且我也不确定是什么here,并且有问题的代码从lib/acts_as_versioned.rb的第199行开始。如果有人愿意告诉我这里的内幕,我将不胜感激。谢谢-C 最佳答案 这是一个异端。http://en.wikipedia
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?