
交友软件包含聊天支付,会员系统,前后台管理
交友软件包含聊天支付,会员系统,动态,前后台管理一套出售,有需要的联系QQ728045048
交友软件包含聊天支付,会员系统,动态,前后台管理一套出售,有需要的联系QQ728045048

开源知识付费系统—— 万岳知识付费系统开源WEB+UNIAPP版

系统演示
目录结构
- 前端代码 knowledge_uni_app目录
-
后台代码 knowledge_admin目录
Web版地址
- 教师端地址: https://demo.sdwanyue.com/teacher 账号:13866666666 密码:123456
-
后台地址: https://demo.sdwanyue.com/admin 账号: demo 密码: 123456
项目介绍
万岳知识付费系统打造沉浸式学习体验,提升教学质量,还原真实课堂。知识付费功能包含热门精选、在线直播、付费视频、付费音频、付费阅读等营销功能,实现用户快速裂变。提高用户工作效率和收入是成为知识付费的刚需,可以从海量信息中寻找到适合自身的产品,利用碎片化时间和少许资金就能获得自己需要的信息。
万岳知识付费深刻理解用户诉求,紧盯市场需求。帮助大家低成本高效率体验知识付费平台,以利用互联网让人们生活更美好为使命,精益求精,创新研发,为客户创造更多价值!
- 所有使用到的框架或者组件都是基于开源项目,代码保证100%开源。
-
系统功能通用,无论是个人还是企业都可以利用该系统快速搭建一个属于自己的知识付费系统。
系统前端采用uni-app+socket.io+WebRtc核心技术, 接口采用PhalApi框架配合TP5.1框架ThinkCMF,系统功能如下:
功能展示
开源版使用须知
-
允许用于个人学习、教学案例
-
开源版不适合商用,商用请购买商业版
-
禁止将本项目的代码和资源进行任何形式的出售,产生的一切任何后果责任由侵权者自负
商业合作
- 如果你想使用功能更完善的知识付费系统,请联系QQ客服: 2415408120 获取专业版
- 如果您想基于知识付费系统进行定制开发,我们提供有偿定制服务支持!
- 其他合作模式不限,欢迎来撩!
- 官网地址:http://www.sdwanyue.com
系统演示
目录结构
- 前端代码 knowledge_uni_app目录
-
后台代码 knowledge_admin目录
Web版地址
- 教师端地址: https://demo.sdwanyue.com/teacher 账号:13866666666 密码:123456
-
后台地址: https://demo.sdwanyue.com/admin 账号: demo 密码: 123456
项目介绍
万岳知识付费系统打造沉浸式学习体验,提升教学质量,还原真实课堂。知识付费功能包含热门精选、在线直播、付费视频、付费音频、付费阅读等营销功能,实现用户快速裂变。提高用户工作效率和收入是成为知识付费的刚需,可以从海量信息中寻找到适合自身的产品,利用碎片化时间和少许资金就能获得自己需要的信息。
万岳知识付费深刻理解用户诉求,紧盯市场需求。帮助大家低成本高效率体验知识付费平台,以利用互联网让人们生活更美好为使命,精益求精,创新研发,为客户创造更多价值!
- 所有使用到的框架或者组件都是基于开源项目,代码保证100%开源。
-
系统功能通用,无论是个人还是企业都可以利用该系统快速搭建一个属于自己的知识付费系统。
系统前端采用uni-app+socket.io+WebRtc核心技术, 接口采用PhalApi框架配合TP5.1框架ThinkCMF,系统功能如下:
功能展示
开源版使用须知
-
允许用于个人学习、教学案例
-
开源版不适合商用,商用请购买商业版
-
禁止将本项目的代码和资源进行任何形式的出售,产生的一切任何后果责任由侵权者自负
商业合作
- 如果你想使用功能更完善的知识付费系统,请联系QQ客服: 2415408120 获取专业版
- 如果您想基于知识付费系统进行定制开发,我们提供有偿定制服务支持!
- 其他合作模式不限,欢迎来撩!
- 官网地址:http://www.sdwanyue.com

在横竖屏切换后 页面错乱问题的解决办法
需求:用户来到首页时候是竖屏的,点开详情页横屏展示详细信息,用户点击返回回到首页
问题:从横屏到竖屏或者竖屏到横屏都有可能出现页面错乱的问题,且还容易闪退!
原因:
因为页面使用rpx为单位的;如果用的是px为单位就不会;因为rpx是根据屏幕尺寸来计算的,回到首页时候,页面获取到的屏幕尺寸还是横屏的尺寸;
测试:
home.vue:
onShow(){
uni.getSystemInfo({
success: (res) => {
uni.showModal({
title:"sW:"+res.screenWidth+';sh:'+res.screenHeight+';ww:'+res.windowWidth+';wh:'+res.windowHeight
})
}
})
}
detail.vue:
methods: {
go_home(){
uni.showTabBar();
// #ifdef APP-PLUS
plus.screen.unlockOrientation(); //解除锁定屏幕方向
plus.screen.lockOrientation('portrait-primary');
// #endif
uni.reLaunch({
url:"../index/index"
})
},
首次进入首页弹窗内容如下:
sw:393;sh:857;ww:393;wh:807
进入详情页 点击首页后弹窗内容如下
sw:873;sh:393;ww:873;wh:343
很明显系统提前获取了错误的页面尺寸;
解决办法就呼之欲出了,我只需要保证在首页时候拿到正常的屏幕尺寸:
detail.vue
methods: {
go_home_real(){
uni.getSystemInfo({
success: (res) => {
if(res.screenWidth <= res.screenWidth) {
clearInterval(this.dingshiqi)
uni.reLaunch({
url:"../index/index"
})
}
}
})
},
go_home(){
uni.showTabBar();
// #ifdef APP-PLUS
plus.screen.unlockOrientation(); //解除锁定屏幕方向
plus.screen.lockOrientation('portrait-primary');
// #endif
this.dingshiqi = setInterval(this.go_home_real,300);//每隔0.3秒检测一次屏幕是否已经竖过来了 如果是就跳转
},
}
跳转时候做个检测
屏幕尺寸改变时候会触发onResize 也可以在这上面作文章;
data() {
return {
portraitUrl:'',
landScapeUrl:'',
}
},
onResize() {
let _this = this
uni.getSystemInfo({
success: function(res) {
if (res.windowWidth > res.windowHeight) {
if(_this.landScapeUrl) {
uni.reLaunch({
url:_this.landScapeUrl
})
}
} else {
if(_this.portraitUrl) {
uni.reLaunch({
url:_this.portraitUrl
})
}
}
}
})
},
methods: {
go_home(){
uni.showTabBar();
this.portraitUrl = '../index/index';
console.log("go_home")
// #ifdef APP-PLUS
plus.screen.unlockOrientation(); //解除锁定屏幕方向
plus.screen.lockOrientation('portrait-primary');
// #endif
console.log("go_home_end")
},
}
需求:用户来到首页时候是竖屏的,点开详情页横屏展示详细信息,用户点击返回回到首页
问题:从横屏到竖屏或者竖屏到横屏都有可能出现页面错乱的问题,且还容易闪退!
原因:
因为页面使用rpx为单位的;如果用的是px为单位就不会;因为rpx是根据屏幕尺寸来计算的,回到首页时候,页面获取到的屏幕尺寸还是横屏的尺寸;
测试:
home.vue:
onShow(){
uni.getSystemInfo({
success: (res) => {
uni.showModal({
title:"sW:"+res.screenWidth+';sh:'+res.screenHeight+';ww:'+res.windowWidth+';wh:'+res.windowHeight
})
}
})
}
detail.vue:
methods: {
go_home(){
uni.showTabBar();
// #ifdef APP-PLUS
plus.screen.unlockOrientation(); //解除锁定屏幕方向
plus.screen.lockOrientation('portrait-primary');
// #endif
uni.reLaunch({
url:"../index/index"
})
},
首次进入首页弹窗内容如下:
sw:393;sh:857;ww:393;wh:807
进入详情页 点击首页后弹窗内容如下
sw:873;sh:393;ww:873;wh:343
很明显系统提前获取了错误的页面尺寸;
解决办法就呼之欲出了,我只需要保证在首页时候拿到正常的屏幕尺寸:
detail.vue
methods: {
go_home_real(){
uni.getSystemInfo({
success: (res) => {
if(res.screenWidth <= res.screenWidth) {
clearInterval(this.dingshiqi)
uni.reLaunch({
url:"../index/index"
})
}
}
})
},
go_home(){
uni.showTabBar();
// #ifdef APP-PLUS
plus.screen.unlockOrientation(); //解除锁定屏幕方向
plus.screen.lockOrientation('portrait-primary');
// #endif
this.dingshiqi = setInterval(this.go_home_real,300);//每隔0.3秒检测一次屏幕是否已经竖过来了 如果是就跳转
},
}
跳转时候做个检测
屏幕尺寸改变时候会触发onResize 也可以在这上面作文章;
data() {
return {
portraitUrl:'',
landScapeUrl:'',
}
},
onResize() {
let _this = this
uni.getSystemInfo({
success: function(res) {
if (res.windowWidth > res.windowHeight) {
if(_this.landScapeUrl) {
uni.reLaunch({
url:_this.landScapeUrl
})
}
} else {
if(_this.portraitUrl) {
uni.reLaunch({
url:_this.portraitUrl
})
}
}
}
})
},
methods: {
go_home(){
uni.showTabBar();
this.portraitUrl = '../index/index';
console.log("go_home")
// #ifdef APP-PLUS
plus.screen.unlockOrientation(); //解除锁定屏幕方向
plus.screen.lockOrientation('portrait-primary');
// #endif
console.log("go_home_end")
},
}
收起阅读 »

C++防止头文件被重复引入的3种方法!
在之前我们详细介绍了 C 语言中如何使用宏定义(#ifndef / #define / #endif)来有效避免头文件被重复 #include,此方式在 C++ 多文件编程中也很常用。
举个例子,如下是一个 C++ 项目,其内部含有 school.h 和 student.h 这 2 个头文件以及 main.cpp 源文件,其各自包含的代码为:
//student.h
class Student {
//......
};
//school.h
include "student.h"
class School {
//......
private:
Student stu[50];
};
//main.cpp
include "student.h"
include "school.h"
int main() {
//......
return 0;
}
运行此项目会发现,编译器报“Student 类型重定义”错误。这是因为在 school.h 文件中已经 #include 了一次 "student.h",而在 main.cpp 主程序又同时 #include 了 "school.h" 和 "student.h",即 Student 类的定义被引入了 2 次,C++不允许同一个类被重复定义。
有小伙伴可能想到,既然 School.h 文件中已经引入了 Student 类,那去掉 main.cpp 主程序引入的 student.h 文件不就可以了吗?这样确实可以避免重复引入 Student 类,但此方式并不适用于所有“重复引入”的场景。
C++ 多文件编程中,处理“多次 #include 导致重复引入”问题的方式有以下 3 种。
————————
1) 使用宏定义避免重复引入
在实际多文件开发中,我们往往使用如下的宏定义来避免发生重复引入:
ifndef _NAME_H
define _NAME_H
//头文件内容
endif
其中,_NAME_H 是宏的名称。需要注意的是,这里设置的宏名必须是独一无二的,不要和项目中其他宏的名称相同。
当程序中第一次 #include 该文件时,由于 _NAME_H 尚未定义,所以会定义 _NAME_H 并执行“头文件内容”部分的代码;当发生多次 #include 时,因为前面已经定义了 _NAME_H,所以不会再重复执行“头文件内容”部分的代码。
也就是说,我们可以将前面项目中的 student.h 文件做如下修改:
ifndef _STUDENT_H
define _STUDENT_H
class Student {
//......
};
endif
虽然该项目 main.cpp 文件中仍 #include 了 2 次 "student.h",但鉴于 _STUDENT_H 宏只能定义一次,所以 Student 类也仅会定义一次。再次执行该项目会发现,其可以正常执行。
2) 使用#pragma once避免重复引入
除了前面第一种最常用的方式之外,还可以使用 #pragma one 指令,将其附加到指定文件的最开头位置,则该文件就只会被 #include 一次。
我们知道,#ifndef 是通过定义独一无二的宏来避免重复引入的,这意味着每次引入头文件都要进行识别,所以效率不高。但考虑到 C 和 C++ 都支持宏定义,所以项目中使用 #ifndef 规避可能出现的“头文件重复引入”问题,不会影响项目的可移植性。
和 ifndef 相比,#pragma once 不涉及宏定义,当编译器遇到它时就会立刻知道当前文件只引入一次,所以效率很高。
但值得一提的是,并不是每个版本的编译器都能识别 #pragma once 指令,一些较老版本的编译器就不支持该指令(执行时会发出警告,但编译会继续进行),即 #pragma once 指令的兼容性不是很好。
目前,几乎所有常见的编译器都支持 #pragma once 指令,甚至于 Visual Studio 2017 新建头文件时就会自带该指令。可以这么说,在 C/C++ 中,#pragma once 是一个非标准但却逐渐被很多编译器支持的指令。
除此之外,#pragma once 只能作用于某个具体的文件,而无法向 #ifndef 那样仅作用于指定的一段代码。
这里仍以前面的 "student.h" 文件为例,将其内容修改为:
pragma once
class Student {
//......
};
再次运行项目,同样可以正常执行。
3) 使用_Pragma操作符
C99 标准中新增加了一个和 #pragma 指令类似的 _Pragma 操作符,其可以看做是 #pragma 的增强版,不仅可以实现 #pragma 所有的功能,更重要的是,_Pragma 还能和宏搭配使用。
有关 _Pragma 操作符更多的功能和用法,本节不做详细讲解,这里仅介绍如何用 _Pragma 操作符避免头文件重复引入。
当处理头文件重复引入问题时,可以将如下语句添加到相应文件的开头:
_Pragma("once")
比如,将该语句添加到前面项目中 student.h 文件中的开头位置,再次执行项目,其可以正常执行。
事实上,无论是 C 语言还是 C++,为防止用户重复引入系统库文件,几乎所有库文件中都采用了以上 3 种结构中的一种,这也是为什么重复引入系统库文件编译器也不会报错的原因。
总结
本节介绍了 3 种避免头文件被重复引入的方法,其中 #pragma once 和 _Pragma("once") 可算作一类,其特点是编译效率高,但可移植性差(编译器不支持,会发出警告,但不会中断程序的执行);而 #ifndef 的特点是可移植性高,编译效率差。读者可根据实际情况,挑选最符合实际需要的解决方案。
除非对项目的编译效率有严格的要求,强烈推荐读者选用第一种解决方案,即采用 #ifndef / #define / #endif 组合解决头文件被重复引入。
另外在某些场景中,考虑到编译效率和可移植性,#pragma once 和 #ifndef 经常被结合使用来避免头文件被重复引入。比如说:
pragma once
ifndef _STUDENT_H
define _STUDENT_H
class Student {
//......
};
endif
当编译器可以识别 #pragma once 时,则整个文件仅被编译一次;反之,即便编译器不识别 #pragma once 指令,此时仍有 #ifndef 在发挥作用。
在之前我们详细介绍了 C 语言中如何使用宏定义(#ifndef / #define / #endif)来有效避免头文件被重复 #include,此方式在 C++ 多文件编程中也很常用。
举个例子,如下是一个 C++ 项目,其内部含有 school.h 和 student.h 这 2 个头文件以及 main.cpp 源文件,其各自包含的代码为:
//student.h
class Student {
//......
};
//school.h
include "student.h"
class School {
//......
private:
Student stu[50];
};
//main.cpp
include "student.h"
include "school.h"
int main() {
//......
return 0;
}
运行此项目会发现,编译器报“Student 类型重定义”错误。这是因为在 school.h 文件中已经 #include 了一次 "student.h",而在 main.cpp 主程序又同时 #include 了 "school.h" 和 "student.h",即 Student 类的定义被引入了 2 次,C++不允许同一个类被重复定义。
有小伙伴可能想到,既然 School.h 文件中已经引入了 Student 类,那去掉 main.cpp 主程序引入的 student.h 文件不就可以了吗?这样确实可以避免重复引入 Student 类,但此方式并不适用于所有“重复引入”的场景。
C++ 多文件编程中,处理“多次 #include 导致重复引入”问题的方式有以下 3 种。
————————
1) 使用宏定义避免重复引入
在实际多文件开发中,我们往往使用如下的宏定义来避免发生重复引入:
ifndef _NAME_H
define _NAME_H
//头文件内容
endif
其中,_NAME_H 是宏的名称。需要注意的是,这里设置的宏名必须是独一无二的,不要和项目中其他宏的名称相同。
当程序中第一次 #include 该文件时,由于 _NAME_H 尚未定义,所以会定义 _NAME_H 并执行“头文件内容”部分的代码;当发生多次 #include 时,因为前面已经定义了 _NAME_H,所以不会再重复执行“头文件内容”部分的代码。
也就是说,我们可以将前面项目中的 student.h 文件做如下修改:
ifndef _STUDENT_H
define _STUDENT_H
class Student {
//......
};
endif
虽然该项目 main.cpp 文件中仍 #include 了 2 次 "student.h",但鉴于 _STUDENT_H 宏只能定义一次,所以 Student 类也仅会定义一次。再次执行该项目会发现,其可以正常执行。
2) 使用#pragma once避免重复引入
除了前面第一种最常用的方式之外,还可以使用 #pragma one 指令,将其附加到指定文件的最开头位置,则该文件就只会被 #include 一次。
我们知道,#ifndef 是通过定义独一无二的宏来避免重复引入的,这意味着每次引入头文件都要进行识别,所以效率不高。但考虑到 C 和 C++ 都支持宏定义,所以项目中使用 #ifndef 规避可能出现的“头文件重复引入”问题,不会影响项目的可移植性。
和 ifndef 相比,#pragma once 不涉及宏定义,当编译器遇到它时就会立刻知道当前文件只引入一次,所以效率很高。
但值得一提的是,并不是每个版本的编译器都能识别 #pragma once 指令,一些较老版本的编译器就不支持该指令(执行时会发出警告,但编译会继续进行),即 #pragma once 指令的兼容性不是很好。
目前,几乎所有常见的编译器都支持 #pragma once 指令,甚至于 Visual Studio 2017 新建头文件时就会自带该指令。可以这么说,在 C/C++ 中,#pragma once 是一个非标准但却逐渐被很多编译器支持的指令。
除此之外,#pragma once 只能作用于某个具体的文件,而无法向 #ifndef 那样仅作用于指定的一段代码。
这里仍以前面的 "student.h" 文件为例,将其内容修改为:
pragma once
class Student {
//......
};
再次运行项目,同样可以正常执行。
3) 使用_Pragma操作符
C99 标准中新增加了一个和 #pragma 指令类似的 _Pragma 操作符,其可以看做是 #pragma 的增强版,不仅可以实现 #pragma 所有的功能,更重要的是,_Pragma 还能和宏搭配使用。
有关 _Pragma 操作符更多的功能和用法,本节不做详细讲解,这里仅介绍如何用 _Pragma 操作符避免头文件重复引入。
当处理头文件重复引入问题时,可以将如下语句添加到相应文件的开头:
_Pragma("once")
比如,将该语句添加到前面项目中 student.h 文件中的开头位置,再次执行项目,其可以正常执行。
事实上,无论是 C 语言还是 C++,为防止用户重复引入系统库文件,几乎所有库文件中都采用了以上 3 种结构中的一种,这也是为什么重复引入系统库文件编译器也不会报错的原因。
总结
本节介绍了 3 种避免头文件被重复引入的方法,其中 #pragma once 和 _Pragma("once") 可算作一类,其特点是编译效率高,但可移植性差(编译器不支持,会发出警告,但不会中断程序的执行);而 #ifndef 的特点是可移植性高,编译效率差。读者可根据实际情况,挑选最符合实际需要的解决方案。
除非对项目的编译效率有严格的要求,强烈推荐读者选用第一种解决方案,即采用 #ifndef / #define / #endif 组合解决头文件被重复引入。
另外在某些场景中,考虑到编译效率和可移植性,#pragma once 和 #ifndef 经常被结合使用来避免头文件被重复引入。比如说:
pragma once
ifndef _STUDENT_H
define _STUDENT_H
class Student {
//......
};
endif
当编译器可以识别 #pragma once 时,则整个文件仅被编译一次;反之,即便编译器不识别 #pragma once 指令,此时仍有 #ifndef 在发挥作用。
收起阅读 »
调用安卓系统分享功能,分享非媒体文件到微信
在我的 app 中需要分享 json 文件,看了好多文章大多数都是讲如何分享媒体文件的,比如图片音频什么的,其实调用系统分享功能也是比较简单的,但是分享到微信就会遇到找不到资源的问题,要使用 FileProvider 方式的话就必须要通过原生开发辅助才行,经过无数次的尝试发现微信要获取文件必须要 content:// 开头的 Uri 才行,最后使用了参考文档中的第二种方法 scanFile,目前只是为了达到目的所以代码比较粗糙,欢迎大佬指正
大概思路是这样的:
- 把要分享的文件从 app 私有目录复制到公共目录,这里选了 Download 目录
- 调用 MediaScannerConnection.scanFile 方法,在 onScanCompleted 回调函数中获取正确的 Uri 标识
- 再调用系统分享功能即可
// #ifdef APP-PLUS
plus.android.importClass('android.content.ContentResolver')
const MainActivity = plus.android.runtimeMainActivity(),
Intent = plus.android.importClass('android.content.Intent'),
Uri = plus.android.importClass('android.net.Uri'),
InputStreamReader = plus.android.importClass('java.io.InputStreamReader'),
OutputStreamWriter = plus.android.importClass('java.io.OutputStreamWriter'),
BufferedReader = plus.android.importClass('java.io.BufferedReader'),
BufferedWriter = plus.android.importClass('java.io.BufferedWriter'),
File = plus.android.importClass('java.io.File'),
FileInputStream = plus.android.importClass('java.io.FileInputStream'),
FileOutputStream = plus.android.importClass('java.io.FileOutputStream'),
MediaScannerConnection = plus.android.importClass('android.media.MediaScannerConnection'),
Environment = plus.android.importClass('android.os.Environment'),
SETTINGS_FILENAME = 'settings.json'
// #endif
function share_file() {
// #ifndef APP-PLUS
return false
// #endif
// #ifdef APP-PLUS
plus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, fs => {
fs.root.getFile(SETTINGS_FILENAME, {}, file_entry => {
const listener = new plus.android.implements('android.media.MediaScannerConnection$OnScanCompletedListener', {
'onScanCompleted': (path, uri) => {
console.log('uri: ' + uri.toString())
const intent = new Intent()
.setAction(Intent.ACTION_SEND)
.setType('text/*')
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(Intent.EXTRA_TEXT, 'Share a file')
.putExtra(Intent.EXTRA_STREAM, uri) // Uri.parse(file_entry.fullPath))
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
MainActivity.startActivity(Intent.createChooser(intent, 'Share a file'))
// MainActivity.startActivity(intent)
new File(path).deleteOnExit()
}
})
copy_file_to_public_directory(file_entry.fullPath)
MediaScannerConnection.scanFile(MainActivity, [get_public_directory() + '/' + SETTINGS_FILENAME], null, listener)
return true
}, error => {
uni.showToast({
title: '文件不存在',
icon: 'none',
duration: 2000
})
})
})
// #endif
}
function copy_file_to_public_directory(file_path) {
// #ifndef APP-PLUS
return false
// #endif
// #ifdef APP-PLUS
const input_stream = new FileInputStream(file_path),
output_Stream = new FileOutputStream(get_public_directory() + '/' + SETTINGS_FILENAME),
file_reader = new BufferedReader(new InputStreamReader(input_stream)),
file_writer = new BufferedWriter(new OutputStreamWriter(output_Stream)),
content = file_reader.readLine()
file_writer.write(content, 0, content.length)
file_writer.flush()
file_writer.close()
file_reader.close()
output_Stream.close()
input_stream.close()
console.log('copy file success')
return true
// #endif
}
function get_public_directory() {
// '/storage/emulated/0/Download/temp'
// #ifndef APP-PLUS
return false
// #endif
// #ifdef APP-PLUS
return new File(Environment.getExternalStorageDirectory(), 'Download/temp').getAbsolutePath()
// #endif
}
参考文档:
在我的 app 中需要分享 json 文件,看了好多文章大多数都是讲如何分享媒体文件的,比如图片音频什么的,其实调用系统分享功能也是比较简单的,但是分享到微信就会遇到找不到资源的问题,要使用 FileProvider 方式的话就必须要通过原生开发辅助才行,经过无数次的尝试发现微信要获取文件必须要 content:// 开头的 Uri 才行,最后使用了参考文档中的第二种方法 scanFile,目前只是为了达到目的所以代码比较粗糙,欢迎大佬指正
大概思路是这样的:
- 把要分享的文件从 app 私有目录复制到公共目录,这里选了 Download 目录
- 调用 MediaScannerConnection.scanFile 方法,在 onScanCompleted 回调函数中获取正确的 Uri 标识
- 再调用系统分享功能即可
// #ifdef APP-PLUS
plus.android.importClass('android.content.ContentResolver')
const MainActivity = plus.android.runtimeMainActivity(),
Intent = plus.android.importClass('android.content.Intent'),
Uri = plus.android.importClass('android.net.Uri'),
InputStreamReader = plus.android.importClass('java.io.InputStreamReader'),
OutputStreamWriter = plus.android.importClass('java.io.OutputStreamWriter'),
BufferedReader = plus.android.importClass('java.io.BufferedReader'),
BufferedWriter = plus.android.importClass('java.io.BufferedWriter'),
File = plus.android.importClass('java.io.File'),
FileInputStream = plus.android.importClass('java.io.FileInputStream'),
FileOutputStream = plus.android.importClass('java.io.FileOutputStream'),
MediaScannerConnection = plus.android.importClass('android.media.MediaScannerConnection'),
Environment = plus.android.importClass('android.os.Environment'),
SETTINGS_FILENAME = 'settings.json'
// #endif
function share_file() {
// #ifndef APP-PLUS
return false
// #endif
// #ifdef APP-PLUS
plus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, fs => {
fs.root.getFile(SETTINGS_FILENAME, {}, file_entry => {
const listener = new plus.android.implements('android.media.MediaScannerConnection$OnScanCompletedListener', {
'onScanCompleted': (path, uri) => {
console.log('uri: ' + uri.toString())
const intent = new Intent()
.setAction(Intent.ACTION_SEND)
.setType('text/*')
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(Intent.EXTRA_TEXT, 'Share a file')
.putExtra(Intent.EXTRA_STREAM, uri) // Uri.parse(file_entry.fullPath))
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
MainActivity.startActivity(Intent.createChooser(intent, 'Share a file'))
// MainActivity.startActivity(intent)
new File(path).deleteOnExit()
}
})
copy_file_to_public_directory(file_entry.fullPath)
MediaScannerConnection.scanFile(MainActivity, [get_public_directory() + '/' + SETTINGS_FILENAME], null, listener)
return true
}, error => {
uni.showToast({
title: '文件不存在',
icon: 'none',
duration: 2000
})
})
})
// #endif
}
function copy_file_to_public_directory(file_path) {
// #ifndef APP-PLUS
return false
// #endif
// #ifdef APP-PLUS
const input_stream = new FileInputStream(file_path),
output_Stream = new FileOutputStream(get_public_directory() + '/' + SETTINGS_FILENAME),
file_reader = new BufferedReader(new InputStreamReader(input_stream)),
file_writer = new BufferedWriter(new OutputStreamWriter(output_Stream)),
content = file_reader.readLine()
file_writer.write(content, 0, content.length)
file_writer.flush()
file_writer.close()
file_reader.close()
output_Stream.close()
input_stream.close()
console.log('copy file success')
return true
// #endif
}
function get_public_directory() {
// '/storage/emulated/0/Download/temp'
// #ifndef APP-PLUS
return false
// #endif
// #ifdef APP-PLUS
return new File(Environment.getExternalStorageDirectory(), 'Download/temp').getAbsolutePath()
// #endif
}
参考文档:
收起阅读 »
在线客服系统源码h5|thinkphp在线客服完整源码|网页在线客服源码
法国阿纳托尔曾经说过:企业客服人员早上醒来后通常做的第一件事就是检查手机,看看是否有顾客发来的重要信息,这种行为已经成为我们日常生活方式的一部分。
源码及演示:e.cusscode.top/s
不管原因是什么,我们都有一套日常使用的通信工具电子邮件、电话、网络会议工具或社交网络。对于一个高效运行的企业而言,拥有一套好的源码搭建的在线客服系统,对于提供企业运行效率至关重要!随着流感大流行使在家工作成为一种新的常态,我们面临着前所未有的沟通方式的变化,这使得这些工具不仅是必不可少的,而且现在是必需的。
搭建在线客服系统软件的必要性:
作为全球分布式团队的一部分进行远程工作时,我们必须有一个协作环境。线客服系统在帮助我们保持联系方面起着至关重要的作用。与电子邮件不同,线客服系统提供与全球同事的快速、实时通信。
选择线客服系统源码有很多因素。为了帮助您选择合适的应用程序,在本文中,我将探讨四个开源聊线客服系统工具(当您需要与同事“面对面”时),然后概述一些您应该在有效的通信应用程序中寻找的功能。
1、RockChat
RockChat是一个综合性的交流平台,它将频道分为公共(对任何加入的人开放)或私人(仅限邀请)房间。您还可以直接向登录的用户发送消息;共享文档、链接、照片、视频和gif;进行视频通话;以及在不离开平台的情况下发送音频消息。
源码开源的,但它的独特之处在于它的自助客服系统。您可以将其下载到您的服务器上,无论它是本地服务器还是公共云上的虚拟专用服务器。多开源项目使用Rocket.Chat作为他们的官方交流平台。它在不断地发展,有新的特性和改进。
RockChat最让我喜欢的是它能够根据用户需求进行定制,并且它使用机器学习在用户之间进行自动、实时的消息转换。你也可以在移动设备上下载和聊天。
2、IRC
IRC是一种实时的、基于文本的通信形式。虽然它是最古老的电子通信形式之一,但在许多著名的软件项目中仍然很流行。
IRC频道是独立的在线客服系统。它允许你与多人在一个开放的渠道交谈,或与某人私下一对一的交谈。如果频道名以#开头,则可以假定它是正式的,而以#开头的聊天室是非官方的,通常是随意的。
IRC入门很简单。您的IRC句柄或昵称允许人们找到您,因此它必须是唯一的。但你选择IRC客户完全是你的决定。如果您想要一个比标准IRC客户端功能更丰富的应用程序。
考虑到它的年龄,你为什么还要在IRC上?原因之一是,它仍然是我们所依赖的许多免费和开源项目的所在地。如果您想参与开源软件和社区,可以选择IRC。
3、Zulip
Zulip是一个流行的在线客服系统源码,遵循基于主题的线程模型。在Zulip,你订阅流,就像在IRC频道或Rocket.Chat中一样。但是每个Zulip流都会打开一个独特的主题,这有助于您以后跟踪对话,从而使其更有条理。
与其他平台一样,它支持emojis、内嵌图像、视频和tweet预览。它还支持LaTeX共享数学公式或公式,并支持标记和语法高亮显示以共享代码。
Zulip是跨平台的,它提供用于构建您自己的集成的api。我特别喜欢Zulip与GitHub的集成特性:如果我正在处理一个问题,我可以使用Zulip的标记链接回pull请求ID。
Zulip是开源的(您可以访问源代码在GitHub上),免费使用,但它为内部支持付费,LDAP集成和更多存储。
4、Let's Chat
Let's Chat是一个小型团队的自托管的在线客服系统源码解决方案。它运行在Node.js和MongoDB上,只需点击几下,就可以部署到本地服务器或托管服务上。它是免费的,开源的源代码在GitHub上提供。
Let'sChat与其他开源聊天工具的区别在于它的企业特性:它支持LDAP和Kerberos身份验证。它还具有新用户想要的所有功能:您可以在存档中搜索消息历史记录,并用username之类的名字标记人物。
我喜欢Let'sChat的地方是它有私人和密码保护的房间、图像嵌入、GIPHY支持和代码粘贴。它在不断地发展,并在bucket中添加更多的特性。
选择在线客服系统源码的要点:
各种各样的在线客服系统源码让你很难选择一个。以下是一些选择在线客服系统源码的一般准则。
具有交互式界面和简单导航的工具是理想的。
最好是寻找一个功能强大并允许人们以各种方式使用它的工具。
与您使用的工具的集成可以在您的决策中发挥重要作用。有些工具与GitHub、GitLab和某些应用程序有很好的无缝集成,这是一个很有用的特性。
使用能够在基于云的服务上托管的工具非常方便。
聊天服务的安全性应该考虑在内。许多组织和个人都需要在专用服务器上托管服务。
提供丰富的私人和私人聊天室设置。
由于人们比以往任何时候都更依赖在线服务,所以有一个备用通信平台是明智之举,由于这些服务在不断更新,您可能会发现自己连接到多个通道,因此集成变得非常有价值。
法国阿纳托尔曾经说过:企业客服人员早上醒来后通常做的第一件事就是检查手机,看看是否有顾客发来的重要信息,这种行为已经成为我们日常生活方式的一部分。
源码及演示:e.cusscode.top/s
不管原因是什么,我们都有一套日常使用的通信工具电子邮件、电话、网络会议工具或社交网络。对于一个高效运行的企业而言,拥有一套好的源码搭建的在线客服系统,对于提供企业运行效率至关重要!随着流感大流行使在家工作成为一种新的常态,我们面临着前所未有的沟通方式的变化,这使得这些工具不仅是必不可少的,而且现在是必需的。
搭建在线客服系统软件的必要性:
作为全球分布式团队的一部分进行远程工作时,我们必须有一个协作环境。线客服系统在帮助我们保持联系方面起着至关重要的作用。与电子邮件不同,线客服系统提供与全球同事的快速、实时通信。
选择线客服系统源码有很多因素。为了帮助您选择合适的应用程序,在本文中,我将探讨四个开源聊线客服系统工具(当您需要与同事“面对面”时),然后概述一些您应该在有效的通信应用程序中寻找的功能。
1、RockChat
RockChat是一个综合性的交流平台,它将频道分为公共(对任何加入的人开放)或私人(仅限邀请)房间。您还可以直接向登录的用户发送消息;共享文档、链接、照片、视频和gif;进行视频通话;以及在不离开平台的情况下发送音频消息。
源码开源的,但它的独特之处在于它的自助客服系统。您可以将其下载到您的服务器上,无论它是本地服务器还是公共云上的虚拟专用服务器。多开源项目使用Rocket.Chat作为他们的官方交流平台。它在不断地发展,有新的特性和改进。
RockChat最让我喜欢的是它能够根据用户需求进行定制,并且它使用机器学习在用户之间进行自动、实时的消息转换。你也可以在移动设备上下载和聊天。
2、IRC
IRC是一种实时的、基于文本的通信形式。虽然它是最古老的电子通信形式之一,但在许多著名的软件项目中仍然很流行。
IRC频道是独立的在线客服系统。它允许你与多人在一个开放的渠道交谈,或与某人私下一对一的交谈。如果频道名以#开头,则可以假定它是正式的,而以#开头的聊天室是非官方的,通常是随意的。
IRC入门很简单。您的IRC句柄或昵称允许人们找到您,因此它必须是唯一的。但你选择IRC客户完全是你的决定。如果您想要一个比标准IRC客户端功能更丰富的应用程序。
考虑到它的年龄,你为什么还要在IRC上?原因之一是,它仍然是我们所依赖的许多免费和开源项目的所在地。如果您想参与开源软件和社区,可以选择IRC。
3、Zulip
Zulip是一个流行的在线客服系统源码,遵循基于主题的线程模型。在Zulip,你订阅流,就像在IRC频道或Rocket.Chat中一样。但是每个Zulip流都会打开一个独特的主题,这有助于您以后跟踪对话,从而使其更有条理。
与其他平台一样,它支持emojis、内嵌图像、视频和tweet预览。它还支持LaTeX共享数学公式或公式,并支持标记和语法高亮显示以共享代码。
Zulip是跨平台的,它提供用于构建您自己的集成的api。我特别喜欢Zulip与GitHub的集成特性:如果我正在处理一个问题,我可以使用Zulip的标记链接回pull请求ID。
Zulip是开源的(您可以访问源代码在GitHub上),免费使用,但它为内部支持付费,LDAP集成和更多存储。
4、Let's Chat
Let's Chat是一个小型团队的自托管的在线客服系统源码解决方案。它运行在Node.js和MongoDB上,只需点击几下,就可以部署到本地服务器或托管服务上。它是免费的,开源的源代码在GitHub上提供。
Let'sChat与其他开源聊天工具的区别在于它的企业特性:它支持LDAP和Kerberos身份验证。它还具有新用户想要的所有功能:您可以在存档中搜索消息历史记录,并用username之类的名字标记人物。
我喜欢Let'sChat的地方是它有私人和密码保护的房间、图像嵌入、GIPHY支持和代码粘贴。它在不断地发展,并在bucket中添加更多的特性。
选择在线客服系统源码的要点:
各种各样的在线客服系统源码让你很难选择一个。以下是一些选择在线客服系统源码的一般准则。
具有交互式界面和简单导航的工具是理想的。
最好是寻找一个功能强大并允许人们以各种方式使用它的工具。
与您使用的工具的集成可以在您的决策中发挥重要作用。有些工具与GitHub、GitLab和某些应用程序有很好的无缝集成,这是一个很有用的特性。
使用能够在基于云的服务上托管的工具非常方便。
聊天服务的安全性应该考虑在内。许多组织和个人都需要在专用服务器上托管服务。
提供丰富的私人和私人聊天室设置。
由于人们比以往任何时候都更依赖在线服务,所以有一个备用通信平台是明智之举,由于这些服务在不断更新,您可能会发现自己连接到多个通道,因此集成变得非常有价值。
收起阅读 »
uni-app 内置国际化方案说明
uni-app 从 3.1.5 版本开始框架内置组件开始完善国际化支持
>+ App平台、H5平台 优化 uni.showModal、uni.showActionSheet 等 API 内置国际化支持
>+ App平台 优化 应用退出提示内置国际化支持
>+ App平台 优化 uni.scanCode、uni.previewImage 等 API 内置国际化支持
>+ H5平台 优化 picker、video 组件内置国际化支持
这些组件内置如下语言
- 中文简体 zh-Hans
- 中文繁体 zh-Hant
- 英语 en
- 法语 fr
- 西班牙语 es
组件和接口显示会根据系统语言环境自动切换,未支持的系统语言环境会显示为英文。
uni-app 3.2.5 版本以下当使用 vue-i18n 时,会使用 vue-i18n 设置的语言。
uni-app 3.2.5 版本开始请在 manifest.json 内配置,或者调用 uni.setLocale 进行设置,具体参考 locale.md。
uni-app 从 3.1.5 版本开始框架内置组件开始完善国际化支持
>+ App平台、H5平台 优化 uni.showModal、uni.showActionSheet 等 API 内置国际化支持
>+ App平台 优化 应用退出提示内置国际化支持
>+ App平台 优化 uni.scanCode、uni.previewImage 等 API 内置国际化支持
>+ H5平台 优化 picker、video 组件内置国际化支持
这些组件内置如下语言
- 中文简体 zh-Hans
- 中文繁体 zh-Hant
- 英语 en
- 法语 fr
- 西班牙语 es
组件和接口显示会根据系统语言环境自动切换,未支持的系统语言环境会显示为英文。
uni-app 3.2.5 版本以下当使用 vue-i18n 时,会使用 vue-i18n 设置的语言。
uni-app 3.2.5 版本开始请在 manifest.json 内配置,或者调用 uni.setLocale 进行设置,具体参考 locale.md。
收起阅读 »
星援App开发者一审获刑五年,系“蔡徐坤微博转发过亿”幕后推手
2018年,“明星蔡徐坤一条微博转发量过亿”事件引发舆论对流量造假的关注。按照当时的微博用户数量,转发量一亿意味着每三个微博用户中就有一人转发了蔡徐坤的微博。人民日报官微评论称:“一亿转发量”,你们也真敢刷。
2019年6月,操纵上述微博刷量事件的幕后推手“星援”APP被查。日前,中国裁判文书网公布了“星援”APP开发者蔡坤苗的判决书,其因提供侵入计算机信息系统程序罪一审获刑五年。
北京市丰台区法院审理查明,2018年1月至2019年3月间,被告人蔡坤苗未获得被害单位北京微梦创科网络技术有限公司授权而自行开发“星援”APP,有偿为他人提供不需要登录新浪微博客户端即可转发微博博文及自动批量转发微博博文的服务。后大量用户以向“星援”APP充值的形式有偿使用该软件,并通过运行上述软件侵入新浪微博服务器。
经鉴定,“星援”APP通过截取新浪微博服务器中对应账号的相关数据,后使用与其截取数据相同的网络数据格式向该服务器提交数据并完成与该服务器的交互,以实现不登录新浪微博客户端即可转发微博博文的功能以及自动批量转发微博博文的功能。经统计,至案发时该软件已有用户使用19万余个控制端微博账号登录,被告人蔡坤苗获取违法所得人民币6253752.86元。
大学肄业的“95后”开发微博刷量APP
北京市丰台区法院公布的判决书显示,“星援”APP的开发者为蔡坤苗,其于1995年5月30日出生于福建省泉州市,大学肄业,系泉州市星援网络科技有限公司法定代表人。蔡坤苗因涉嫌犯破坏计算机信息系统罪,于2019年4月11日被逮捕。
2019年11月27日,北京市丰台区检察院指控被告人蔡坤苗犯提供侵入、非法控制计算机信息系统程序、工具罪,向丰台区法院提起公诉。
法院审理查明
2018年1月至2019年3月间,被告人蔡坤苗未获得北京微梦创科网络技术有限公司授权而自行开发“星援”APP,有偿为他人提供不需要登录新浪微博客户端即可转发微博博文及自动批量转发微博博文的服务。后大量用户以向“星援”APP充值的形式有偿使用该软件,并通过运行上述软件侵入新浪微博服务器。
经鉴定
“星援”APP通过截取新浪微博服务器中对应账号的相关数据,后使用与其截取数据相同的网络数据格式向该服务器提交数据并完成与该服务器的交互,以实现不登录新浪微博客户端即可转发微博博文的功能以及自动批量转发微博博文的功能。经统计,至案发时该软件已有用户使用19万余个控制端微博账号登录,上述控制端账号绑定微博账号×××余万个(原文如此),被告人蔡坤苗获取违法所得人民币6253752.86元。
2019年3月8日,被告人蔡坤苗被北京市公安局丰台分局太平桥派出所民警抓获,其到案后如实供述基本犯罪事实。
北京微梦创科网络技术有限公司员工李某称:“我们发现有一个叫‘星援’的APP破解了新浪微博的技术参数、算法,能对微博进行转发、评论、点赞等,影响了正常业务和系统稳定。2018年5月份的一天,我用手机刷微博时发现一个叫‘星援’的APP。这个APP可以大量转发或者评论同一条微博。我感觉这个APP可能有损我公司的利益,就跟公司领导进行了汇报。我们做了技术分析,直到现在才破解出来。过程中我们也收到用户的投诉,说‘星援’APP影响了微博的正常榜单和内容,同时也影响了系统的稳定和正常运行。”
相关司法鉴定意见书证明
使用新浪微博账号信息登录星援APP,在不登录微博客户端的情况下,可实现转发新浪微博博文的功能。使用新浪微博账号登录星援APP,通过该软件提供的配置界面,在配置相关参数后,可实现自动批量转发新浪微博博文的功能。
上述鉴定意见书显示,星援APP通过绑定微博账号的操作获取到微博用户的账号信息后,请求微博的服务器,从微博服务器返回的请求中获取相应账号的uid等信息,再通过结合密钥和特定算法的方式,生成微博加密数字签名s值,结合其他参数,使用与“新浪微博客户端”转发微博时相同的网络数据格式,将该数据提交给“新浪微博服务器”,该数据被“新浪微博服务器”误认为是“新浪微博客户端”提交的网络数据,进而和星援APP发生了数据交互,从而实现了不需要登陆“新浪微博客户端”即可转发新浪微博博文的功能。该APP还拥有通过绑定多个账号、多次重复请求,同时在转发微博博文时随机生成不同的硬件设备信息,实现自动批量转发新浪微博博文的功能。
17万微博用户绑定了3000万个微博“小号”
被告人蔡坤苗供述:“2018年3月,我自己做了一个名为星援的手机APP软件,并注册了一个网络工作室。2018年8月,我成立了泉州市星援网络科技有限公司,并担任公司法定代表人。”
蔡坤苗供述称,其公司主要经营两款手机应用软件,分别是星援和应援宝。这两款软件均是对接新浪微博的,客户通过这两款软件可以登录自己的微博账号实现批量转发、点赞和评论操作,而且绑定的微博数量没有上限,不用再人工登录每个微博账号进行重复操作。星援、应援宝两款手机软件通过用户的微博账号、密码登陆,登陆的时候不需要再另行注册。这两款软件的用户可以批量操作在软件端绑定的账号,更加快速的进行微博转发(行话叫抡博)、评论、点赞。微博客户端只能使用一个账号登陆进行操作,而星援、应援宝两款软件可以同时登陆多个微博账号进行相关操作。这两款软件在功能上是一样的,只是名字不一样。
蔡坤苗称,星援、应援宝两款软件可以加快明星粉丝,提升转发评论的数据量,满足数据的需求,“我于2019年2月份查看后台数据,星援、应援宝共有微博‘大号’用户17余万个,这17余万用户大约绑定了3000余万个微博‘小号’。‘星援’‘应援宝’一共有微博中的明星群管理员×××余个。微博‘大号’是常用的微博账号,有粉丝的老号。微博‘小号’是新注册或注册时间短的账号,也就是为转发增量而准备的账号。2019年2月份左右,我查了一下银行账户,‘星援’累计充值人民币700余万元,应援宝使用人数比较少,大概充值有10余万元。”
蔡坤苗供述称,他将犯罪所得主要用于买房和公司开销了,“我在泉州城东中骏世界城买了一处住宅,目前还在建设没有交房,费用大约100余万元。我还在泉州城东中骏世界城买了两个底商登记在我父亲蔡某名下,费用大约300万到400万之间,具体多少钱记不清了。其余资金用于日常开销、员工工资支出等。公司人事是陈某,每月工资7000元。UI设计是苏某和一个男孩,每月工资7000元。”
判决书显示
被害单位北京微梦创科网络技术有限公司的诉讼代理人在审理期间提供的证据证明,被告人蔡坤苗恶意开发的“星援”APP在未经北京微梦创科网络技术有限公司授权的情况下自动批量转发微博,大量转发的微博严重干扰了明星势力榜排行的数据,并导致排行系统功能受到实质性的影响;被告人蔡坤苗的行为给北京微梦创科网络技术有限公司造成应急人工支出45986.2元、2018年第四季度的服务器支出10376934元。
不过,法院审理后认为,上述诉讼代理人认为被告人蔡坤苗给被害单位造成经济损失人民币10422920.2元的意见,经查,相关证据均为被害单位单方材料,尚不足以证实与星援APP的关联性,故不予采纳。
北京市丰台区法院审理后认为,被告人蔡坤苗提供专门用于侵入计算机信息系统的程序,情节特别严重,其行为已构成提供侵入计算机信息系统程序罪,应予处罚。鉴于被告人蔡坤苗到案后如实供述基本犯罪事实,故对其予以从轻处罚。
2020年12月31日,被告人蔡坤苗被判犯提供侵入计算机信息系统程序罪,判处有期徒刑五年,并处罚金人民币十万元;继续追缴被告人蔡坤苗违法所得予以没收。
此文章【来源:澎湃新闻】,转载自【北晚新视觉网】,如有不当联系邮箱:pufa@dcloud.io 删除。原文链接
2018年,“明星蔡徐坤一条微博转发量过亿”事件引发舆论对流量造假的关注。按照当时的微博用户数量,转发量一亿意味着每三个微博用户中就有一人转发了蔡徐坤的微博。人民日报官微评论称:“一亿转发量”,你们也真敢刷。
2019年6月,操纵上述微博刷量事件的幕后推手“星援”APP被查。日前,中国裁判文书网公布了“星援”APP开发者蔡坤苗的判决书,其因提供侵入计算机信息系统程序罪一审获刑五年。
北京市丰台区法院审理查明,2018年1月至2019年3月间,被告人蔡坤苗未获得被害单位北京微梦创科网络技术有限公司授权而自行开发“星援”APP,有偿为他人提供不需要登录新浪微博客户端即可转发微博博文及自动批量转发微博博文的服务。后大量用户以向“星援”APP充值的形式有偿使用该软件,并通过运行上述软件侵入新浪微博服务器。
经鉴定,“星援”APP通过截取新浪微博服务器中对应账号的相关数据,后使用与其截取数据相同的网络数据格式向该服务器提交数据并完成与该服务器的交互,以实现不登录新浪微博客户端即可转发微博博文的功能以及自动批量转发微博博文的功能。经统计,至案发时该软件已有用户使用19万余个控制端微博账号登录,被告人蔡坤苗获取违法所得人民币6253752.86元。
大学肄业的“95后”开发微博刷量APP
北京市丰台区法院公布的判决书显示,“星援”APP的开发者为蔡坤苗,其于1995年5月30日出生于福建省泉州市,大学肄业,系泉州市星援网络科技有限公司法定代表人。蔡坤苗因涉嫌犯破坏计算机信息系统罪,于2019年4月11日被逮捕。
2019年11月27日,北京市丰台区检察院指控被告人蔡坤苗犯提供侵入、非法控制计算机信息系统程序、工具罪,向丰台区法院提起公诉。
法院审理查明
2018年1月至2019年3月间,被告人蔡坤苗未获得北京微梦创科网络技术有限公司授权而自行开发“星援”APP,有偿为他人提供不需要登录新浪微博客户端即可转发微博博文及自动批量转发微博博文的服务。后大量用户以向“星援”APP充值的形式有偿使用该软件,并通过运行上述软件侵入新浪微博服务器。
经鉴定
“星援”APP通过截取新浪微博服务器中对应账号的相关数据,后使用与其截取数据相同的网络数据格式向该服务器提交数据并完成与该服务器的交互,以实现不登录新浪微博客户端即可转发微博博文的功能以及自动批量转发微博博文的功能。经统计,至案发时该软件已有用户使用19万余个控制端微博账号登录,上述控制端账号绑定微博账号×××余万个(原文如此),被告人蔡坤苗获取违法所得人民币6253752.86元。
2019年3月8日,被告人蔡坤苗被北京市公安局丰台分局太平桥派出所民警抓获,其到案后如实供述基本犯罪事实。
北京微梦创科网络技术有限公司员工李某称:“我们发现有一个叫‘星援’的APP破解了新浪微博的技术参数、算法,能对微博进行转发、评论、点赞等,影响了正常业务和系统稳定。2018年5月份的一天,我用手机刷微博时发现一个叫‘星援’的APP。这个APP可以大量转发或者评论同一条微博。我感觉这个APP可能有损我公司的利益,就跟公司领导进行了汇报。我们做了技术分析,直到现在才破解出来。过程中我们也收到用户的投诉,说‘星援’APP影响了微博的正常榜单和内容,同时也影响了系统的稳定和正常运行。”
相关司法鉴定意见书证明
使用新浪微博账号信息登录星援APP,在不登录微博客户端的情况下,可实现转发新浪微博博文的功能。使用新浪微博账号登录星援APP,通过该软件提供的配置界面,在配置相关参数后,可实现自动批量转发新浪微博博文的功能。
上述鉴定意见书显示,星援APP通过绑定微博账号的操作获取到微博用户的账号信息后,请求微博的服务器,从微博服务器返回的请求中获取相应账号的uid等信息,再通过结合密钥和特定算法的方式,生成微博加密数字签名s值,结合其他参数,使用与“新浪微博客户端”转发微博时相同的网络数据格式,将该数据提交给“新浪微博服务器”,该数据被“新浪微博服务器”误认为是“新浪微博客户端”提交的网络数据,进而和星援APP发生了数据交互,从而实现了不需要登陆“新浪微博客户端”即可转发新浪微博博文的功能。该APP还拥有通过绑定多个账号、多次重复请求,同时在转发微博博文时随机生成不同的硬件设备信息,实现自动批量转发新浪微博博文的功能。
17万微博用户绑定了3000万个微博“小号”
被告人蔡坤苗供述:“2018年3月,我自己做了一个名为星援的手机APP软件,并注册了一个网络工作室。2018年8月,我成立了泉州市星援网络科技有限公司,并担任公司法定代表人。”
蔡坤苗供述称,其公司主要经营两款手机应用软件,分别是星援和应援宝。这两款软件均是对接新浪微博的,客户通过这两款软件可以登录自己的微博账号实现批量转发、点赞和评论操作,而且绑定的微博数量没有上限,不用再人工登录每个微博账号进行重复操作。星援、应援宝两款手机软件通过用户的微博账号、密码登陆,登陆的时候不需要再另行注册。这两款软件的用户可以批量操作在软件端绑定的账号,更加快速的进行微博转发(行话叫抡博)、评论、点赞。微博客户端只能使用一个账号登陆进行操作,而星援、应援宝两款软件可以同时登陆多个微博账号进行相关操作。这两款软件在功能上是一样的,只是名字不一样。
蔡坤苗称,星援、应援宝两款软件可以加快明星粉丝,提升转发评论的数据量,满足数据的需求,“我于2019年2月份查看后台数据,星援、应援宝共有微博‘大号’用户17余万个,这17余万用户大约绑定了3000余万个微博‘小号’。‘星援’‘应援宝’一共有微博中的明星群管理员×××余个。微博‘大号’是常用的微博账号,有粉丝的老号。微博‘小号’是新注册或注册时间短的账号,也就是为转发增量而准备的账号。2019年2月份左右,我查了一下银行账户,‘星援’累计充值人民币700余万元,应援宝使用人数比较少,大概充值有10余万元。”
蔡坤苗供述称,他将犯罪所得主要用于买房和公司开销了,“我在泉州城东中骏世界城买了一处住宅,目前还在建设没有交房,费用大约100余万元。我还在泉州城东中骏世界城买了两个底商登记在我父亲蔡某名下,费用大约300万到400万之间,具体多少钱记不清了。其余资金用于日常开销、员工工资支出等。公司人事是陈某,每月工资7000元。UI设计是苏某和一个男孩,每月工资7000元。”
判决书显示
被害单位北京微梦创科网络技术有限公司的诉讼代理人在审理期间提供的证据证明,被告人蔡坤苗恶意开发的“星援”APP在未经北京微梦创科网络技术有限公司授权的情况下自动批量转发微博,大量转发的微博严重干扰了明星势力榜排行的数据,并导致排行系统功能受到实质性的影响;被告人蔡坤苗的行为给北京微梦创科网络技术有限公司造成应急人工支出45986.2元、2018年第四季度的服务器支出10376934元。
不过,法院审理后认为,上述诉讼代理人认为被告人蔡坤苗给被害单位造成经济损失人民币10422920.2元的意见,经查,相关证据均为被害单位单方材料,尚不足以证实与星援APP的关联性,故不予采纳。
北京市丰台区法院审理后认为,被告人蔡坤苗提供专门用于侵入计算机信息系统的程序,情节特别严重,其行为已构成提供侵入计算机信息系统程序罪,应予处罚。鉴于被告人蔡坤苗到案后如实供述基本犯罪事实,故对其予以从轻处罚。
2020年12月31日,被告人蔡坤苗被判犯提供侵入计算机信息系统程序罪,判处有期徒刑五年,并处罚金人民币十万元;继续追缴被告人蔡坤苗违法所得予以没收。
此文章【来源:澎湃新闻】,转载自【北晚新视觉网】,如有不当联系邮箱:pufa@dcloud.io 删除。原文链接
收起阅读 »
安卓设置系统休眠时间-安卓原生方法
//获取默认休眠时间
@UniJSMethod(uiThread = true)
public void GetDormant(final JSCallback callback) {
try{
Context context = mWXSDKInstance.getContext();
int systemGravity = Settings.System.getInt(context.getContentResolver(),android.provider.Settings.System.SCREEN_OFF_TIMEOUT,0);
callback.invoke(systemGravity);
}catch (Exception ex){
callback.invoke(false);
Log.e(TAG, "setDormant: "+ex);
}
}
//设置系统休眠时间
@UniJSMethod(uiThread = true)
public void setDormant(int time,final JSCallback callback) {
try{
Context context = mWXSDKInstance.getContext();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(context)) {
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} else {
//有了权限,具体的动作
Settings.System.putInt(context.getContentResolver(),
Settings.System.SCREEN_OFF_TIMEOUT, time);
Uri uri = Settings.System
.getUriFor(Settings.System.SCREEN_OFF_TIMEOUT);
context.getContentResolver().notifyChange(uri, null);
Log.e(TAG, "setDormant: 设置完成" );
callback.invoke(true);
}
}
}catch (Exception ex){
callback.invoke(false);
Log.e(TAG, "setDormant: "+ex);
}
}
//获取默认休眠时间
@UniJSMethod(uiThread = true)
public void GetDormant(final JSCallback callback) {
try{
Context context = mWXSDKInstance.getContext();
int systemGravity = Settings.System.getInt(context.getContentResolver(),android.provider.Settings.System.SCREEN_OFF_TIMEOUT,0);
callback.invoke(systemGravity);
}catch (Exception ex){
callback.invoke(false);
Log.e(TAG, "setDormant: "+ex);
}
}
//设置系统休眠时间
@UniJSMethod(uiThread = true)
public void setDormant(int time,final JSCallback callback) {
try{
Context context = mWXSDKInstance.getContext();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(context)) {
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} else {
//有了权限,具体的动作
Settings.System.putInt(context.getContentResolver(),
Settings.System.SCREEN_OFF_TIMEOUT, time);
Uri uri = Settings.System
.getUriFor(Settings.System.SCREEN_OFF_TIMEOUT);
context.getContentResolver().notifyChange(uri, null);
Log.e(TAG, "setDormant: 设置完成" );
callback.invoke(true);
}
}
}catch (Exception ex){
callback.invoke(false);
Log.e(TAG, "setDormant: "+ex);
}
}
收起阅读 »

uni-app 屏幕旋转
/
输入参数
portrait-primary:竖屏主方向
portrait-secondary: 竖屏次方向
landscape-primary:横屏主方向
landscape-secondary:横屏次方向
portrait:竖屏方向(primary + secondary)
landscape:横屏方向(primary + secondary)
natural:设备的自然方向
any: 锁定四个方向,即锁定当前屏幕方向
/
plus.screen.lockOrientation('landscape-primary');
/
输入参数
portrait-primary:竖屏主方向
portrait-secondary: 竖屏次方向
landscape-primary:横屏主方向
landscape-secondary:横屏次方向
portrait:竖屏方向(primary + secondary)
landscape:横屏方向(primary + secondary)
natural:设备的自然方向
any: 锁定四个方向,即锁定当前屏幕方向
/
plus.screen.lockOrientation('landscape-primary');
收起阅读 »