@@ -0,0 +1,23 @@ |
||
| 1 |
+# Generated by Django 3.2.8 on 2024-08-08 07:59 |
|
| 2 |
+ |
|
| 3 |
+from django.db import migrations, models |
|
| 4 |
+ |
|
| 5 |
+ |
|
| 6 |
+class Migration(migrations.Migration): |
|
| 7 |
+ |
|
| 8 |
+ dependencies = [ |
|
| 9 |
+ ('account', '0063_auto_20240529_1656'),
|
|
| 10 |
+ ] |
|
| 11 |
+ |
|
| 12 |
+ operations = [ |
|
| 13 |
+ migrations.AddField( |
|
| 14 |
+ model_name='lensmaninfo', |
|
| 15 |
+ name='identity_card_name', |
|
| 16 |
+ field=models.CharField(blank=True, help_text='身份证姓名', max_length=32, null=True, verbose_name='identity_card_name'), |
|
| 17 |
+ ), |
|
| 18 |
+ migrations.AddField( |
|
| 19 |
+ model_name='lensmaninfo', |
|
| 20 |
+ name='identity_card_number', |
|
| 21 |
+ field=models.CharField(blank=True, help_text='身份证号', max_length=32, null=True, verbose_name='identity_card_number'), |
|
| 22 |
+ ), |
|
| 23 |
+ ] |
@@ -394,6 +394,10 @@ class LensmanInfo(BaseModelMixin): |
||
| 394 | 394 |
integral_start_date = models.DateField(_(u'start_date'), blank=True, null=True, help_text=u'积分开始日期') |
| 395 | 395 |
integral_end_date = models.DateField(_(u'start_date'), blank=True, null=True, help_text=u'积分截止日期') |
| 396 | 396 |
|
| 397 |
+ # 身份证信息 |
|
| 398 |
+ identity_card_number = models.CharField(_(u'identity_card_number'), max_length=32, blank=True, null=True, help_text=u'身份证号') |
|
| 399 |
+ identity_card_name = models.CharField(_(u'identity_card_name'), max_length=32, blank=True, null=True, help_text=u'身份证姓名') |
|
| 400 |
+ |
|
| 397 | 401 |
class Meta: |
| 398 | 402 |
verbose_name = _(u'LensmanInfo') |
| 399 | 403 |
verbose_name_plural = _(u'LensmanInfo') |
@@ -0,0 +1,20 @@ |
||
| 1 |
+from django.conf import settings |
|
| 2 |
+from django_logit import logit |
|
| 3 |
+from django_response import response |
|
| 4 |
+ |
|
| 5 |
+from kodo.decorators import check_admin |
|
| 6 |
+from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo |
|
| 7 |
+ |
|
| 8 |
+@logit(res=True) |
|
| 9 |
+@check_admin |
|
| 10 |
+def add_lensman_contribution_income_api(request, administrator): |
|
| 11 |
+ contrbution_id = request.POST.get('contribution_id', '')
|
|
| 12 |
+ lensman_id = request.POST.get('lensman_id', '')
|
|
| 13 |
+ activity_id = request.POST.get('activity_id', '')
|
|
| 14 |
+ user_id = request.POST.get('user_id', '')
|
|
| 15 |
+ |
|
| 16 |
+ amount = int(request.POST.get('amount', '0'))
|
|
| 17 |
+ |
|
| 18 |
+ LensmanContributionActivityIncomeExpensesInfo.objects.update_or_create(contrbution_id=contrbution_id, lensman_id=lensman_id, activity_id=activity_id, user_id=user_id, defaults={'amount': amount})
|
|
| 19 |
+ |
|
| 20 |
+ return response(200, '增加摄影师投稿收入成功') |
@@ -0,0 +1,31 @@ |
||
| 1 |
+from django.conf import settings |
|
| 2 |
+from django_logit import logit |
|
| 3 |
+from django_response import response |
|
| 4 |
+ |
|
| 5 |
+from kodo.decorators import check_admin |
|
| 6 |
+from apps.contract.models import LensmanContributionContractInfo |
|
| 7 |
+ |
|
| 8 |
+ |
|
| 9 |
+@logit(res=True) |
|
| 10 |
+@check_admin |
|
| 11 |
+def get_signed_contribtion_contract_file_api(request, administrator): |
|
| 12 |
+ contribution_id = request.POST.get('contribution_id', '')
|
|
| 13 |
+ user_id = request.POST.get('user_id', '')
|
|
| 14 |
+ |
|
| 15 |
+ contract = LensmanContributionContractInfo.objects.filter(contribution_id=contribution_id, user_id=user_id).first() |
|
| 16 |
+ |
|
| 17 |
+ operator = {
|
|
| 18 |
+ "UserId": settings.CONTRACT_LENSMAN_CONTRIBUTION_OPERATOR_ID |
|
| 19 |
+ } |
|
| 20 |
+ |
|
| 21 |
+ BusinessType = 'FLOW' |
|
| 22 |
+ BusinessIds = [contract.flow_id] |
|
| 23 |
+ FileType = 'PDF' |
|
| 24 |
+ UrlTtl = '86400' # 过期时间 |
|
| 25 |
+ |
|
| 26 |
+ # TODO: 获取合同文件 https://qian.tencent.com/developers/companyApis/templatesAndFiles/DescribeFileUrls |
|
| 27 |
+ FileUrls = [] |
|
| 28 |
+ |
|
| 29 |
+ return response(200, data={
|
|
| 30 |
+ 'file_url': FileUrls[0].Url |
|
| 31 |
+ }) |
@@ -0,0 +1,131 @@ |
||
| 1 |
+from django.conf import settings |
|
| 2 |
+from django_logit import logit |
|
| 3 |
+from django_response import response |
|
| 4 |
+from TimeConvert import TimeConvert as tc |
|
| 5 |
+ |
|
| 6 |
+from apps.contract.models import LensmanContributionContractInfo |
|
| 7 |
+from apps.lensman.activity.models import LensmanContributionActivityIncomeExpensesInfo |
|
| 8 |
+from account.models import LensmanInfo |
|
| 9 |
+from member.models import MemberActivityContributionInfo |
|
| 10 |
+ |
|
| 11 |
+ |
|
| 12 |
+@logit(res=True) |
|
| 13 |
+def get_contribtion_contract_api(request): |
|
| 14 |
+ user_id = request.POST.get('user_id', '')
|
|
| 15 |
+ lensman_id = request.POST.get('lensman_id', '')
|
|
| 16 |
+ activity_id = request.POST.get('activity_id', '')
|
|
| 17 |
+ contribtuon_id = request.POST.get('contribtuon_id', '')
|
|
| 18 |
+ |
|
| 19 |
+ lensman = LensmanInfo.objects.get(lensman_id=lensman_id) |
|
| 20 |
+ |
|
| 21 |
+ contract, _ = LensmanContributionContractInfo.objects.update_or_create( |
|
| 22 |
+ user_id=user_id, lensman_id=lensman_id, activity_id=activity_id, contribtuon_id=contribtuon_id) |
|
| 23 |
+ |
|
| 24 |
+ file_ids = upload_contribution_images(contribtuon_id) |
|
| 25 |
+ |
|
| 26 |
+ operator = {
|
|
| 27 |
+ "UserId": settings.CONTRACT_LENSMAN_CONTRIBUTION_OPERATOR_ID |
|
| 28 |
+ } |
|
| 29 |
+ |
|
| 30 |
+ flow_id = create_contribution_contract_flow(lensman, operator) |
|
| 31 |
+ contract.flow_id = flow_id |
|
| 32 |
+ contract.save() |
|
| 33 |
+ |
|
| 34 |
+ document_id, fields = create_contribution_contract_document(lensman, file_ids, flow_id, operator) |
|
| 35 |
+ contract.contract_content_fields = fields |
|
| 36 |
+ contract.document_id = document_id |
|
| 37 |
+ contract.save() |
|
| 38 |
+ |
|
| 39 |
+ # TODO : 发起签署流程 |
|
| 40 |
+ start_contribution_contract_flow(flow_id, operator) |
|
| 41 |
+ |
|
| 42 |
+ scheme_url = get_contribtion_contract_sign_mppath(operator, lensman, flow_id) |
|
| 43 |
+ |
|
| 44 |
+ return response(200, data={
|
|
| 45 |
+ 'contract': contract.mpdata, |
|
| 46 |
+ 'scheme_url': scheme_url |
|
| 47 |
+ }) |
|
| 48 |
+ |
|
| 49 |
+ |
|
| 50 |
+def upload_contribution_images(contribtuon_id): |
|
| 51 |
+ # TODO : 上传MemberActivityContributionInfo图片 https://qian.tencent.com/developers/companyApis/templatesAndFiles/UploadFiles |
|
| 52 |
+ |
|
| 53 |
+ contribtuon = MemberActivityContributionInfo.objects.get(contribtuon_id=contribtuon_id) |
|
| 54 |
+ |
|
| 55 |
+ # 返回图片的 file_ids |
|
| 56 |
+ return [] |
|
| 57 |
+ |
|
| 58 |
+ |
|
| 59 |
+def create_contribution_contract_flow(lensman, Operator): |
|
| 60 |
+ # TODO : 创建签署流程 https://qian.tencent.com/developers/companyApis/startFlows/CreateFlow |
|
| 61 |
+ |
|
| 62 |
+ # 创建签署流程参数 Operator |
|
| 63 |
+ FlowName = lensman.identity_card_name + "的投稿合同" + tc.local_string(format='%Y%m%d') |
|
| 64 |
+ FlowType = '活动投稿授权书' |
|
| 65 |
+ Approvers = [{
|
|
| 66 |
+ "ApproverType": "1", |
|
| 67 |
+ "Required": "true", |
|
| 68 |
+ "NotifyType": "none", |
|
| 69 |
+ "ApproverMobile": lensman.phone, |
|
| 70 |
+ "ApproverName": lensman.identity_card_name, |
|
| 71 |
+ "ApproverIdCardNumber": lensman.identity_card_number, |
|
| 72 |
+ }] |
|
| 73 |
+ |
|
| 74 |
+ # 创建签署流程返回值 FlowId |
|
| 75 |
+ return '' |
|
| 76 |
+ |
|
| 77 |
+ |
|
| 78 |
+def create_contribution_contract_document(lensman, contribtuon_id, file_ids, FlowId, Operator): |
|
| 79 |
+ # TODO : 创建电子签文档 https://qian.tencent.com/developers/companyApis/startFlows/CreateDocument |
|
| 80 |
+ |
|
| 81 |
+ income = LensmanContributionActivityIncomeExpensesInfo.objects.get(contribtuon_id=contribtuon_id, lensman_id=lensman.lensman_id) |
|
| 82 |
+ |
|
| 83 |
+ # 创建电子文档参数 Operator FlowId |
|
| 84 |
+ TemplateId = settings.CONTRACT_LENSMAN_CONTRIBUTION_TEMPLATE_ID |
|
| 85 |
+ |
|
| 86 |
+ FormFields = [{
|
|
| 87 |
+ "ComponentName": "ComponentId_0", |
|
| 88 |
+ "ComponentValue": lensman.identity_card_name |
|
| 89 |
+ }, {
|
|
| 90 |
+ "ComponentName": "ComponentId_1", |
|
| 91 |
+ "ComponentValue": lensman.identity_card_number, |
|
| 92 |
+ }, {
|
|
| 93 |
+ "ComponentName": "ComponentId_2", |
|
| 94 |
+ "ComponentValue": income.amount, |
|
| 95 |
+ }, {
|
|
| 96 |
+ "ComponentName": "ComponentId_3", |
|
| 97 |
+ "ComponentValue": "", |
|
| 98 |
+ }] |
|
| 99 |
+ |
|
| 100 |
+ for i, file_id in enumerate(file_ids): |
|
| 101 |
+ FormFields.append({
|
|
| 102 |
+ "ComponentName": "ComponentId_" + str(37 + i), |
|
| 103 |
+ "ComponentValue": file_id, |
|
| 104 |
+ }) |
|
| 105 |
+ |
|
| 106 |
+ # 返回创建电子文档 DocumentId |
|
| 107 |
+ return '', FormFields |
|
| 108 |
+ |
|
| 109 |
+ |
|
| 110 |
+def start_contribution_contract_flow(FlowId, Operator): |
|
| 111 |
+ # TODO : 发起签署流程 https://qian.tencent.com/developers/companyApis/startFlows/StartFlow |
|
| 112 |
+ |
|
| 113 |
+ # 发起签署流程参数 Operator FlowId |
|
| 114 |
+ |
|
| 115 |
+ # |
|
| 116 |
+ return '' |
|
| 117 |
+ |
|
| 118 |
+ |
|
| 119 |
+def get_contribtion_contract_sign_mppath(Operator, lensman, FlowId): |
|
| 120 |
+ # TODO : 获取签署链接 https://qian.tencent.com/developers/companyApis/startFlows/CreateSchemeUrl |
|
| 121 |
+ |
|
| 122 |
+ Name = lensman.identity_card_name |
|
| 123 |
+ Mobile = lensman.phone |
|
| 124 |
+ IdCardType = 'ID_CARD' |
|
| 125 |
+ IdCardNumber = lensman.identity_card_number |
|
| 126 |
+ EndPoint = 'APP' |
|
| 127 |
+ PathType = '1' #腾讯电子签小程序流程合同的详情页 |
|
| 128 |
+ AutoJumpBack = 'true' #签署完成会自动跳转回来 |
|
| 129 |
+ |
|
| 130 |
+ # 返回 SchemeUrl |
|
| 131 |
+ return '' |
@@ -0,0 +1,12 @@ |
||
| 1 |
+from django.conf.urls import include, url |
|
| 2 |
+from api.lensman import contract_admin_views, contract_mp_views, activity_admin_views |
|
| 3 |
+ |
|
| 4 |
+urlpatterns = [ |
|
| 5 |
+ url(r'^mp/lensman/contribution/contract/get$', contract_mp_views.get_contribtion_contract_api, name='get_contribtion_contract_api'), |
|
| 6 |
+] |
|
| 7 |
+ |
|
| 8 |
+urlpatterns += [ |
|
| 9 |
+ url(r'^admin/lensman/contribution/contract/file/get$', contract_admin_views.get_signed_contribtion_contract_file_api, name='get_signed_contribtion_contract_file_api'), |
|
| 10 |
+ |
|
| 11 |
+ url(r'^admin/lensman/contribution/income/add$', activity_admin_views.add_lensman_contribution_income_api, name='add_lensman_contribution_income_api'), |
|
| 12 |
+] |
@@ -384,4 +384,7 @@ urlpatterns += [ |
||
| 384 | 384 |
url(r'^admin/lensman/update$', lensman_admin_views.lensman_update, name='admin_lensman_update'), |
| 385 | 385 |
url(r'^admin/lensman/integral/list$', lensman_admin_views.lensman_integral_list, name='admin_lensman_integral_list'), |
| 386 | 386 |
url(r'^admin/lensman/integral/update$', lensman_admin_views.lensman_integral_update, name='admin_lensman_integral_update'), |
| 387 |
-] |
|
| 387 |
+ |
|
| 388 |
+ url(r'', include(('api.lensman.lensman_urls', 'lensman'), namespace='lensman')),
|
|
| 389 |
+] |
|
| 390 |
+ |
@@ -0,0 +1,3 @@ |
||
| 1 |
+from django.contrib import admin |
|
| 2 |
+ |
|
| 3 |
+# Register your models here. |
@@ -0,0 +1,6 @@ |
||
| 1 |
+from django.apps import AppConfig |
|
| 2 |
+ |
|
| 3 |
+ |
|
| 4 |
+class ContractConfig(AppConfig): |
|
| 5 |
+ default_auto_field = 'django.db.models.BigAutoField' |
|
| 6 |
+ name = 'apps.contract' |
@@ -0,0 +1,41 @@ |
||
| 1 |
+# Generated by Django 3.2.8 on 2024-08-09 04:36 |
|
| 2 |
+ |
|
| 3 |
+from django.db import migrations, models |
|
| 4 |
+import django_models_ext.fileext |
|
| 5 |
+import jsonfield.fields |
|
| 6 |
+import shortuuidfield.fields |
|
| 7 |
+ |
|
| 8 |
+ |
|
| 9 |
+class Migration(migrations.Migration): |
|
| 10 |
+ |
|
| 11 |
+ initial = True |
|
| 12 |
+ |
|
| 13 |
+ dependencies = [ |
|
| 14 |
+ ] |
|
| 15 |
+ |
|
| 16 |
+ operations = [ |
|
| 17 |
+ migrations.CreateModel( |
|
| 18 |
+ name='LensmanContributionContractInfo', |
|
| 19 |
+ fields=[ |
|
| 20 |
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
| 21 |
+ ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')),
|
|
| 22 |
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
|
|
| 23 |
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
|
|
| 24 |
+ ('contract_id', shortuuidfield.fields.ShortUUIDField(blank=True, db_index=True, editable=False, help_text='合同唯一标识', max_length=22, null=True, unique=True)),
|
|
| 25 |
+ ('user_id', models.CharField(blank=True, db_index=True, help_text='用户唯一标识', max_length=32, null=True, verbose_name='user_id')),
|
|
| 26 |
+ ('lensman_id', models.CharField(blank=True, db_index=True, help_text='摄影师唯一标识', max_length=32, null=True, verbose_name='lensman_id')),
|
|
| 27 |
+ ('activity_id', models.CharField(blank=True, db_index=True, help_text='活动唯一标识', max_length=32, null=True, verbose_name='activity_id')),
|
|
| 28 |
+ ('contribution_id', models.CharField(blank=True, db_index=True, help_text='活动投稿唯一标识', max_length=32, null=True, verbose_name='contribution_id')),
|
|
| 29 |
+ ('contract_content_fields', jsonfield.fields.JSONField(blank=True, help_text=' 合同内容字段', null=True, verbose_name='contract_content_fields')),
|
|
| 30 |
+ ('contract_file', models.FileField(blank=True, help_text='图片', null=True, upload_to=django_models_ext.fileext.upload_path, verbose_name='contract_file')),
|
|
| 31 |
+ ('flow_id', models.CharField(blank=True, help_text='电子签流程ID', max_length=128, null=True, verbose_name='flow_id')),
|
|
| 32 |
+ ('document_id', models.CharField(blank=True, help_text='电子签文档ID', max_length=128, null=True, verbose_name='document_id')),
|
|
| 33 |
+ ('contract_status', models.IntegerField(choices=[(1, '合同创建'), (2, '合同签署中'), (3, '合同拒签'), (4, '合同签署完成'), (5, '合同流签(合同过期)'), (6, '合同撤回'), (8, '合同待填写'), (21, '解除协议(已解除)'), (16, '合同已失效')], db_index=True, default=1, help_text='合同签署状态', verbose_name='contract_status')),
|
|
| 34 |
+ ('approve_status', models.IntegerField(choices=[(2, '待签署'), (7, '待签署'), (3, '已签署'), (4, '拒绝'), (5, '过期没人处理'), (6, '流程已撤回'), (8, '合同待填写'), (9, '流程已终止'), (10, '填写完成'), (15, '解除协议(已解除)'), (15, '已转他人处理')], db_index=True, default=2, help_text='签署人签署状态', verbose_name='approve_status')),
|
|
| 35 |
+ ], |
|
| 36 |
+ options={
|
|
| 37 |
+ 'verbose_name': '摄影师投稿合同信息', |
|
| 38 |
+ 'verbose_name_plural': '摄影师投稿合同信息', |
|
| 39 |
+ }, |
|
| 40 |
+ ), |
|
| 41 |
+ ] |
@@ -0,0 +1,91 @@ |
||
| 1 |
+# -*- coding: utf-8 -*- |
|
| 2 |
+ |
|
| 3 |
+from django.db import models |
|
| 4 |
+from django.utils.translation import ugettext_lazy as _ |
|
| 5 |
+from django_models_ext import BaseModelMixin, upload_file_path, upload_path |
|
| 6 |
+from jsonfield import JSONField |
|
| 7 |
+from shortuuidfield import ShortUUIDField |
|
| 8 |
+from TimeConvert import TimeConvert as tc |
|
| 9 |
+ |
|
| 10 |
+from utils.qiniucdn import qiniu_file_url |
|
| 11 |
+ |
|
| 12 |
+# Create your models here. |
|
| 13 |
+ |
|
| 14 |
+ |
|
| 15 |
+class LensmanContributionContractInfo(BaseModelMixin): |
|
| 16 |
+ CONTRACT_STATUS_TUPLE = ( |
|
| 17 |
+ (1, u'合同创建'), |
|
| 18 |
+ (2, u'合同签署中'), |
|
| 19 |
+ (3, u'合同拒签'), |
|
| 20 |
+ (4, u'合同签署完成'), |
|
| 21 |
+ (5, u'合同流签(合同过期)'), |
|
| 22 |
+ (6, u'合同撤回'), |
|
| 23 |
+ (8, u'合同待填写'), |
|
| 24 |
+ (21, u'解除协议(已解除)'), |
|
| 25 |
+ (16, u'合同已失效'), |
|
| 26 |
+ ) |
|
| 27 |
+ |
|
| 28 |
+ APPROVE_STATUS_TYPE = ( |
|
| 29 |
+ (2, u'待签署'), |
|
| 30 |
+ (7, u'待签署'), |
|
| 31 |
+ (3, u'已签署'), |
|
| 32 |
+ (4, u'拒绝'), |
|
| 33 |
+ (5, u'过期没人处理'), |
|
| 34 |
+ (6, u'流程已撤回'), |
|
| 35 |
+ (8, u'合同待填写'), |
|
| 36 |
+ (9, u'流程已终止'), |
|
| 37 |
+ (10, u'填写完成'), |
|
| 38 |
+ (15, u'解除协议(已解除)'), |
|
| 39 |
+ (15, u'已转他人处理'), |
|
| 40 |
+ ) |
|
| 41 |
+ |
|
| 42 |
+ contract_id = ShortUUIDField(_(u'contract_id'), max_length=32, blank=True, null=True, help_text=u'合同唯一标识', db_index=True, unique=True) |
|
| 43 |
+ |
|
| 44 |
+ user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) |
|
| 45 |
+ lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True) |
|
| 46 |
+ |
|
| 47 |
+ activity_id = models.CharField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True) |
|
| 48 |
+ contribution_id = models.CharField(_(u'contribution_id'), max_length=32, blank=True, null=True, help_text=u'活动投稿唯一标识', db_index=True) |
|
| 49 |
+ |
|
| 50 |
+ contract_content_fields = JSONField(_(u'contract_content_fields'), blank=True, null=True, help_text=u' 合同内容字段') |
|
| 51 |
+ contract_file = models.FileField(_(u'contract_file'), upload_to=upload_path, blank=True, null=True, help_text=u'图片') |
|
| 52 |
+ |
|
| 53 |
+ # 电子签参数 |
|
| 54 |
+ flow_id = models.CharField(_(u'flow_id'), max_length=128, blank=True, null=True, help_text=u'电子签流程ID') |
|
| 55 |
+ # 后续需用同样的FlowId再次调用发起签署流程,合同才能进入签署环节 |
|
| 56 |
+ document_id = models.CharField(_(u'document_id'), max_length=128, blank=True, null=True, help_text=u'电子签文档ID') |
|
| 57 |
+ |
|
| 58 |
+ contract_status = models.IntegerField(_(u'contract_status'), choices=CONTRACT_STATUS_TUPLE, default=1, help_text=u'合同签署状态', db_index=True) |
|
| 59 |
+ approve_status = models.IntegerField(_(u'approve_status'), choices=APPROVE_STATUS_TYPE, default=2, help_text=u'签署人签署状态', db_index=True) |
|
| 60 |
+ |
|
| 61 |
+ class Meta: |
|
| 62 |
+ verbose_name = _(u'摄影师投稿合同信息') |
|
| 63 |
+ verbose_name_plural = _(u'摄影师投稿合同信息') |
|
| 64 |
+ |
|
| 65 |
+ def __unicode__(self): |
|
| 66 |
+ return '%d' % self.pk |
|
| 67 |
+ |
|
| 68 |
+ @property |
|
| 69 |
+ def contract_file_url(self): |
|
| 70 |
+ return qiniu_file_url(self.contract_file.name, bucket='tamron') |
|
| 71 |
+ |
|
| 72 |
+ @property |
|
| 73 |
+ def data(self): |
|
| 74 |
+ return {
|
|
| 75 |
+ 'contract_id': self.contract_id, |
|
| 76 |
+ 'lensman_id': self.lensman_id, |
|
| 77 |
+ 'activity_id': self.activity_id, |
|
| 78 |
+ 'contribution_id': self.contribution_id, |
|
| 79 |
+ 'contract_content_fields': self.contract_content_fields, |
|
| 80 |
+ 'contract_file_url': self.contract_file_url, |
|
| 81 |
+ 'created_at': tc.local_string(utc_dt=self.created_at, format='%Y-%m-%d %H:%M:%S'), |
|
| 82 |
+ 'updated_at': tc.local_string(utc_dt=self.updated_at, format='%Y-%m-%d %H:%M:%S') |
|
| 83 |
+ } |
|
| 84 |
+ |
|
| 85 |
+ @property |
|
| 86 |
+ def admindata(self): |
|
| 87 |
+ return self.data |
|
| 88 |
+ |
|
| 89 |
+ @property |
|
| 90 |
+ def mpdata(self): |
|
| 91 |
+ return self.data |
@@ -0,0 +1,3 @@ |
||
| 1 |
+from django.test import TestCase |
|
| 2 |
+ |
|
| 3 |
+# Create your tests here. |
@@ -0,0 +1,3 @@ |
||
| 1 |
+from django.shortcuts import render |
|
| 2 |
+ |
|
| 3 |
+# Create your views here. |
@@ -0,0 +1,3 @@ |
||
| 1 |
+from django.contrib import admin |
|
| 2 |
+ |
|
| 3 |
+# Register your models here. |
@@ -0,0 +1,6 @@ |
||
| 1 |
+from django.apps import AppConfig |
|
| 2 |
+ |
|
| 3 |
+ |
|
| 4 |
+class ActivityConfig(AppConfig): |
|
| 5 |
+ default_auto_field = 'django.db.models.BigAutoField' |
|
| 6 |
+ name = 'apps.lensman.activity' |
@@ -0,0 +1,32 @@ |
||
| 1 |
+# Generated by Django 3.2.8 on 2024-08-09 04:36 |
|
| 2 |
+ |
|
| 3 |
+from django.db import migrations, models |
|
| 4 |
+ |
|
| 5 |
+ |
|
| 6 |
+class Migration(migrations.Migration): |
|
| 7 |
+ |
|
| 8 |
+ initial = True |
|
| 9 |
+ |
|
| 10 |
+ dependencies = [ |
|
| 11 |
+ ] |
|
| 12 |
+ |
|
| 13 |
+ operations = [ |
|
| 14 |
+ migrations.CreateModel( |
|
| 15 |
+ name='LensmanContributionActivityIncomeExpensesInfo', |
|
| 16 |
+ fields=[ |
|
| 17 |
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
| 18 |
+ ('status', models.BooleanField(default=True, help_text='Status', verbose_name='status')),
|
|
| 19 |
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')),
|
|
| 20 |
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')),
|
|
| 21 |
+ ('user_id', models.CharField(blank=True, db_index=True, help_text='用户唯一标识', max_length=32, null=True, verbose_name='user_id')),
|
|
| 22 |
+ ('lensman_id', models.CharField(blank=True, db_index=True, help_text='摄影师唯一标识', max_length=32, null=True, verbose_name='lensman_id')),
|
|
| 23 |
+ ('activity_id', models.CharField(blank=True, db_index=True, help_text='活动唯一标识', max_length=32, null=True, verbose_name='activity_id')),
|
|
| 24 |
+ ('contribution_id', models.CharField(blank=True, db_index=True, help_text='活动投稿唯一标识', max_length=32, null=True, verbose_name='contribution_id')),
|
|
| 25 |
+ ('amount', models.IntegerField(default=0, help_text='金额(分)', verbose_name='amount')),
|
|
| 26 |
+ ], |
|
| 27 |
+ options={
|
|
| 28 |
+ 'verbose_name': '摄影师投稿活动收入费用信息', |
|
| 29 |
+ 'verbose_name_plural': '摄影师投稿活动收入费用信息', |
|
| 30 |
+ }, |
|
| 31 |
+ ), |
|
| 32 |
+ ] |
@@ -0,0 +1,37 @@ |
||
| 1 |
+# -*- coding: utf-8 -*- |
|
| 2 |
+ |
|
| 3 |
+from django.db import models |
|
| 4 |
+from django.utils.translation import ugettext_lazy as _ |
|
| 5 |
+from django_models_ext import BaseModelMixin |
|
| 6 |
+from TimeConvert import TimeConvert as tc |
|
| 7 |
+ |
|
| 8 |
+class LensmanContributionActivityIncomeExpensesInfo(BaseModelMixin): |
|
| 9 |
+ user_id = models.CharField(_(u'user_id'), max_length=32, blank=True, null=True, help_text=u'用户唯一标识', db_index=True) |
|
| 10 |
+ lensman_id = models.CharField(_(u'lensman_id'), max_length=32, blank=True, null=True, help_text=u'摄影师唯一标识', db_index=True) |
|
| 11 |
+ |
|
| 12 |
+ activity_id = models.CharField(_(u'activity_id'), max_length=32, blank=True, null=True, help_text=u'活动唯一标识', db_index=True) |
|
| 13 |
+ contribution_id = models.CharField(_(u'contribution_id'), max_length=32, blank=True, null=True, help_text=u'活动投稿唯一标识', db_index=True) |
|
| 14 |
+ |
|
| 15 |
+ amount = models.IntegerField(_(u'amount'), default=0, help_text=u'金额(分)') |
|
| 16 |
+ |
|
| 17 |
+ class Meta: |
|
| 18 |
+ verbose_name = _(u'摄影师投稿活动收入费用信息') |
|
| 19 |
+ verbose_name_plural = _(u'摄影师投稿活动收入费用信息') |
|
| 20 |
+ |
|
| 21 |
+ def __unicode__(self): |
|
| 22 |
+ return '%d' % self.pk |
|
| 23 |
+ |
|
| 24 |
+ @property |
|
| 25 |
+ def data(self): |
|
| 26 |
+ return {
|
|
| 27 |
+ 'lensman_id': self.lensman_id, |
|
| 28 |
+ 'activity_id': self.activity_id, |
|
| 29 |
+ 'contribution_id': self.contribution_id, |
|
| 30 |
+ 'amount': self.amount, |
|
| 31 |
+ 'created_at': tc.local_string(utc_dt=self.created_at, format='%Y-%m-%d %H:%M:%S'), |
|
| 32 |
+ 'updated_at': tc.local_string(utc_dt=self.updated_at, format='%Y-%m-%d %H:%M:%S') |
|
| 33 |
+ } |
|
| 34 |
+ |
|
| 35 |
+ @property |
|
| 36 |
+ def admindata(self): |
|
| 37 |
+ return self.data |
@@ -0,0 +1,3 @@ |
||
| 1 |
+from django.test import TestCase |
|
| 2 |
+ |
|
| 3 |
+# Create your tests here. |
@@ -0,0 +1,3 @@ |
||
| 1 |
+from django.shortcuts import render |
|
| 2 |
+ |
|
| 3 |
+# Create your views here. |
@@ -74,6 +74,8 @@ INSTALLED_APPS = ( |
||
| 74 | 74 |
'statistic', |
| 75 | 75 |
'tenancy', |
| 76 | 76 |
'website', |
| 77 |
+ 'apps.contract', |
|
| 78 |
+ 'apps.lensman.activity' |
|
| 77 | 79 |
) |
| 78 | 80 |
|
| 79 | 81 |
INSTALLED_APPS += ('multidomain', )
|
@@ -262,9 +264,12 @@ QINIU = {
|
||
| 262 | 264 |
# 图片链接设置 |
| 263 | 265 |
FILE_URL_TYPE = 'AUTO' # QINIU / SERVER / AUTO |
| 264 | 266 |
QINIU_FILE_URL_HTTPS = True |
| 265 |
-QINIU_FILE_URL_BEFORE = 'https://img.tamron.kodo.com.cn' # QINIU_FILE_URL_HTTPS False 时必填 |
|
| 266 |
-QINIU_FILE_URL_BEFORE2 = 'https://img.tamron.kodo.com.cn' # QINIU_FILE_URL_HTTPS False 时必填 |
|
| 267 |
-QINIU_FILE_URL_AFTER = 'http://img.tamron.kodo.com.cn' # QINIU_FILE_URL_HTTPS False 时必填 |
|
| 267 |
+# QINIU_FILE_URL_HTTPS False 时必填 |
|
| 268 |
+QINIU_FILE_URL_BEFORE = 'https://img.tamron.kodo.com.cn' |
|
| 269 |
+# QINIU_FILE_URL_HTTPS False 时必填 |
|
| 270 |
+QINIU_FILE_URL_BEFORE2 = 'https://img.tamron.kodo.com.cn' |
|
| 271 |
+# QINIU_FILE_URL_HTTPS False 时必填 |
|
| 272 |
+QINIU_FILE_URL_AFTER = 'http://img.tamron.kodo.com.cn' |
|
| 268 | 273 |
|
| 269 | 274 |
# 图片设置 |
| 270 | 275 |
# https://docs.djangoproject.com/en/5.0/releases/1.10/#maximum-size-of-a-request-body-and-the-number-of-get-post-parameters-is-limited |
@@ -280,10 +285,12 @@ CURTAIL_UUID_LENGTH = 7 # Used in django-curtail-uuid==1.0.0 |
||
| 280 | 285 |
|
| 281 | 286 |
# 水印设置 |
| 282 | 287 |
WATERMARK_OR_NOT = False # 水印是否开启 |
| 283 |
-WATERMARK_LOGO_PATH = os.path.join(PROJ_DIR, 'static/kodo/img/paiai_water_mark.png').replace('\\', '/') # 水印图片路径
|
|
| 288 |
+WATERMARK_LOGO_PATH = os.path.join( |
|
| 289 |
+ PROJ_DIR, 'static/kodo/img/paiai_water_mark.png').replace('\\', '/') # 水印图片路径
|
|
| 284 | 290 |
|
| 285 | 291 |
# 原图设置 |
| 286 |
-LENSMAN_PHOTO_ORIGIN_EXPIRED_MSEL = 604800000 # 摄影师原图过期毫秒数,7d = 7 * 24 * 3600 * 1000msel |
|
| 292 |
+# 摄影师原图过期毫秒数,7d = 7 * 24 * 3600 * 1000msel |
|
| 293 |
+LENSMAN_PHOTO_ORIGIN_EXPIRED_MSEL = 604800000 |
|
| 287 | 294 |
|
| 288 | 295 |
# 缩略图设置 |
| 289 | 296 |
THUMBNAIL_MAX_WIDTH = 540 |
@@ -292,19 +299,27 @@ THUMBNAIL_MAX_WIDTH2 = 1080 |
||
| 292 | 299 |
# 首页设置 |
| 293 | 300 |
PAI2_HOME_PER_PAGE = 20 # 首页照片每页数量 |
| 294 | 301 |
PAI2_HOME_MAX_PAGE = 20 # 首页照片最大页数 |
| 295 |
-PAI2_HOME_MAX_ROWS = 400 # 首页照片最大数量,PAI2_HOME_PER_PAGE * PAI2_HOME_MAX_PAGE = 20 * 20 = 400 |
|
| 302 |
+# 首页照片最大数量,PAI2_HOME_PER_PAGE * PAI2_HOME_MAX_PAGE = 20 * 20 = 400 |
|
| 303 |
+PAI2_HOME_MAX_ROWS = 400 |
|
| 296 | 304 |
|
| 297 | 305 |
# 下载页设置 |
| 298 |
-TMPL_DOWNLOAD_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/download.tmpl.html').replace('\\', '/')
|
|
| 306 |
+TMPL_DOWNLOAD_PAGE_PATH = os.path.join( |
|
| 307 |
+ BASE_DIR, 'page/templates/page/download.tmpl.html').replace('\\', '/')
|
|
| 299 | 308 |
|
| 300 |
-PAI2_USER_DOWNLOAD_ADR_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_user_adr_download.html').replace('\\', '/')
|
|
| 301 |
-PAI2_USER_DOWNLOAD_IOS_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_user_ios_download.html').replace('\\', '/')
|
|
| 309 |
+PAI2_USER_DOWNLOAD_ADR_PAGE_PATH = os.path.join( |
|
| 310 |
+ BASE_DIR, 'page/templates/page/kodo_user_adr_download.html').replace('\\', '/')
|
|
| 311 |
+PAI2_USER_DOWNLOAD_IOS_PAGE_PATH = os.path.join( |
|
| 312 |
+ BASE_DIR, 'page/templates/page/kodo_user_ios_download.html').replace('\\', '/')
|
|
| 302 | 313 |
|
| 303 |
-PAI2_LENSMAN_DOWNLOAD_ADR_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_lensman_adr_download.html').replace('\\', '/')
|
|
| 304 |
-PAI2_LENSMAN_DOWNLOAD_IOS_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_lensman_ios_download.html').replace('\\', '/')
|
|
| 314 |
+PAI2_LENSMAN_DOWNLOAD_ADR_PAGE_PATH = os.path.join( |
|
| 315 |
+ BASE_DIR, 'page/templates/page/kodo_lensman_adr_download.html').replace('\\', '/')
|
|
| 316 |
+PAI2_LENSMAN_DOWNLOAD_IOS_PAGE_PATH = os.path.join( |
|
| 317 |
+ BASE_DIR, 'page/templates/page/kodo_lensman_ios_download.html').replace('\\', '/')
|
|
| 305 | 318 |
|
| 306 |
-PAI2_TOURGUIDE_DOWNLOAD_ADR_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_tourguide_adr_download.html').replace('\\', '/')
|
|
| 307 |
-PAI2_TOURGUIDE_DOWNLOAD_IOS_PAGE_PATH = os.path.join(BASE_DIR, 'page/templates/page/kodo_tourguide_ios_download.html').replace('\\', '/')
|
|
| 319 |
+PAI2_TOURGUIDE_DOWNLOAD_ADR_PAGE_PATH = os.path.join( |
|
| 320 |
+ BASE_DIR, 'page/templates/page/kodo_tourguide_adr_download.html').replace('\\', '/')
|
|
| 321 |
+PAI2_TOURGUIDE_DOWNLOAD_IOS_PAGE_PATH = os.path.join( |
|
| 322 |
+ BASE_DIR, 'page/templates/page/kodo_tourguide_ios_download.html').replace('\\', '/')
|
|
| 308 | 323 |
|
| 309 | 324 |
# 下载设置 |
| 310 | 325 |
PAI2_USER_DOWNLOAD_WX_URL = 'https://a.app.qq.com/o/simple.jsp?pkgname=ai.pai.client' |
@@ -490,7 +505,8 @@ WEBSITE_MOBI = '{0}/pc/'.format(DOMAIN)
|
||
| 490 | 505 |
|
| 491 | 506 |
# 依赖 local_settings 中的配置 |
| 492 | 507 |
# 微信授权设置 |
| 493 |
-WECHAT_OAUTH2_REDIRECT_URI = '{0}/we/we_oauth2?scope={{0}}redirect_url={{1}}'.format(DOMAIN_HTTP)
|
|
| 508 |
+WECHAT_OAUTH2_REDIRECT_URI = '{0}/we/we_oauth2?scope={{0}}redirect_url={{1}}'.format(
|
|
| 509 |
+ DOMAIN_HTTP) |
|
| 494 | 510 |
WECHAT_BASE_REDIRECT_URI = '{0}/we/base_redirect'.format(DOMAIN_HTTP)
|
| 495 | 511 |
WECHAT_USERINFO_REDIRECT_URI = '{0}/we/userinfo_redirect'.format(DOMAIN_HTTP)
|
| 496 | 512 |
|
@@ -500,13 +516,18 @@ SYSTEM_MESSAGE_AVATAR = PAI2_LOGO_URL |
||
| 500 | 516 |
COMMENT_MESSAGE_AVATAR = PAI2_LOGO_URL |
| 501 | 517 |
THUMBUP_MESSAGE_AVATAR = PAI2_LOGO_URL |
| 502 | 518 |
|
| 503 |
-KODO_CLERK_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fclerk%3Fbrand_id%3D{{0}}'.format(OAUTH_DOMAIN, BASE_DOMAIN)
|
|
| 504 |
-KODO_SCREEN_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fscreen%2Fadmin%2Foauth%3Fbrand_id%3D{{0}}'.format(OAUTH_DOMAIN, BASE_DOMAIN)
|
|
| 505 |
-KODO_SCREEN_LOGIN_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fscreen%2Fadmin%2Flogin%3Fbrand_id%3D{{0}}%26token%3D{{1}}'.format(OAUTH_DOMAIN, BASE_DOMAIN)
|
|
| 519 |
+KODO_CLERK_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fclerk%3Fbrand_id%3D{{0}}'.format(
|
|
| 520 |
+ OAUTH_DOMAIN, BASE_DOMAIN) |
|
| 521 |
+KODO_SCREEN_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fscreen%2Fadmin%2Foauth%3Fbrand_id%3D{{0}}'.format(
|
|
| 522 |
+ OAUTH_DOMAIN, BASE_DOMAIN) |
|
| 523 |
+KODO_SCREEN_LOGIN_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fscreen%2Fadmin%2Flogin%3Fbrand_id%3D{{0}}%26token%3D{{1}}'.format(
|
|
| 524 |
+ OAUTH_DOMAIN, BASE_DOMAIN) |
|
| 506 | 525 |
|
| 507 |
-KODO_SUPERSR_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fsupersr%2Foauth%3Fbrand_id%3D{{0}}'.format(OAUTH_DOMAIN, BASE_DOMAIN)
|
|
| 526 |
+KODO_SUPERSR_AUTH_URL = '{0}/w/o?r=http%3A%2F%2F{1}%2Fp%2Fsupersr%2Foauth%3Fbrand_id%3D{{0}}'.format(
|
|
| 527 |
+ OAUTH_DOMAIN, BASE_DOMAIN) |
|
| 508 | 528 |
|
| 509 |
-DJANGO_WE_COMPONENT_REDIRECT_URI = '{0}/we/component_preauth'.format(PREAUTH_DOMAIN)
|
|
| 529 |
+DJANGO_WE_COMPONENT_REDIRECT_URI = '{0}/we/component_preauth'.format(
|
|
| 530 |
+ PREAUTH_DOMAIN) |
|
| 510 | 531 |
|
| 511 | 532 |
# Redis 连接 |
| 512 | 533 |
REDIS_CACHE = connector(REDIS.get('default', {}))
|
@@ -569,3 +590,7 @@ DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' |
||
| 569 | 590 |
|
| 570 | 591 |
DEFAULT_START_DATE = '1970-01-02' |
| 571 | 592 |
DEFAULT_END_DATE = '9999-12-03' |
| 593 |
+ |
|
| 594 |
+# 腾讯电子签配置 |
|
| 595 |
+CONTRACT_LENSMAN_CONTRIBUTION_TEMPLATE_ID = 'yDCp3UU05rgksnUXtZsEvdrK1tRGb7ax' |
|
| 596 |
+CONTRACT_LENSMAN_CONTRIBUTION_OPERATOR_ID = 'yDCp3UU055m70lUx6jaTk1RVkiVkKenJ' |