新增摄影师合同相关接口

FFIB 9 mois auparavant
Parent
Commettre
2fdf901626

+ 23 - 0
account/migrations/0064_auto_20240808_1559.py

@@ -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
+    ]

+ 4 - 0
account/models.py

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

+ 20 - 0
api/lensman/activity_admin_views.py

@@ -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, '增加摄影师投稿收入成功')

+ 31 - 0
api/lensman/contract_admin_views.py

@@ -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
+    })

+ 131 - 0
api/lensman/contract_mp_views.py

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

+ 12 - 0
api/lensman/lensman_urls.py

@@ -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
+]

+ 4 - 1
api/urls.py

@@ -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
apps/contract/__init__.py


+ 3 - 0
apps/contract/admin.py

@@ -0,0 +1,3 @@
1
+from django.contrib import admin
2
+
3
+# Register your models here.

+ 6 - 0
apps/contract/apps.py

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

+ 41 - 0
apps/contract/migrations/0001_initial.py

@@ -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
apps/contract/migrations/__init__.py


+ 91 - 0
apps/contract/models.py

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

+ 3 - 0
apps/contract/tests.py

@@ -0,0 +1,3 @@
1
+from django.test import TestCase
2
+
3
+# Create your tests here.

+ 3 - 0
apps/contract/views.py

@@ -0,0 +1,3 @@
1
+from django.shortcuts import render
2
+
3
+# Create your views here.

+ 0 - 0
apps/lensman/activity/__init__.py


+ 3 - 0
apps/lensman/activity/admin.py

@@ -0,0 +1,3 @@
1
+from django.contrib import admin
2
+
3
+# Register your models here.

+ 6 - 0
apps/lensman/activity/apps.py

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

+ 32 - 0
apps/lensman/activity/migrations/0001_initial.py

@@ -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
apps/lensman/activity/migrations/__init__.py


+ 37 - 0
apps/lensman/activity/models.py

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

+ 3 - 0
apps/lensman/activity/tests.py

@@ -0,0 +1,3 @@
1
+from django.test import TestCase
2
+
3
+# Create your tests here.

+ 3 - 0
apps/lensman/activity/views.py

@@ -0,0 +1,3 @@
1
+from django.shortcuts import render
2
+
3
+# Create your views here.

+ 44 - 19
kodo/settings.py

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

+ 0 - 0
utils/amount_utils.py