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