diff --git a/fir_client/src/components/FirAppInfosbaseinfo.vue b/fir_client/src/components/FirAppInfosbaseinfo.vue index e818d0c..51d36f3 100644 --- a/fir_client/src/components/FirAppInfosbaseinfo.vue +++ b/fir_client/src/components/FirAppInfosbaseinfo.vue @@ -57,7 +57,12 @@ style="width: 155px;height: 288px;margin-right: 20px;background-color: #d1eef9;float: left" fit="scale-down" @click="delscreen(screen.id)" - v-for="(screen) in currentapp.screenshots" :key="screen.id" :src="screen.url" alt=""/> + v-for="(screen) in currentapp.screenshots" :key="screen.id" :src="screen.url" alt=""> +
+ 加载失败 +
+
+ + diff --git a/fir_client/src/router/index.js b/fir_client/src/router/index.js index 69dcb41..22c70a0 100644 --- a/fir_client/src/router/index.js +++ b/fir_client/src/router/index.js @@ -113,6 +113,11 @@ const router = new VueRouter({ // component: FirUserProfileChangePwd component: () => import("@/components/FirUserProfileChangePwd"), + }, { + path: 'certification', + name: 'FirUserProfileCertification', + component: () => import("@/components/FirUserProfileCertification"), + }, ] } diff --git a/fir_client/src/utils/index.js b/fir_client/src/utils/index.js index 8823f35..257d564 100644 --- a/fir_client/src/utils/index.js +++ b/fir_client/src/utils/index.js @@ -171,7 +171,7 @@ export function uploadaliyunoss(file, certinfo, app, successcallback, processcal } -import {loginFun, uploadstorage} from '../restful' +import {getuploadurl, loginFun, uploadimgs, uploadstorage} from '../restful' export function uploadlocalstorage(file, certinfo, app, successcallback, processcallback) { uploadstorage(certinfo, file, successcallback, processcallback) @@ -476,3 +476,85 @@ export function show_beautpic(father, canvas, nb = 666) { createDots(); requestAnimationFrame(animateDots); } + + +function updateimgs(fthis, certinfo, callabck) { + uploadimgs(data => { + if (data.code === 1000) { + fthis.$message.success('上传成功'); + callabck() + } else { + fthis.$message.error('更新失败: ' + data.msg); + } + }, {'methods': 'PUT', 'data': {'certinfo': certinfo}}); +} + +function uploadtostorage(fthis, file, certinfo, callabck) { + + if (certinfo.storage === 1) { + // eslint-disable-next-line no-unused-vars,no-unreachable + uploadqiniuoss(file, certinfo, this, res => { + updateimgs(fthis, certinfo, callabck); + + }, process => { + fthis.uploadprocess = process; + }) + } else if (certinfo.storage === 2) { + // eslint-disable-next-line no-unused-vars + uploadaliyunoss(file, certinfo, this, res => { + updateimgs(fthis, certinfo, callabck); + }, process => { + fthis.uploadprocess = process; + }); + + } else { + //本地 + if (certinfo.domain_name) { + certinfo.upload_url = getuploadurl(certinfo.domain_name) + } else { + certinfo.upload_url = getuploadurl(); + } + // eslint-disable-next-line no-unused-vars,no-unreachable + uploadlocalstorage(file, certinfo, this, res => { + updateimgs(fthis, certinfo, callabck); + }, process => { + fthis.uploadprocess = process; + }) + } + +} + +/** + * @return {boolean} + */ +export function AvatarUploadUtils(fthis, file, params, callabck) { + const isLt2M = file.size / 1024 / 1024 < 2; + if (file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg') { + if (isLt2M) { + uploadimgs(data => { + if (data.code === 1000) { + // eslint-disable-next-line no-console + // console.log(data.data); + let certinfo = data.data; + certinfo.ext = params.ext; + uploadtostorage(fthis, file, certinfo, callabck); + } else { + fthis.$message.error('参数有误'); + } + }, { + 'methods': 'GET', + 'data': params + }); + + return false; + } else { + fthis.$message.error('上传头像图片大小不能超过 2MB!'); + + } + } else { + fthis.$message.error('上传头像图片只能是 JPG/PNG/JPEG 格式!'); + + } + return false; + +} \ No newline at end of file diff --git a/fir_ser/api/migrations/0025_order_price.py b/fir_ser/api/migrations/0025_order_price.py new file mode 100644 index 0000000..56cc8bb --- /dev/null +++ b/fir_ser/api/migrations/0025_order_price.py @@ -0,0 +1,53 @@ +# Generated by Django 3.0.3 on 2021-03-29 14:10 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0024_auto_20210324_1751'), + ] + + operations = [ + migrations.CreateModel( + name='Price', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=128, unique=True, verbose_name='下载包唯一名称')), + ('title', models.CharField(max_length=128, verbose_name='下载包名称')), + ('description', models.CharField(max_length=128, verbose_name='下载包描述')), + ('price', models.FloatField(verbose_name='下载包价格')), + ('package_size', models.BigIntegerField(verbose_name='下载包次数')), + ('download_count_gift', models.IntegerField(default=0, verbose_name='赠送下载次数')), + ('is_enable', models.BooleanField(default=True, verbose_name='是否启用该价格')), + ('updated_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')), + ], + options={ + 'verbose_name': '价格列表', + 'verbose_name_plural': '价格列表', + 'unique_together': {('price', 'package_size')}, + }, + ), + migrations.CreateModel( + name='Order', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('payment_type', models.SmallIntegerField(choices=[(0, '微信'), (1, '支付宝'), (2, '优惠码'), (4, '银联')])), + ('payment_number', models.CharField(blank=True, max_length=128, null=True, verbose_name='支付第3方订单号')), + ('order_number', models.CharField(max_length=128, unique=True, verbose_name='订单号')), + ('actual_amount', models.FloatField(verbose_name='实付金额')), + ('status', models.SmallIntegerField( + choices=[(0, '交易成功'), (1, '待支付'), (2, '退费申请中'), (3, '已退费'), (4, '主动取消'), (5, '超时取消')], + verbose_name='状态')), + ('order_type', + models.SmallIntegerField(choices=[(0, '用户下单'), (1, '后台充值')], default=0, verbose_name='订单类型')), + ('date', models.DateTimeField(auto_now_add=True, verbose_name='订单生成时间')), + ('pay_time', models.DateTimeField(blank=True, null=True, verbose_name='付款时间')), + ('cancel_time', models.DateTimeField(blank=True, null=True, verbose_name='订单取消时间')), + ( + 'account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/fir_ser/api/migrations/0026_auto_20210329_1419.py b/fir_ser/api/migrations/0026_auto_20210329_1419.py new file mode 100644 index 0000000..8dce364 --- /dev/null +++ b/fir_ser/api/migrations/0026_auto_20210329_1419.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.3 on 2021-03-29 14:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0025_order_price'), + ] + + operations = [ + migrations.AlterField( + model_name='price', + name='price', + field=models.BigIntegerField(verbose_name='下载包价格'), + ), + ] diff --git a/fir_ser/api/migrations/0027_auto_20210329_1506.py b/fir_ser/api/migrations/0027_auto_20210329_1506.py new file mode 100644 index 0000000..dcde6f7 --- /dev/null +++ b/fir_ser/api/migrations/0027_auto_20210329_1506.py @@ -0,0 +1,34 @@ +# Generated by Django 3.0.3 on 2021-03-29 15:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0026_auto_20210329_1419'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='actual_download_gift_times', + field=models.BigIntegerField(default=0, verbose_name='实际赠送的数量'), + preserve_default=False, + ), + migrations.AddField( + model_name='order', + name='actual_download_times', + field=models.BigIntegerField(default=0, verbose_name='实际购买的数量'), + preserve_default=False, + ), + migrations.AlterField( + model_name='order', + name='actual_amount', + field=models.BigIntegerField(verbose_name='实付金额,单位分'), + ), + migrations.AlterField( + model_name='price', + name='price', + field=models.BigIntegerField(verbose_name='下载包价格,单位分'), + ), + ] diff --git a/fir_ser/api/migrations/0028_order_created_time.py b/fir_ser/api/migrations/0028_order_created_time.py new file mode 100644 index 0000000..1d5bf81 --- /dev/null +++ b/fir_ser/api/migrations/0028_order_created_time.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2021-03-29 15:12 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0027_auto_20210329_1506'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='created_time', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now, verbose_name='订单创建时间'), + preserve_default=False, + ), + ] diff --git a/fir_ser/api/migrations/0029_remove_order_date.py b/fir_ser/api/migrations/0029_remove_order_date.py new file mode 100644 index 0000000..6e95ab8 --- /dev/null +++ b/fir_ser/api/migrations/0029_remove_order_date.py @@ -0,0 +1,16 @@ +# Generated by Django 3.0.3 on 2021-03-29 16:27 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0028_order_created_time'), + ] + + operations = [ + migrations.RemoveField( + model_name='order', + name='date', + ), + ] diff --git a/fir_ser/api/migrations/0030_auto_20210329_1755.py b/fir_ser/api/migrations/0030_auto_20210329_1755.py new file mode 100644 index 0000000..3afdac2 --- /dev/null +++ b/fir_ser/api/migrations/0030_auto_20210329_1755.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.3 on 2021-03-29 17:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0029_remove_order_date'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='description', + field=models.TextField(blank=True, default='', null=True, verbose_name='备注'), + ), + migrations.AlterField( + model_name='order', + name='actual_download_gift_times', + field=models.BigIntegerField(default=0, verbose_name='实际赠送的数量'), + ), + migrations.AlterField( + model_name='order', + name='actual_download_times', + field=models.BigIntegerField(default=0, verbose_name='实际购买的数量'), + ), + ] diff --git a/fir_ser/api/migrations/0031_auto_20210407_2021.py b/fir_ser/api/migrations/0031_auto_20210407_2021.py new file mode 100644 index 0000000..309b690 --- /dev/null +++ b/fir_ser/api/migrations/0031_auto_20210407_2021.py @@ -0,0 +1,51 @@ +# Generated by Django 3.0.3 on 2021-04-07 20:21 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0030_auto_20210329_1755'), + ] + + operations = [ + migrations.CreateModel( + name='UserCertificationInfo', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=128, verbose_name='真实姓名')), + ('card', models.CharField(max_length=128, verbose_name='身份证号码')), + ('addr', models.CharField(max_length=128, verbose_name='居住地')), + ('mobile', models.BigIntegerField(unique=True, verbose_name='手机号码')), + ('status', models.SmallIntegerField(choices=[(0, '审核中'), (1, '审核成功'), (2, '审核失败')], default=0, + verbose_name='审核状态')), + ('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('user_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, + verbose_name='用户ID')), + ], + options={ + 'verbose_name': '用户认证信息', + 'verbose_name_plural': '用户认证信息', + }, + ), + migrations.CreateModel( + name='CertificationInfo', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('certification_url', models.CharField(blank=True, max_length=128, verbose_name='认证URL')), + ('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('user_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, + verbose_name='用户ID')), + ], + options={ + 'verbose_name': '身份证截图', + 'verbose_name_plural': '身份证截图', + }, + ), + migrations.AddIndex( + model_name='usercertificationinfo', + index=models.Index(fields=['card'], name='api_usercer_card_246743_idx'), + ), + ] diff --git a/fir_ser/api/migrations/0032_certificationinfo_type.py b/fir_ser/api/migrations/0032_certificationinfo_type.py new file mode 100644 index 0000000..97ba559 --- /dev/null +++ b/fir_ser/api/migrations/0032_certificationinfo_type.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2021-04-07 20:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0031_auto_20210407_2021'), + ] + + operations = [ + migrations.AddField( + model_name='certificationinfo', + name='type', + field=models.SmallIntegerField(choices=[(0, '国徽面照片'), (1, '人像面照片'), (2, '手持身份证照片')], default=0, + verbose_name='图像类型'), + preserve_default=False, + ), + ] diff --git a/fir_ser/api/migrations/0033_auto_20210407_2045.py b/fir_ser/api/migrations/0033_auto_20210407_2045.py new file mode 100644 index 0000000..aa43c29 --- /dev/null +++ b/fir_ser/api/migrations/0033_auto_20210407_2045.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.3 on 2021-04-07 20:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0032_certificationinfo_type'), + ] + + operations = [ + migrations.AlterField( + model_name='certificationinfo', + name='type', + field=models.SmallIntegerField(choices=[(0, '未知'), (1, '国徽面照片'), (2, '人像面照片'), (3, '手持身份证照片')], default=0, + verbose_name='图像类型'), + ), + ] diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py index e3b10ef..0289ff0 100644 --- a/fir_ser/api/models.py +++ b/fir_ser/api/models.py @@ -394,3 +394,37 @@ class Price(models.Model): def __str__(self): return "%s-%s-%s-%s" % (self.name, self.price, self.package_size, self.download_count_gift) + + +class UserCertificationInfo(models.Model): + user_id = models.ForeignKey(to="UserInfo", verbose_name="用户ID", on_delete=models.CASCADE) + name = models.CharField(max_length=128, null=False, verbose_name="真实姓名") + card = models.CharField(max_length=128, null=False, verbose_name="身份证号码") + addr = models.CharField(max_length=128, null=False, verbose_name="居住地") + mobile = models.BigIntegerField(verbose_name="手机号码", unique=True, null=False) + status_choices = ((0, '审核中'), (1, '审核成功'), (2, '审核失败')) + status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="审核状态") + created_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") + + class Meta: + verbose_name = '用户认证信息' + verbose_name_plural = "用户认证信息" + indexes = [models.Index(fields=['card'])] + + def __str__(self): + return "%s-%s" % (self.user_id, self.name) + + +class CertificationInfo(models.Model): + user_id = models.ForeignKey(to="UserInfo", verbose_name="用户ID", on_delete=models.CASCADE) + certification_url = models.CharField(max_length=128, blank=True, verbose_name="认证URL") + type_choices = ((0, '未知'), (1, '国徽面照片'), (2, '人像面照片'), (3, '手持身份证照片')) + type = models.SmallIntegerField(choices=type_choices, default=0, 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.user_id, self.certification_url) diff --git a/fir_ser/api/views/uploads.py b/fir_ser/api/views/uploads.py index 403f51c..e434988 100644 --- a/fir_ser/api/views/uploads.py +++ b/fir_ser/api/views/uploads.py @@ -160,7 +160,7 @@ class UploadView(APIView): if ftype == 'app' or ftype == 'screen': app_obj = Apps.objects.filter(app_id=app_id, user_id=request.user).first() - elif ftype and ftype == 'head': + elif ftype and ftype in ['head', 'certification']: if request.user.uid != app_id: res.code = 1007 res.msg = '该用户不存在' @@ -176,7 +176,7 @@ class UploadView(APIView): res.code = 1006 res.msg = '类型不允许' else: - upload_key = make_from_user_uuid(request.user) + '.' + app_type + upload_key = make_from_user_uuid(request.user) + '.' + app_type + settings.FILE_UPLOAD_TMP_KEY upload_token = storage.get_upload_token(upload_key) storage_type = storage.get_storage_type() res.data = { @@ -231,7 +231,7 @@ class UploadView(APIView): # res.code = 1006 # res.msg = '该应用不存在' # return Response(res.dict) - elif ftype and ftype == 'head': + elif ftype and ftype in ['head', 'certification']: if request.user.uid != app_id: res.code = 1007 res.msg = '该用户不存在' @@ -296,15 +296,23 @@ class UploadView(APIView): logger.info("user %s update img %s info" % (request.user, app_id)) ftype = certinfo.get('ftype', None) - storage = Storage(request.user) + upload_key = certinfo.get("upload_key", None) + if ftype and upload_key: + storage = Storage(request.user) + new_upload_key = upload_key.strip(settings.FILE_UPLOAD_TMP_KEY) + else: + res.msg = '参数有误' + res.code = 1008 + return Response(res.dict) if ftype and app_id and ftype == 'app': app_obj = Apps.objects.filter(app_id=app_id, user_id=request.user).first() if app_obj: release_obj = AppReleaseInfo.objects.filter(app_id=app_obj, is_master=True).first() if release_obj: old_file_key = release_obj.icon_url - release_obj.icon_url = certinfo.get("upload_key") + release_obj.icon_url = new_upload_key release_obj.save() + storage.rename_file(upload_key, new_upload_key) del_cache_response_by_short(app_id) storage.delete_file(old_file_key) return Response(res.dict) @@ -313,23 +321,35 @@ class UploadView(APIView): if app_obj: scount = AppScreenShot.objects.filter(app_id=app_obj).count() if scount >= 5: - storage.delete_file(certinfo.get("upload_key")) + storage.delete_file(upload_key) res.msg = '最多支持五张截图' res.code = 1009 return Response(res.dict) - AppScreenShot.objects.create(app_id=app_obj, screenshot_url=certinfo.get("upload_key")) + AppScreenShot.objects.create(app_id=app_obj, screenshot_url=new_upload_key) + storage.rename_file(upload_key, new_upload_key) del_cache_response_by_short(app_id) return Response(res.dict) - elif ftype and app_id and ftype == 'head': + elif ftype and app_id and ftype in ['head', 'certification']: if request.user.uid != app_id: res.code = 1007 res.msg = '该用户不存在' return Response(res.dict) - old_file_key = request.user.head_img - UserInfo.objects.filter(pk=request.user.id).update(head_img=certinfo.get("upload_key")) - if old_file_key != "" or old_file_key != 'head_img.jpeg': - storage.delete_file(old_file_key) + if ftype == 'head': + old_file_key = request.user.head_img + UserInfo.objects.filter(pk=request.user.id).update(head_img=new_upload_key) + if old_file_key != "" or old_file_key != 'head_img.jpeg': + storage.delete_file(old_file_key) + storage.rename_file(upload_key, new_upload_key) + elif ftype == 'certification': + ext = certinfo.get('ext', None) + if ext: + ptype = ext.get('type', None) + if ptype is not None: + pass + pass + else: + pass return Response(res.dict) else: