@@ -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' |