@@ -148,12 +148,21 @@
+ width="90">
+
+
@@ -169,8 +178,8 @@
@click="click_order_info(scope.row)">详情
取消
+ size="mini" type="danger"
+ @click="cancel_order(scope.row)">取消
@@ -213,16 +222,19 @@
}
},
methods: {
- cancel_order(order){
+ cancel_order(order) {
my_order(res => {
if (res.code === 1000) {
this.$message.success("操作成功");
- this.get_data_from_tabname()
+ this.get_data_from_tabname({
+ "size": this.pagination.pagesize,
+ "page": this.pagination.currentPage
+ })
} else {
this.$message.error("失败了 " + res.msg)
}
}, {
- methods: 'PUT', data: {order_number: order.order_number,act:'cancel'},
+ methods: 'PUT', data: {order_number: order.order_number, act: 'cancel'},
})
},
goto_pay(order) {
@@ -230,7 +242,7 @@
if (res.code === 1000) {
this.$message.success("正在跳转支付平台");
let pay_url = res.data;
- if(pay_url && pay_url.length > 10){
+ if (pay_url && pay_url.length > 10) {
window.location.href = pay_url
}
} else {
@@ -241,15 +253,17 @@
})
},
click_order_info(order) {
- my_order(res => {
- if (res.code === 1000) {
- this.get_data_from_tabname()
- } else {
- this.$message.error("失败了 " + res.msg)
- }
- }, {
- methods: 'PUT', data: {order_number: order.order_number,act:'status'},
- });
+ if (order.status === 1 || order.status === 2) {
+ my_order(res => {
+ if (res.code === 1000) {
+ this.get_data_from_tabname()
+ } else {
+ this.$message.error("失败了 " + res.msg)
+ }
+ }, {
+ methods: 'PUT', data: {order_number: order.order_number, act: 'status'},
+ });
+ }
this.show_order_info = true;
this.current_order_info = order;
diff --git a/fir_client/src/components/user/FirUserStorage.vue b/fir_client/src/components/user/FirUserStorage.vue
index d765bf3..4155bd5 100644
--- a/fir_client/src/components/user/FirUserStorage.vue
+++ b/fir_client/src/components/user/FirUserStorage.vue
@@ -90,17 +90,19 @@
-
- 迁移数据并保存
-
-
-
-
-
-
-
+
+
+ 迁移数据并保存
+
+
+ 强制迁移,忽略数据迁移失败错误,可能会导致数据丢失
+
+
+
@@ -401,7 +403,7 @@
});
},
- change_storage_info() {
+ change_storage_info(force) {
this.$confirm('此操作将导致应用,图片,显示下载异常, 是否继续?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@@ -418,8 +420,10 @@
if (data.code === 1000) {
this.$message.success('修改成功');
this.getstorageinfoFun();
+ } else {
+ this.$message.error(data.msg)
}
- }, {"methods": 'PUT', 'data': {'use_storage_id': this.use_storage_id}});
+ }, {"methods": 'PUT', 'data': {'use_storage_id': this.use_storage_id, 'force': force}});
this.getstorageinfoFun();
}).catch(() => {
this.$message({
diff --git a/fir_ser/api/base_views.py b/fir_ser/api/base_views.py
index 0d828e2..fa7d0b3 100644
--- a/fir_ser/api/base_views.py
+++ b/fir_ser/api/base_views.py
@@ -17,7 +17,8 @@ from api.utils.serializer import AppsSerializer, AppReleaseSerializer
from rest_framework.pagination import PageNumberPagination
import logging
from fir_ser.settings import SERVER_DOMAIN
-from api.utils.utils import is_valid_domain, delete_local_files, delete_app_screenshots_files
+from api.utils.utils import delete_local_files, delete_app_screenshots_files
+from api.utils.baseutils import is_valid_domain
logger = logging.getLogger(__name__)
diff --git a/fir_ser/api/migrations/0041_auto_20210416_1438.py b/fir_ser/api/migrations/0041_auto_20210416_1438.py
new file mode 100644
index 0000000..12b1659
--- /dev/null
+++ b/fir_ser/api/migrations/0041_auto_20210416_1438.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.0.3 on 2021-04-16 14:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ('api', '0040_auto_20210413_1010'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='order',
+ name='status',
+ field=models.SmallIntegerField(
+ choices=[(0, '交易成功'), (1, '待支付'), (2, '订单已创建'), (3, '退费申请中'), (4, '已退费'), (5, '主动取消'), (6, '超时取消')],
+ verbose_name='状态'),
+ ),
+ ]
diff --git a/fir_ser/api/models.py b/fir_ser/api/models.py
index 73f055c..2684617 100644
--- a/fir_ser/api/models.py
+++ b/fir_ser/api/models.py
@@ -360,7 +360,7 @@ class Order(models.Model):
actual_amount = models.BigIntegerField(verbose_name="实付金额,单位分")
actual_download_times = models.BigIntegerField(verbose_name="实际购买的数量", default=0)
actual_download_gift_times = models.BigIntegerField(verbose_name="实际赠送的数量", default=0)
- status_choices = ((0, '交易成功'), (1, '待支付'), (2, '订单已创建'), (3, '退费申请中'), (4, '已退费'), (5, '主动取消'), (6, '超时取消'))
+ status_choices = ((0, '交易成功'), (1, '待支付'), (2, '订单已创建'), (3, '退费申请中'), (4, '已退费'), (5, '主动取消'), (6, '超时取消'))
status = models.SmallIntegerField(choices=status_choices, verbose_name="状态")
order_type_choices = ((0, '用户下单'), (1, '后台充值'),)
order_type = models.SmallIntegerField(choices=order_type_choices, default=0, verbose_name="订单类型")
diff --git a/fir_ser/api/utils/app/supersignutils.py b/fir_ser/api/utils/app/supersignutils.py
index a907bdb..b1d96e5 100644
--- a/fir_ser/api/utils/app/supersignutils.py
+++ b/fir_ser/api/utils/app/supersignutils.py
@@ -11,9 +11,10 @@ from api.models import APPSuperSignUsedInfo, AppUDID, AppIOSDeveloperInfo, AppRe
UDIDsyncDeveloper, DeveloperAppID, DeveloperDevicesID
from api.utils.app.randomstrings import make_app_uuid, make_from_user_uuid
from api.utils.storage.caches import del_cache_response_by_short, send_msg_over_limit
-from api.utils.utils import file_format_path, delete_app_to_dev_and_file, delete_app_profile_file, \
- send_ios_developer_active_status, get_profile_full_path, delete_local_files, download_files_form_oss, \
+from api.utils.utils import delete_app_to_dev_and_file, send_ios_developer_active_status, delete_local_files, \
+ download_files_form_oss, \
get_developer_udided
+from api.utils.baseutils import file_format_path, delete_app_profile_file, get_profile_full_path
from api.utils.storage.storage import Storage
from django.core.cache import cache
diff --git a/fir_ser/api/utils/baseutils.py b/fir_ser/api/utils/baseutils.py
new file mode 100644
index 0000000..ee6fee5
--- /dev/null
+++ b/fir_ser/api/utils/baseutils.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+# -*- coding:utf-8 -*-
+# project: 4月
+# author: NinEveN
+# date: 2021/4/16
+
+import os, re
+from fir_ser.settings import SUPER_SIGN_ROOT
+from api.models import AppReleaseInfo
+from api.utils.app.randomstrings import make_app_uuid
+from django.core.validators import validate_email
+from django.core.exceptions import ValidationError
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+def get_app_d_count_by_app_id(app_id):
+ d_count = 1
+ binary_size = AppReleaseInfo.objects.filter(is_master=True, app_id__app_id=app_id).values('binary_size')
+ if binary_size and binary_size > 0:
+ d_count += binary_size // 1024 // 1024 // 100
+ return d_count
+
+
+def file_format_path(user_obj, auth=None, email=None):
+ if email:
+ cert_dir_name = make_app_uuid(user_obj, email)
+ else:
+ pkey = auth.get("username")
+ if auth.get("issuer_id"):
+ pkey = auth.get("issuer_id")
+ cert_dir_name = make_app_uuid(user_obj, pkey)
+ cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name)
+ if not os.path.isdir(cert_dir_path):
+ os.makedirs(cert_dir_path)
+ file_format_path_name = os.path.join(cert_dir_path, cert_dir_name)
+ return file_format_path_name
+
+
+def get_profile_full_path(developer_obj, app_obj):
+ pkey = developer_obj.email
+ if developer_obj.issuer_id:
+ pkey = developer_obj.issuer_id
+ cert_dir_name = make_app_uuid(developer_obj.user_id, pkey)
+ cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name, "profile")
+ provision_name = os.path.join(cert_dir_path, app_obj.app_id)
+ return provision_name + '.mobileprovision'
+
+
+def delete_app_profile_file(developer_obj, app_obj):
+ file = get_profile_full_path(developer_obj, app_obj)
+ try:
+ if os.path.isfile(file):
+ os.remove(file)
+ except Exception as e:
+ logger.error("delete_app_profile_file developer_obj:%s app_obj:%s file:%s Exception:%s" % (
+ developer_obj, app_obj, file, e))
+
+
+def is_valid_domain(value):
+ pattern = re.compile(
+ r'^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|'
+ r'([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|'
+ r'([a-zA-Z0-9][-_.a-zA-Z0-9]{0,61}[a-zA-Z0-9]))\.'
+ r'([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}.[a-zA-Z]{2,3})$'
+ )
+ return True if pattern.match(value) else False
+
+
+def is_valid_phone(value):
+ phone_pat = re.compile('^(13\d|14[5|7]|15\d|166|17[3|6|7]|18\d)\d{8}$')
+ return True if str(value) and re.search(phone_pat, str(value)) else False
+
+
+def is_valid_email(email):
+ try:
+ validate_email(email)
+ return True
+ except ValidationError:
+ return False
diff --git a/fir_ser/api/utils/pay/ali.py b/fir_ser/api/utils/pay/ali.py
index 598d448..3fda8c7 100644
--- a/fir_ser/api/utils/pay/ali.py
+++ b/fir_ser/api/utils/pay/ali.py
@@ -76,7 +76,7 @@ class Alipay(object):
data = self.alipay.api_alipay_trade_query(out_trade_no=out_trade_no)
# (0, '交易成功'), (1, '待支付'), (2, '订单已创建'), (3, '退费申请中'), (4, '已退费'), (5, '主动取消'), (6, '超时取消')
code = data.get("code", '')
- logger.info("out_trade_no: %s info:%s"%(out_trade_no, data))
+ logger.info("out_trade_no: %s info:%s" % (out_trade_no, data))
if code == '10000':
trade_status = data.get("trade_status", '')
if trade_status in ['TRADE_SUCCESS']:
diff --git a/fir_ser/api/utils/storage/caches.py b/fir_ser/api/utils/storage/caches.py
index 61f164e..5dbdee3 100644
--- a/fir_ser/api/utils/storage/caches.py
+++ b/fir_ser/api/utils/storage/caches.py
@@ -12,7 +12,7 @@ from django.utils import timezone
from fir_ser.settings import CACHE_KEY_TEMPLATE, SERVER_DOMAIN, SYNC_CACHE_TO_DATABASE, DEFAULT_MOBILEPROVISION, \
USER_FREE_DOWNLOAD_TIMES, AUTH_USER_FREE_DOWNLOAD_TIMES
from api.utils.storage.storage import Storage, LocalStorage
-from api.utils.utils import file_format_path
+from api.utils.baseutils import get_app_d_count_by_app_id, file_format_path
import logging
from django.db.models import F
@@ -96,15 +96,20 @@ def get_download_url_by_cache(app_obj, filename, limit, isdownload=True, key='',
def get_app_instance_by_cache(app_id, password, limit, udid):
if udid:
- return Apps.objects.filter(app_id=app_id).values("pk", 'user_id', 'type', 'password', 'issupersign',
- 'user_id__certification__status').first()
+ app_info = Apps.objects.filter(app_id=app_id).values("pk", 'user_id', 'type', 'password', 'issupersign',
+ 'user_id__certification__status').first()
+ if app_info:
+ app_info['d_count'] = get_app_d_count_by_app_id(app_id)
+ return app_info
app_key = "_".join([CACHE_KEY_TEMPLATE.get("app_instance_key"), app_id])
app_obj_cache = cache.get(app_key)
if not app_obj_cache:
app_obj_cache = Apps.objects.filter(app_id=app_id).values("pk", 'user_id', 'type', 'password',
'issupersign',
'user_id__certification__status').first()
- cache.set(app_key, app_obj_cache, limit)
+ if app_obj_cache:
+ app_obj_cache['d_count'] = get_app_d_count_by_app_id(app_id)
+ cache.set(app_key, app_obj_cache, limit)
app_password = app_obj_cache.get("password")
diff --git a/fir_ser/api/utils/utils.py b/fir_ser/api/utils/utils.py
index daed33c..3d9806b 100644
--- a/fir_ser/api/utils/utils.py
+++ b/fir_ser/api/utils/utils.py
@@ -3,11 +3,11 @@
# project: 5月
# author: liuyu
# date: 2020/5/7
-import os, re, json, requests, datetime, random
-from fir_ser.settings import SUPER_SIGN_ROOT, SERVER_DOMAIN, CAPTCHA_LENGTH, MEDIA_ROOT
+import os, json, requests, datetime, random
+from fir_ser.settings import SERVER_DOMAIN, CAPTCHA_LENGTH, MEDIA_ROOT
from api.models import APPSuperSignUsedInfo, APPToDeveloper, \
UDIDsyncDeveloper, UserInfo, AppReleaseInfo, AppScreenShot
-from api.utils.app.randomstrings import make_app_uuid
+from api.utils.storage.caches import get_app_d_count_by_app_id
from api.utils.storage.localApi import LocalStorage
from api.utils.storage.storage import Storage
from api.utils.tempcaches import tmpCache
@@ -16,39 +16,13 @@ from api.utils.sendmsg.sendmsg import SendMessage
from django.db.models import Sum
from captcha.models import CaptchaStore
from captcha.helpers import captcha_image_url
-from django.core.validators import validate_email
-from django.core.exceptions import ValidationError
+from api.utils.storage.caches import consume_user_download_times
from django.core.cache import cache
import logging
logger = logging.getLogger(__name__)
-def file_format_path(user_obj, auth=None, email=None):
- if email:
- cert_dir_name = make_app_uuid(user_obj, email)
- else:
- pkey = auth.get("username")
- if auth.get("issuer_id"):
- pkey = auth.get("issuer_id")
- cert_dir_name = make_app_uuid(user_obj, pkey)
- cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name)
- if not os.path.isdir(cert_dir_path):
- os.makedirs(cert_dir_path)
- file_format_path_name = os.path.join(cert_dir_path, cert_dir_name)
- return file_format_path_name
-
-
-def get_profile_full_path(developer_obj, app_obj):
- pkey = developer_obj.email
- if developer_obj.issuer_id:
- pkey = developer_obj.issuer_id
- cert_dir_name = make_app_uuid(developer_obj.user_id, pkey)
- cert_dir_path = os.path.join(SUPER_SIGN_ROOT, cert_dir_name, "profile")
- provision_name = os.path.join(cert_dir_path, app_obj.app_id)
- return provision_name + '.mobileprovision'
-
-
def delete_app_to_dev_and_file(developer_obj, app_id):
APPToDeveloper_obj = APPToDeveloper.objects.filter(developerid=developer_obj, app_id_id=app_id)
if APPToDeveloper_obj:
@@ -59,16 +33,6 @@ def delete_app_to_dev_and_file(developer_obj, app_id):
APPToDeveloper_obj.delete()
-def delete_app_profile_file(developer_obj, app_obj):
- file = get_profile_full_path(developer_obj, app_obj)
- try:
- if os.path.isfile(file):
- os.remove(file)
- except Exception as e:
- logger.error("delete_app_profile_file developer_obj:%s app_obj:%s file:%s Exception:%s" % (
- developer_obj, app_obj, file, e))
-
-
def get_developer_udided(developer_obj):
SuperSignUsed_obj = APPSuperSignUsedInfo.objects.filter(developerid=developer_obj)
UDIDsyncDeveloper_obj = UDIDsyncDeveloper.objects.filter(developerid=developer_obj)
@@ -127,29 +91,6 @@ def upload_oss_default_head_img(user_obj, storage_obj):
return storage_obj.upload_file(head_img_full_path)
-def is_valid_domain(value):
- pattern = re.compile(
- r'^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|'
- r'([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|'
- r'([a-zA-Z0-9][-_.a-zA-Z0-9]{0,61}[a-zA-Z0-9]))\.'
- r'([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}.[a-zA-Z]{2,3})$'
- )
- return True if pattern.match(value) else False
-
-
-def is_valid_phone(value):
- phone_pat = re.compile('^(13\d|14[5|7]|15\d|166|17[3|6|7]|18\d)\d{8}$')
- return True if str(value) and re.search(phone_pat, str(value)) else False
-
-
-def is_valid_email(email):
- try:
- validate_email(email)
- return True
- except ValidationError:
- return False
-
-
def get_sender_token(sender, user_id, target, action, msg=None):
sms_token_obj = DownloadToken()
code = generateNumericTokenOfLength(6)
@@ -316,6 +257,11 @@ def migrating_storage_file_data(user_obj, filename, new_storage_obj, clean_old_d
def migrating_storage_data(user_obj, new_storage_obj, clean_old_data):
with cache.lock("%s_%s" % ('migrating_storage_data', user_obj.uid)):
+
+ status = user_obj.certification.status
+ auth_status = False
+ if status and status == 1:
+ auth_status = True
for app_release_obj in AppReleaseInfo.objects.filter(app_id__user_id=user_obj).all():
# 迁移APP数据
filename = get_filename_from_apptype(app_release_obj.release_id, app_release_obj.release_type)
@@ -328,6 +274,9 @@ def migrating_storage_data(user_obj, new_storage_obj, clean_old_data):
for apptodev_obj in APPToDeveloper.objects.filter(app_id=app_release_obj.app_id).all():
filename = get_filename_from_apptype(apptodev_obj.binary_file, app_release_obj.release_type)
migrating_storage_file_data(user_obj, filename, new_storage_obj, clean_old_data)
+ # 消费下载次数
+ amount = get_app_d_count_by_app_id(app_release_obj.app_id.app_id)
+ consume_user_download_times(user_obj.pk, app_release_obj.app_id, amount, auth_status)
return True
diff --git a/fir_ser/api/views/apps.py b/fir_ser/api/views/apps.py
index f5a1db5..a7306f6 100644
--- a/fir_ser/api/views/apps.py
+++ b/fir_ser/api/views/apps.py
@@ -17,7 +17,8 @@ from api.utils.serializer import AppsSerializer, AppReleaseSerializer
from rest_framework.pagination import PageNumberPagination
import logging
from fir_ser.settings import SERVER_DOMAIN
-from api.utils.utils import is_valid_domain, delete_local_files, delete_app_screenshots_files
+from api.utils.utils import delete_local_files, delete_app_screenshots_files
+from api.utils.baseutils import is_valid_domain
from api.base_views import app_delete
logger = logging.getLogger(__name__)
diff --git a/fir_ser/api/views/download.py b/fir_ser/api/views/download.py
index 157d050..7e0ec60 100644
--- a/fir_ser/api/views/download.py
+++ b/fir_ser/api/views/download.py
@@ -20,7 +20,7 @@ from api.utils.serializer import AppsShortSerializer
from api.models import Apps, AppReleaseInfo, APPToDeveloper, APPSuperSignUsedInfo
from django.http import FileResponse
import logging
-from api.utils.utils import get_profile_full_path
+from api.utils.baseutils import get_profile_full_path
from api.utils.throttle import VisitShortThrottle, InstallShortThrottle
logger = logging.getLogger(__file__)
@@ -240,10 +240,10 @@ class InstallView(APIView):
ip = request.META['REMOTE_ADDR']
logger.info("remote ip %s short %s download_url %s app_obj %s" % (ip, short, download_url, app_obj))
set_app_download_by_cache(app_id)
- amount = 1
- # 超级签需要消耗2个下载次数
+ amount = app_obj.get("d_count")
+ # 超级签需要多消耗2倍下载次数
if app_obj.get("issupersign"):
- amount += 1
+ amount *= 2
auth_status = False
status = app_obj.get('user_id__certification__status', None)
if status and status == 1:
diff --git a/fir_ser/api/views/login.py b/fir_ser/api/views/login.py
index e224801..4182a56 100644
--- a/fir_ser/api/views/login.py
+++ b/fir_ser/api/views/login.py
@@ -6,9 +6,10 @@ from django.core.cache import cache
from rest_framework.views import APIView
import binascii
import os, datetime
-from api.utils.utils import get_captcha, valid_captcha, is_valid_domain, is_valid_phone, \
- get_sender_sms_token, is_valid_email, is_valid_sender_code, get_sender_email_token, get_random_username, \
+from api.utils.utils import get_captcha, valid_captcha, \
+ get_sender_sms_token, is_valid_sender_code, get_sender_email_token, get_random_username, \
check_username_exists
+from api.utils.baseutils import is_valid_domain, is_valid_phone, is_valid_email
from api.utils.auth import ExpiringTokenAuthentication
from api.utils.response import BaseResponse
from fir_ser.settings import CACHE_KEY_TEMPLATE, SERVER_DOMAIN, REGISTER, LOGIN
diff --git a/fir_ser/api/views/order.py b/fir_ser/api/views/order.py
index 00fe73e..3658d65 100644
--- a/fir_ser/api/views/order.py
+++ b/fir_ser/api/views/order.py
@@ -69,7 +69,7 @@ class OrderView(APIView):
try:
order_number = get_order_num()
actual_amount = price_obj.price
- Order.objects.create(payment_type=0, order_number=order_number,
+ Order.objects.create(payment_type=1, order_number=order_number,
account=request.user, status=1, order_type=0, actual_amount=actual_amount,
actual_download_times=price_obj.package_size,
actual_download_gift_times=price_obj.download_count_gift)
@@ -95,12 +95,12 @@ class OrderView(APIView):
order_number = request.data.get("order_number", None)
act = request.data.get("act", None)
if order_number:
- order_obj = Order.objects.filter(account=request.user, order_number=order_number, status=1).first()
+ order_obj = Order.objects.filter(account=request.user, order_number=order_number).first()
if order_obj:
try:
if act == 'cancel' and order_obj.status != 0:
update_order_status(order_number, 5)
- elif act == 'status' and order_obj.status == 1:
+ elif act == 'status' and order_obj.status in [1, 2]:
alipay = Alipay()
alipay.update_order_status(order_obj.order_number)
except Exception as e:
diff --git a/fir_ser/api/views/storage.py b/fir_ser/api/views/storage.py
index 2f8d800..d7babb9 100644
--- a/fir_ser/api/views/storage.py
+++ b/fir_ser/api/views/storage.py
@@ -94,6 +94,7 @@ class StorageView(APIView):
logger.info("user %s update storage data:%s" % (request.user, data))
use_storage_id = data.get("use_storage_id", None)
+ force = data.get("force", None)
if use_storage_id:
if request.user.storage and use_storage_id == request.user.storage.id:
return Response(res.dict)
@@ -115,8 +116,17 @@ class StorageView(APIView):
except Exception as e:
logger.error("update user %s storage failed Exception:%s" % (request.user, e))
- res.code = 1006
- res.msg = '修改失败'
+ if force:
+ if use_storage_id == -1:
+ UserInfo.objects.filter(pk=request.user.pk).update(storage=None)
+ else:
+ UserInfo.objects.filter(pk=request.user.pk).update(storage_id=use_storage_id)
+ clean_storage_data(request.user)
+ else:
+ res.code = 1006
+ res.msg = '修改失败'
+ del_cache_storage(request.user)
+
return Response(res.dict)
storage_id = data.get("id", None)
diff --git a/fir_ser/fir_ser/settings.py b/fir_ser/fir_ser/settings.py
index 09cf2e8..010a210 100644
--- a/fir_ser/fir_ser/settings.py
+++ b/fir_ser/fir_ser/settings.py
@@ -436,14 +436,13 @@ LOGGING = {
PAY_SUCCESS_URL = 'https://app.hehelucky.cn/user/orders' # 前端页面,支付成功跳转页面
PAY_CONFIG = {
-
'ALI': {
- 'APP_ID': "2021002132612737",
+ 'APP_ID': "2021002138691845",
'APP_PRIVATE_KEY': '''-----BEGIN RSA PRIVATE KEY-----
-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
+MIIEowIBAAKCAQEAhqf2mwftoxZDNpl4eWsQ6mEfXgMlNPr6jv72ecA4hbKWqChXQmGS1T+0VsRTSoOXRDlu1MMqkTGISzHvmGb7Gmw+Myfs/ojoonD9r8fODvIo1MHolFBhr3GNQu7tqBlVJ76QgiYft+c4kkqCguuyCrd3Te6C5zCIuh6O98r4D3A3LFcm6OdScWGcfEbR+FUv+jSi2oezHeSpkhhpHGBLSsI0L9JOdHetdUE/TwN8V1HABdpnPXtp9SIu6ioIrrligX1ZRlwht2YUt0BPqPp/ApLdRIsqlhD4/ejmtMlaRqqiN6PulEThBew/qaLVSXIr2HCSXtwbki3pFMFOcsjF2wIDAQABAoIBADp4sQL83FnXDvSki8XdkgjUh7RhFUT+PtLdL9YKfADCXd1DNzDiAcqL0RlkQu62WXcMoW3OGavWoGJWmr3I6fy9R/0atzSH6syu19n+nyGqUcShNwdAKErwufB4o8Y8yddqToHVYCyRQOV1aVrEUhmJNUsn6LvPPW/kWRyMjE7XQDFHpL5/Ly7pXe+f9Btm37ZuePTPsm65P88C3GznjZxXhY1LBWFKLPG1470xdReduyeJFZS/TmK0nUxLwkACm9Gfvp7S2KJ3okUXohsGBAgJ68B9YeGiuIJiZhH2DZ1pm3/R9bSpOX3H+6vjaCsacXT5w7LZB+O0Vkthcm9vqeECgYEAvozFkIkFXXCEmCr3QVCJs4Fc6onbXEJU45xxubPhkA1wwwPrSqdubo4RHvNIus45Fn4mLzuQsaPRyJJZajvaKWC00GxhChMYj+nWgkAmABPKGwkMxzjC7wvEJkGyt87fHpK1XMFWQgfJ42VwUtmyemCMuh+A2SOekIJay93xTtkCgYEAtOhmQ4pu2cyqTzT+SD7p/VnS4sNqqM4I8NSvTuLkEo2IHnUj7YG6XoPZjn35dBvYUWWN2dwgfHXGEEzCOIwfy8GPA4eoKCDNEkMvoBVLdrEzMqg5QwG5GsIGvOuFnAzAw+D5YwEym/qmC2oBbat5jsAGT2rMmU5MnaS8a7lvcdMCgYEAiusQQb5TZfrZACMa3cg8i9y9A9R7UzicsM/mbW+B+8aAtfxOdr+4F+uE+d594IrmPcq8ReUUKR34nFRt0bBO7amuSOEqofCoEIt3MsBXs+i5iJpBcaClJSeb2hQ9mhm8uopUpInjPAJ3okva5twFbYikMDE1e5inSk1uqoBlI4kCgYB4rzDJjeg1U9upy2h3OcFPSkTtEgBtbEV6o+fvcF1GIzTTXMIDB7AUrVDNRizL0GeWpXDkDX1+ifL/nLVUk+YCP7XwXOdJHdiwfjGfUZVuMPg+qwrIMLYTq6xjC5uuZrOR+NtluL7SX3u10ZnyV5pYKLIM+OpUu29RGzy3gJVgEQKBgCC9vXS7P9RHTAxYEG4WOzv0tjFUtPOsaHenvNbc7nVe2Kkre0/TO+EtnuhINmJp2y5UEve6cLK2sPnbT8raarjPuomDfN0hwEx3jZd+rPdB/tdRH0LMLBu28TlzHllJYjbINn+NXc0adbqeuA4ziXTZow5yX5J+i9dy55A1bvie
-----END RSA PRIVATE KEY-----''',
'ALI_PUBLIC_KEY': '''-----BEGIN CERTIFICATE-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Fbo1uH7TRBQUizDFKDSHTqlVCtsRCQuIoD0sqKUOaZ4F1mL9Wz97g//QKkDmQdT6VoDUkEghnxBuZhcMCcEGGEFHICVFfcgzbQQI6ebm58TEQVt/tSIO++FXq23Yglkkd6J8fnBicZfZbTfTysaZemjTvY5+3Nyg5Jp2o3OH1oCp1Xj148laVUrFfzxPaiYyZkyf7Rcd6EdmpZDHqchmB0E1FGK/hi8VnmS9KLtTU2/bIMZeD7Mz9N/6iQPhZImaKzbDr76KSfnNdggbkrD57uhU8tMWZ2QDLYdElCFijJlTPGzVRUqxhG7Wk5JW4cfm0CPNvpBe7xvFnfeCqT6fwIDAQAB
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkru1ulQV1v4q+q38nyzgkdd3evf7C1/Ipu6K+ZFb5FiuxJ7mildkBSuKz/8+TRd+tjgk2lfc2ehK5pja3cxDO/nb25sBoWiU09rtxgXLehLsgRRhatbICrlOnYxg5aiB5odAp3NMRqore4lnVYwfIyL9M49I0G/NbQzYjUQvAQJsnHwc6a6Kuqi1CwR1WXI0sDF9w7KXC4vRFFIUTwI4bVq4HQWI7NhbgEajHM/j6D6Bh/OMcTYnJJzCja0WmZRe5flfCsELlPESOCWUMbYoaNfBzpNvvyOpmRgs9jgy2WY9SeaB9hxwkpr8tOd2Sc7j3221JKCyDaFAX+4zPy7/fQIDAQAB
-----END CERTIFICATE-----''',
'APP_NOTIFY_URL': 'https://app.hehelucky.cn/api/v1/fir/server/pay_success', # 支付支付回调URL
# 'RETURN_URL': 'https://app.hehelucky.cn/api/v1/fir/server/pay_success', # 支付前端页面回调URL