@@ -4,9 +4,10 @@ from django.conf import settings |
||
| 4 | 4 |
from django_logit import logit |
| 5 | 5 |
from django_response import response |
| 6 | 6 |
|
| 7 |
-from kodo.decorators import check_admin |
|
| 8 |
-from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo |
|
| 9 | 7 |
from account.models import LensmanInfo |
| 8 |
+from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo |
|
| 9 |
+from kodo.decorators import check_admin |
|
| 10 |
+ |
|
| 10 | 11 |
|
| 11 | 12 |
@logit(res=True) |
| 12 | 13 |
@check_admin |
@@ -21,4 +22,4 @@ def add_lensman_contribution_income_api(request, administrator): |
||
| 21 | 22 |
|
| 22 | 23 |
LensmanContributionActivityIncomeExpensesInfo.objects.update_or_create(contribution_id=contribution_id, lensman_id=lensman.lensman_id, activity_id=activity_id, user_id=user_id, defaults={'amount': amount})
|
| 23 | 24 |
|
| 24 |
- return response(200, '增加摄影师投稿收入成功') |
|
| 25 |
+ return response(200, '增加摄影师投稿收入成功') |
@@ -4,8 +4,8 @@ from django.conf import settings |
||
| 4 | 4 |
from django_logit import logit |
| 5 | 5 |
from django_response import response |
| 6 | 6 |
|
| 7 |
-from kodo.decorators import check_admin |
|
| 8 | 7 |
from apps.contract.models import LensmanContributionContractInfo |
| 8 |
+from kodo.decorators import check_admin |
|
| 9 | 9 |
|
| 10 | 10 |
|
| 11 | 11 |
@logit(res=True) |
@@ -16,7 +16,7 @@ def get_signed_contribtion_contract_file_api(request, administrator): |
||
| 16 | 16 |
|
| 17 | 17 |
contract = LensmanContributionContractInfo.objects.filter(contribution_id=contribution_id, user_id=user_id).first() |
| 18 | 18 |
|
| 19 |
- operator = {
|
|
| 19 |
+ operator = {
|
|
| 20 | 20 |
"UserId": settings.CONTRACT_LENSMAN_CONTRIBUTION_OPERATOR_ID |
| 21 | 21 |
} |
| 22 | 22 |
|
@@ -1,6 +1,7 @@ |
||
| 1 | 1 |
# -*- coding: utf-8 -*- |
| 2 | 2 |
|
| 3 | 3 |
import base64 |
| 4 |
+import json |
|
| 4 | 5 |
|
| 5 | 6 |
import requests |
| 6 | 7 |
from django_logit import logit |
@@ -12,7 +13,7 @@ from apps.contract.models import LensmanContributionContractInfo |
||
| 12 | 13 |
from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo |
| 13 | 14 |
from member.models import MemberActivityContributionInfo |
| 14 | 15 |
from utils.redis.rimage import get_images_data |
| 15 |
-from utils.tencentcloud.ess import (create_document, create_flow, create_scheme_url, start_flow, |
|
| 16 |
+from utils.tencentcloud.ess import (callback_decode, create_document, create_flow, create_scheme_url, start_flow, |
|
| 16 | 17 |
test_upload_document_files, upload_document_files) |
| 17 | 18 |
|
| 18 | 19 |
|
@@ -181,4 +182,16 @@ def get_contribtion_contract_sign_mppath(lensman, FlowId): |
||
| 181 | 182 |
|
| 182 | 183 |
@logit(body=True, res=True) |
| 183 | 184 |
def ess_callback(request): |
| 185 |
+ # curl http://127.0.0.1:8888/api/mp/ess/callback -H 'Content-type: application/json' -X POST -d '{"encrypt":"62KE4r5Wz0yHzEpMOwVRbM1KV0"}'
|
|
| 186 |
+ data = json.loads(request.body) |
|
| 187 |
+ data = callback_decode(data['encrypt']) |
|
| 188 |
+ MsgType = data.get('MsgType')
|
|
| 189 |
+ if MsgType == 'FlowStatusChange': |
|
| 190 |
+ MsgData = data.get('MsgData', {})
|
|
| 191 |
+ FlowId = MsgData.get('FlowId')
|
|
| 192 |
+ # DocumentId = MsgData.get('DocumentId')
|
|
| 193 |
+ FlowCallbackStatus = MsgData.get('FlowCallbackStatus', -1)
|
|
| 194 |
+ Approvers = MsgData.get('Approvers') or [{}]
|
|
| 195 |
+ ApproveCallbackStatus = Approvers[-1].get('ApproveCallbackStatus', -1)
|
|
| 196 |
+ LensmanContributionContractInfo.objects.filter(flow_id=FlowId).update(tencent_contract_status=FlowCallbackStatus, tencent_approve_status=ApproveCallbackStatus) |
|
| 184 | 197 |
return response() |
@@ -1,3 +1,13 @@ |
||
| 1 |
+# -*- coding: utf-8 -*- |
|
| 2 |
+ |
|
| 1 | 3 |
from django.contrib import admin |
| 2 | 4 |
|
| 3 |
-# Register your models here. |
|
| 5 |
+from apps.contract.models import LensmanContributionContractInfo |
|
| 6 |
+ |
|
| 7 |
+ |
|
| 8 |
+class LensmanContributionContractInfoAdmin(admin.ModelAdmin): |
|
| 9 |
+ list_display = ('contract_id', 'user_id', 'lensman_id', 'activity_id', 'contribution_id', 'flow_id', 'document_id', 'tencent_contract_status', 'tencent_approve_status', 'status', 'created_at', 'updated_at')
|
|
| 10 |
+ list_filter = ('brand_id', 'coupon_expire_type', 'status')
|
|
| 11 |
+ |
|
| 12 |
+ |
|
| 13 |
+admin.site.register(LensmanContributionContractInfo, LensmanContributionContractInfoAdmin) |
@@ -1,4 +1,5 @@ |
||
| 1 | 1 |
# -*- coding: utf-8 -*- |
| 2 |
+ |
|
| 2 | 3 |
from django.db import models |
| 3 | 4 |
from django.utils.translation import ugettext_lazy as _ |
| 4 | 5 |
from django_models_ext import BaseModelMixin, upload_file_path, upload_path |
@@ -8,8 +9,6 @@ from TimeConvert import TimeConvert as tc |
||
| 8 | 9 |
|
| 9 | 10 |
from utils.qiniucdn import qiniu_file_url |
| 10 | 11 |
|
| 11 |
-# Create your models here. |
|
| 12 |
- |
|
| 13 | 12 |
|
| 14 | 13 |
class LensmanContributionContractInfo(BaseModelMixin): |
| 15 | 14 |
CONTRACT_STATUS_TUPLE = ( |
@@ -67,13 +66,14 @@ class LensmanContributionContractInfo(BaseModelMixin): |
||
| 67 | 66 |
@property |
| 68 | 67 |
def contract_file_url(self): |
| 69 | 68 |
return qiniu_file_url(self.contract_file.name, bucket='tamron') |
| 70 |
- |
|
| 69 |
+ |
|
| 71 | 70 |
@property |
| 72 | 71 |
def contract_status(self): |
| 73 | 72 |
if(self.tencent_approve_status == 3 and self.tencent_contract_status == 4): |
| 74 | 73 |
return 1 |
| 75 | 74 |
else: |
| 76 | 75 |
return 0 |
| 76 |
+ |
|
| 77 | 77 |
@property |
| 78 | 78 |
def data(self): |
| 79 | 79 |
return {
|
@@ -248,8 +248,8 @@ TENCENTCLOUD = {
|
||
| 248 | 248 |
'template_id': '', |
| 249 | 249 |
'secret_id': '', |
| 250 | 250 |
'secret_key': '', |
| 251 |
- 'callback_secret_id': '', |
|
| 252 | 251 |
'callback_secret_key': '', |
| 252 |
+ 'callback_secret_token': '', |
|
| 253 | 253 |
'endpoint': 'ess.tencentcloudapi.com', |
| 254 | 254 |
'file_endpoint': 'file.ess.tencent.cn', |
| 255 | 255 |
}, |
@@ -9,6 +9,7 @@ mock==4.0.3 |
||
| 9 | 9 |
monetary==1.0.3 |
| 10 | 10 |
mysqlclient==2.1.1 |
| 11 | 11 |
pngquant==1.0.8 |
| 12 |
+pycryptodomex==3.20.0 |
|
| 12 | 13 |
pysnippets==1.1.4 |
| 13 | 14 |
pyzbar==0.1.9 |
| 14 | 15 |
qiniu==7.9.0 |
@@ -1,7 +1,9 @@ |
||
| 1 | 1 |
# -*- coding: utf-8 -*- |
| 2 | 2 |
|
| 3 |
+import base64 |
|
| 3 | 4 |
import json |
| 4 | 5 |
|
| 6 |
+from Cryptodome.Cipher import AES |
|
| 5 | 7 |
from django.conf import settings |
| 6 | 8 |
from tencentcloud.common import credential |
| 7 | 9 |
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException |
@@ -16,8 +18,8 @@ operator_id = tencentcloud_cfg.get('operator_id')
|
||
| 16 | 18 |
template_id = tencentcloud_cfg.get('template_id')
|
| 17 | 19 |
secret_id = tencentcloud_cfg.get('secret_id')
|
| 18 | 20 |
secret_key = tencentcloud_cfg.get('secret_key')
|
| 19 |
-callback_secret_id = tencentcloud_cfg.get('callback_secret_id')
|
|
| 20 | 21 |
callback_secret_key = tencentcloud_cfg.get('callback_secret_key')
|
| 22 |
+callback_secret_token = tencentcloud_cfg.get('callback_secret_token')
|
|
| 21 | 23 |
endpoint = tencentcloud_cfg.get('endpoint')
|
| 22 | 24 |
file_endpoint = tencentcloud_cfg.get('file_endpoint')
|
| 23 | 25 |
|
@@ -304,3 +306,32 @@ def create_scheme_url(flow_id=None, name=None, mobile=None, card_type='ID_CARD', |
||
| 304 | 306 |
resp = {}
|
| 305 | 307 |
|
| 306 | 308 |
return resp |
| 309 |
+ |
|
| 310 |
+ |
|
| 311 |
+def decode_aes256(data, encryption_key): |
|
| 312 |
+ iv = encryption_key[0:16] |
|
| 313 |
+ aes = AES.new(encryption_key, AES.MODE_CBC, iv) |
|
| 314 |
+ d = aes.decrypt(data) |
|
| 315 |
+ unpad = lambda s: s[0:-ord(d[-1:])] |
|
| 316 |
+ return unpad(d) |
|
| 317 |
+ |
|
| 318 |
+ |
|
| 319 |
+def test_decode(): |
|
| 320 |
+ # https://qian.tencent.com/developers/company/callback_types_v2 |
|
| 321 |
+ data = "62KE4r5Wz0yHzEpMOwVRbM1KV0pPjj+cmJkT+i65MMscgfHAdNP+9K0nV/fFw1xriwi08APc/wM0mHprE43Hc91VPhRDnu2Wn0+bjzgjmy/FgZKZATR9oquy0/BCWu4C77AjkpkoU1/E7gGLr8M9u9t7zbS4AkkGK5xL5TtwI0sS+CMygmyV7bRjxebMycI52U3QJiwDRIPxFO+7yqeXYXV9AQrRskpCDBNFGW72bh+Ixw9dtX00kWcwVQ93V+mayrvdQ8oGSsL32m72kbBfahsIvIxSYSdDAEeTyokqKGfaLWD27vm55QG218IFKEsOJFDGdqCF+IBcM/+rOFeOrewvP5ehIO2KjFBecTDn0RQTlIiokXIQ4zJKvu6njePFRFoFCZjd4oiEIVn/OBw+rjXml3qwgVBQjPRtYdvDJFNENlVjlkVVmLWeS8MIdqsFWhm6Sa7O8X57mwc0cLJ22mGbyVEzNTFqeFJ/mkueW0leLcoZdjv/+IxZusqa1cpfwzkZhwi5rY6kJffNkkrxIc6OeRvpU4ECgBe/b+kxX+ObC0z9u7nzoZAOHx4akYviyIU5B1romjdfHQ/wDr5udm4Rl4NBhU/6V06Rvaadw0Ta9oBkZHGNxFWv32MnL7fVA0zVNOFDP8n+kaQiNGFAXLF4F5oIItYc5+Gp/IxfkltEki7ni7LztViE7b/ZiKSM+gzQn6fLsJ/dlUoZmh141Y0V/GPpsbxBOnWCjBZdNkLTKxdKCMScLCTysJxv7l6Swff8nAEurbzx1tvyhJAvUDnIaLyP8pRPRFq8p0xm3ZVpOo9k7A952XxVHSs40g4sr/Dihkn60aVhGtKK9DueCzn8P3cWG4TYc03M1hNlPfF+UAfnvQ1ZYAMKT/XPLqYtgRFpRkK96YfVecIrfUe9MjWl0/g4hYCAAOJurFoeGwkJiyQ8Q7DCI5EaHa3s/vI621yQyytC6D2u86RiDJxMW0PdvkUfayT7iPwC83EsfEzpQXr0yeSCQCSBgNByEuCNnZl8LAhYl05Y9+bgCzSPt6EUvmaXclYL+/EPrEmi+hzIdXUwBfhXgICT8MteJgMSgmJM2FjjGxy6uZtfHKRIzf1wk6OORPkPJtMgjlMtMs6VFC62EEeo5Xy2v1S95WT/WQ0tnGR8KjbNnmjNSRyD8VtS2mjlLXaK0xRb71YGt57O19YxQQ3R/Hq9zGqOjG+Agdl+pcvh47RlF8o3CnlU7Q==" |
|
| 322 |
+ encryption_key = 'TencentEssEncryptTestKey12345678' |
|
| 323 |
+ return callback_decode(data, encryption_key) |
|
| 324 |
+ |
|
| 325 |
+ |
|
| 326 |
+def callback_decode(data, encryption_key=None): |
|
| 327 |
+ # 此处传入密文,如果接收到的数据是{"encrypt":"base64后的密文"}
|
|
| 328 |
+ # data = 'base64后的密文' |
|
| 329 |
+ data = base64.b64decode(data) |
|
| 330 |
+ encryption_key = encryption_key or callback_secret_key |
|
| 331 |
+ # encryption_key = bytes(encryption_key or callback_secret_key, encoding="utf8") |
|
| 332 |
+ # 此处传入CallbackUrlKey |
|
| 333 |
+ e = decode_aes256(data, encryption_key) |
|
| 334 |
+ # print(type(e)) |
|
| 335 |
+ # print(e) |
|
| 336 |
+ # print(str(e, encoding="utf8")) |
|
| 337 |
+ return json.loads(e) |