这个怎么说呢,我记得我当年已经写过这样的技术贴了,但是因为比较久远,而且当时的思路好像没现在这么清晰,所以再记录一下。差不多现在的这个版本算是成型的一个版本了吧。
需求:在用户登录app后,如果有新版本会自动提示有新版本并弹出下载框(这里是否要强制更新由前端实现即可)。另外说明一点,Android的可以直接决定下载,但是苹果的要去苹果store中下载,所以苹果版的不用上传apk。记录个版本号就行了。另外我这里还涉及到一个配置:status。那是因为ios系统的充值要收取比较高额的手续费,所以我们目前的项目是绕开这个了的。所以用一个字段表示是否审核通过。如果审核中状态定义好,前端根据这个状态判断要不要放开充值页面,如果是审核中的话前端会把所有的充值有关的页面屏蔽点,这样看上去这个app是没有充值功能的。而等审核通过以后修改这个状态,前端会将所有的充值页面放出来。
上面是一个很常见的简单需求。大概的页面我画个简图:
![](https://img.haomeiwen.com/i16553345/796a99df6c4f1d9f.png)
因为我们公司虽然有现成的图但是感觉贴上来不太好,所以这里画了简图。感觉应该能看懂。
然后说具体的实现思路:
首先要维护这个版本号的方式多样,但是我用了最常用的存数据库的方式,这里不是必须的,像是redis或者配置文件中其实都可以。但是感觉这种存数据库最放心。
然后这里我是单独用了一张表维护各种莫名其妙的配置的。比如说什么微信支付id,微信支付秘钥,短信账号,短信秘钥,支付宝秘钥之类的。。反正大概知道这个配置表是什么就行了。自己在设置的时候维护好id对应的东西就行。也可以单独提出来不同的配置不同的表。反正都ok。因为我自己用的不是最适合这个场景的,所以这里用假的来表示一下得了:
![](https://img.haomeiwen.com/i16553345/7aab8d98c05d5f49.png)
其实很简单,有个id,有个版本号,有个状态就能满足了。其实我自己这个表中还有几个字段,remark,status啥的。做到最大兼容嘛。
然后注意的是这里的id就要自己定义好了,虽然我这里标了个auto,但是事实上是用不到这个玩意的。毕竟里面的数据的都是我们直接写入的。
为这个类再写个Dao层就不用说了,就是一个普通的表。
需要的接口:
- 获取当前app的版本号和审核状态(这些信息可以放在一个接口,反正也是在一个页面。也可以根据页面酌情拆分)
- 上传apk包修改安卓app版本(这两个动作一定是一起的,所以是一个接口)
- 修改ios版本(这个安装包是上传苹果store的,所以这里只修改版本号)
- 修改ios审核状态(因为这个是单独的一个功能,所以也是单独的接口)
- 下载最新版安卓app(苹果的跳转iosstore,所以这里只有安卓的)
以上的接口就是这个需求需要的接口了,因为我是根据页面所以设计的,如果遇到不符合的情况可以酌情拆分。
接口的实现:
其实实现代码都简单的很,但是为了下次我可以直接拿来就用,所以还是一步一步写好吧。
Service接口层:
public interface VersionService {
//查看安卓/苹果本号,苹果审核状态
public R getVersion();
//上传安卓apk和修改版本号
public R editVersion(MultipartFile file, double version);
//修改苹果版本号
public R editIosVersion(double version);
//苹果状态修改
public R editIosStatus(Integer status);
//下载安卓apk
public void downApk(HttpServletResponse response);
}
service实现类:
@Service
public class VersionServiceImpl implements VersionService{
@Autowired
SysConfigDao sysConfigDao;
@Override
public R getVersion() {
SysConfig a = sysConfigDao.selectById(1l);//安卓版本id是1
SysConfig i = sysConfigDao.selectById(2l);//ios版本id是2
return R.ok().put("iosVersion", i.getVersion()).put("iosStatus", i.getContent()).put("androidVersion", a.getVersion());
}
@Override
public R editVersion(MultipartFile file, double version) {
double v = sysConfigDao.selectById(1).getVersion();
if (v >= version)
return R.error(300, "版本升级必须新版本大于老版本!");
File file2 = new File("D:\\bus-station\\lsj.apk");
if (file2.exists()) {
File newFile = new File("D:\\bus-station\\lsj(" + v + ").apk");//旧版本记录,方便出问题了回退
file2.renameTo(newFile);
}
File file3 = new File("D:\\bus-station\\lsj.apk");
try {
file.transferTo(file3);
SysConfig sConfig = new SysConfig();
sConfig.setId(1l);
sConfig.setVersion(version);
sysConfigDao.updateById(sConfig);
return R.ok();
} catch (Exception e) {
return R.error();
}
}
@Override
public R editIosVersion(double version) {
double v = sysConfigDao.selectById(2).getVersion();
if (v >= version)
return R.error(300, "版本升级必须新版本大于老版本!");
SysConfig sConfig = new SysConfig();
sConfig.setId(2l);
sConfig.setVersion(version);
sysConfigDao.updateById(sConfig);
return R.ok();
}
@Override
public R editIosStatus(Integer status) {
SysConfig sConfig = new SysConfig();
sConfig.setId(2l);
sConfig.setContent(String.valueOf(status));
sysConfigDao.updateById(sConfig);
return R.ok();
}
@Override
public void downApk(HttpServletResponse response) {
try {
File f = new File("D:\\bus-station\\lsj.apk");
if (!f.exists()) {
response.sendError(404, "File not found!");
return;
}
String fileName = f.getName();
fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
byte[] buf = new byte[1024];
int len = 0;
response.reset(); // 非常重要
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.setContentLengthLong(f.length());
OutputStream out = response.getOutputStream();
while ((len = br.read(buf)) > 0)
out.write(buf, 0, len);
br.close();
out.close();
} catch (Exception e) {
System.err.println(e);
}
}
}
至此,上面的简单的小需求就完成啦。实现起来比较简单,只要思路明确就很容易做的。当然了一些细节处理也都可以随便换种方式实现。我这里只提供一种实现的思路。
至于题目上说的自动升级提示,可以是每次用户登录以后获取当前的app版本号,调用接口查询当前最新版的版本号,如果不一样,就弹出有新版本提示升级的页面。
说起强制升级也是最近开发遇到的一个奇葩需求 ,一个erp配套的app,所以要求强制升级。而这里的实现就是不管点确认还是取消都会到走到下载新apk的接口(这个实现简直就是流氓),而且继续往下斗智斗勇,甲方说有的员工点完升级,下载完新的包但是不安装,所以接下来我们前端又做了不管跳转哪个页面都要再判断下当前版本号和系统最新版本号。。只能说只要思想不滑坡,办法总比问题多。挺有意思的一件事。
本篇文章就到这里,如果稍微帮到你了记得点个喜欢点个关注,也祝大家工作顺顺利利!如果你遇到什么更奇葩的需求欢迎留言一起吐槽或者集思广益讨论解决办法!
网友评论