Django的数据库model
django 数据库还真好使,抛开效率问题,感觉简直好用的不得了
apps表结构分析
- 该APP所属用户
- APP平台类型【android|ios】
- 应用名称
- 应用bundleId
- 创建时间
- 授权下载访问密码
- 下载页可见
- 描述
- 更新时间
- 是否有关联应用【下载码合并】
基于表分析,然后得出django model 大概设计字段
class Apps(models.Model):
app_id = models.CharField(max_length=64, unique=True, db_index=True) # ,唯一标识
user_id = models.ForeignKey(to="UserInfo", verbose_name="用户ID", on_delete=models.CASCADE)
type_choices = ((0, 'android'), (1, 'ios'))
type = models.SmallIntegerField(choices=type_choices, default=0, verbose_name="类型")
status_choices = ((0, '封禁'), (1, '正常'), (2, '违规'))
status = models.SmallIntegerField(choices=status_choices, default=1, verbose_name="应用状态")
name = models.CharField(max_length=32, blank=True, null=True, verbose_name="应用名称")
short = models.CharField(max_length=16, unique=True, verbose_name="短链接", db_index=True)
bundle_id = models.CharField(max_length=64, blank=True, verbose_name="bundle id")
has_combo = models.OneToOneField(to="Apps", related_name='combo_app_info',
verbose_name="关联应用", on_delete=models.SET_NULL, null=True, blank=True)
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
count_hits = models.BigIntegerField(verbose_name="下载次数", default=0)
password = models.CharField(verbose_name="访问密码", blank=True, help_text='默认 没有密码', max_length=32)
isshow = models.BooleanField(verbose_name="下载页可见", default=True)
description = models.TextField('描述', blank=True, null=True, default=None, )
updated_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
class Meta:
verbose_name = '应用信息'
verbose_name_plural = "应用信息"
indexes = [models.Index(fields=['app_id']), models.Index(fields=['id', 'user_id', 'type'])]
def __str__(self):
return "%s %s-%s" % (self.name, self.get_type_display(), self.short)
这个仅仅是应用表数据,还需要更详细的版本表记录
class AppReleaseInfo(models.Model):
is_master = models.BooleanField(verbose_name="是否master版本", default=True)
release_id = models.CharField(max_length=64, unique=True, verbose_name="release 版本id", db_index=True)
app_id = models.ForeignKey(to="Apps", on_delete=models.CASCADE, verbose_name="属于哪个APP")
build_version = models.CharField(max_length=64, verbose_name="build版本", blank=True)
app_version = models.CharField(max_length=64, verbose_name="app版本", blank=True)
release_choices = ((0, 'android'), (1, 'adhoc'), (2, 'Inhouse'), (3, 'unknown'))
release_type = models.SmallIntegerField(choices=release_choices, default=0, verbose_name="版本类型")
minimum_os_version = models.CharField(max_length=64, verbose_name="应用可安装的最低系统版本")
binary_size = models.BigIntegerField(verbose_name="应用大小")
binary_url = models.CharField(max_length=128, blank=True, verbose_name="第三方下载URL")
icon_url = models.CharField(max_length=128, blank=True, verbose_name="图标url")
changelog = models.TextField('更新日志', blank=True, null=True, default=None, )
udid = models.TextField('ios内测版 udid', blank=True, null=True, default='', )
distribution_name = models.CharField(max_length=128, null=True, blank=True, default='', verbose_name="企业签名")
created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
class Meta:
verbose_name = '应用详情'
verbose_name_plural = "应用详情"
def __str__(self):
return "%s-%s" % (self.app_id, self.release_id)
这样,通过这两张表,就差不多把应用一些基本信息给包含了,如果有新字段,后期还可以继续增加
那么,我们就可以着手开发上传的api了
Vue上传页面
很明显,我们发现了好多应用的信息,比如应用名称,应用类型,应用大小等等,这些信息是怎么通过前端web页面获取到呢?
这就不得不提一个好用的js插件了app-info-parser
,本人使用的是0.3.9版本,暂未发现问题
"app-info-parser": "^0.3.9"
官方的github app-info-parser 有兴趣的小伙伴可以进去看下
由于IPA和apk应用解析的内容有写差别,为了统一数据格式,需要我们针对这些信息,进行二次封装
export function getappinfo(file, successcallback, errcallback) {
const AppInfoParser = require('app-info-parser');
const parser = new AppInfoParser(file);
let analyseappinfo = {};
parser.parse().then(result => {
analyseappinfo.icon = result.icon;
analyseappinfo.filename = file.name;
analyseappinfo.filesize = file.size;
if (result.CFBundleDisplayName) {
analyseappinfo.appname = result.CFBundleDisplayName;
analyseappinfo.bundleid = result.CFBundleIdentifier;
analyseappinfo.version = result.CFBundleShortVersionString;
analyseappinfo.buildversion = result.CFBundleVersion;
analyseappinfo.miniosversion = result.MinimumOSVersion;
if (result.mobileProvision.ProvisionedDevices) {
analyseappinfo.release_type = 'Adhoc';
analyseappinfo.release_type_id = 1;
analyseappinfo.udid = result.mobileProvision.ProvisionedDevices;
} else {
analyseappinfo.distribution_name = result.mobileProvision.Name + ": " + result.mobileProvision.TeamName;
analyseappinfo.release_type = 'Inhouse';
analyseappinfo.release_type_id = 2;
analyseappinfo.udid = [];
}
analyseappinfo.type = 'iOS';
} else {
analyseappinfo.appname = result.application.label[0];
analyseappinfo.bundleid = result.package;
analyseappinfo.version = result.versionName;
analyseappinfo.buildversion = result.versionCode;
analyseappinfo.miniosversion = result.usesSdk.minSdkVersion;
analyseappinfo.type = 'Android';
analyseappinfo.release_type = 'Android';
analyseappinfo.release_type_id = 0;
}
successcallback(analyseappinfo)
}).catch(err => {
errcallback(err);
});
}
封装之后,无论是ipa还是apk,获取的数据都是统一的格式
前端数据解析和后端表结构已经完成,那,接下来就可以上传应用,存储操作了