@@ -0,0 +1,25 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.26 on 2020-01-13 10:32 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ('logs', '0005_mchinfodecryptloginfo'), |
|
12 |
+ ] |
|
13 |
+ |
|
14 |
+ operations = [ |
|
15 |
+ migrations.AddField( |
|
16 |
+ model_name='mchinfoencryptloginfo', |
|
17 |
+ name='code', |
|
18 |
+ field=models.CharField(blank=True, db_index=True, help_text='\u4e5d\u4f4d\u7684\u5b57\u7b26\u4e32\u539f\u59cb\u7801', max_length=16, null=True, verbose_name='code'), |
|
19 |
+ ), |
|
20 |
+ migrations.AddField( |
|
21 |
+ model_name='mchinfoencryptloginfo', |
|
22 |
+ name='code_url', |
|
23 |
+ field=models.CharField(blank=True, db_index=True, help_text='28\u4f4d\u666e\u901a\u7801\u5b57\u7b26\t', max_length=128, null=True, verbose_name='code_url'), |
|
24 |
+ ), |
|
25 |
+ ] |
@@ -18,6 +18,10 @@ class MchInfoEncryptLogInfo(BaseModelMixin): |
||
18 | 18 |
|
19 | 19 |
sn = models.CharField(_(u'sn'), max_length=32, blank=True, null=True, help_text=u'序列号', db_index=True) |
20 | 20 |
|
21 |
+ # 一物一码 |
|
22 |
+ code = models.CharField(_(u'code'), max_length=16, blank=True, null=True, help_text=u'九位的字符串原始码', db_index=True) |
|
23 |
+ code_url = models.CharField(_(u'code_url'), max_length=128, blank=True, null=True, help_text=u'28位普通码字符 ', db_index=True) |
|
24 |
+ |
|
21 | 25 |
operator_id = models.CharField(_(u'operator_id'), max_length=32, blank=True, null=True, help_text=u'操作员唯一标识', db_index=True) |
22 | 26 |
|
23 | 27 |
class Meta: |
@@ -0,0 +1,12 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.contrib import admin |
|
4 |
+ |
|
5 |
+from marketcode.models import MarketCodeInfo |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class MarketCodeInfoAdmin(admin.ModelAdmin): |
|
9 |
+ list_display = ('isv_application_id', 'application_id', 'code', 'code_url', 'has_used', 'status', 'created_at', 'updated_at') |
|
10 |
+ |
|
11 |
+ |
|
12 |
+admin.site.register(MarketCodeInfo, MarketCodeInfoAdmin) |
@@ -0,0 +1,8 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.apps import AppConfig |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class MarketcodeConfig(AppConfig): |
|
8 |
+ name = 'marketcode' |
@@ -0,0 +1,34 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.26 on 2020-01-13 10:32 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ initial = True |
|
11 |
+ |
|
12 |
+ dependencies = [ |
|
13 |
+ ] |
|
14 |
+ |
|
15 |
+ operations = [ |
|
16 |
+ migrations.CreateModel( |
|
17 |
+ name='MarketCodeInfo', |
|
18 |
+ fields=[ |
|
19 |
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|
20 |
+ ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')), |
|
21 |
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')), |
|
22 |
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')), |
|
23 |
+ ('isv_application_id', models.CharField(blank=True, db_index=True, help_text='\u5916\u90e8\u5355\u53f7', max_length=128, null=True, verbose_name='isv_application_id')), |
|
24 |
+ ('application_id', models.IntegerField(db_index=True, default=0, help_text='\u7533\u8bf7\u5355\u53f7', verbose_name='application_id')), |
|
25 |
+ ('code', models.CharField(blank=True, db_index=True, help_text='\u4e5d\u4f4d\u7684\u5b57\u7b26\u4e32\u539f\u59cb\u7801', max_length=16, null=True, verbose_name='code')), |
|
26 |
+ ('code_url', models.CharField(blank=True, db_index=True, help_text='28\u4f4d\u666e\u901a\u7801\u5b57\u7b26\t', max_length=128, null=True, verbose_name='code_url')), |
|
27 |
+ ('has_used', models.BooleanField(db_index=True, default=True, help_text='\u662f\u5426\u5df2\u4f7f\u7528', verbose_name='has_used')), |
|
28 |
+ ], |
|
29 |
+ options={ |
|
30 |
+ 'verbose_name': '\u4e00\u7269\u4e00\u7801\u4fe1\u606f', |
|
31 |
+ 'verbose_name_plural': '\u4e00\u7269\u4e00\u7801\u4fe1\u606f', |
|
32 |
+ }, |
|
33 |
+ ), |
|
34 |
+ ] |
@@ -0,0 +1,20 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.26 on 2020-01-13 10:51 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ('marketcode', '0001_initial'), |
|
12 |
+ ] |
|
13 |
+ |
|
14 |
+ operations = [ |
|
15 |
+ migrations.AlterField( |
|
16 |
+ model_name='marketcodeinfo', |
|
17 |
+ name='has_used', |
|
18 |
+ field=models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u5df2\u4f7f\u7528', verbose_name='has_used'), |
|
19 |
+ ), |
|
20 |
+ ] |
@@ -0,0 +1,25 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.26 on 2020-01-13 18:20 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ('marketcode', '0002_auto_20200113_1851'), |
|
12 |
+ ] |
|
13 |
+ |
|
14 |
+ operations = [ |
|
15 |
+ migrations.AddField( |
|
16 |
+ model_name='marketcodeinfo', |
|
17 |
+ name='code_index', |
|
18 |
+ field=models.IntegerField(default=0, help_text='\u8be5\u7801\u5728\u6279\u6b21\u4e2d\u7684\u504f\u79fb\u91cf\t', verbose_name='code_index'), |
|
19 |
+ ), |
|
20 |
+ migrations.AddField( |
|
21 |
+ model_name='marketcodeinfo', |
|
22 |
+ name='lattice', |
|
23 |
+ field=models.CharField(blank=True, help_text='361 \u5b57\u8282\u7684 01 \u70b9\u9635\uff0c\u7528\u4e8e\u652f\u6301\u751f\u6210 19 * 19 \u7684\u5fae\u578b\u7801\uff0c0 \u4e3a\u767d\uff0c1 \u4e3a\u9ed1', max_length=361, null=True, verbose_name='code'), |
|
24 |
+ ), |
|
25 |
+ ] |
@@ -0,0 +1,24 @@ |
||
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 |
+ |
|
7 |
+ |
|
8 |
+class MarketCodeInfo(BaseModelMixin): |
|
9 |
+ isv_application_id = models.CharField(_(u'isv_application_id'), max_length=128, blank=True, null=True, help_text=u'外部单号', db_index=True) |
|
10 |
+ application_id = models.IntegerField(_(u'application_id'), default=0, help_text=u'申请单号', db_index=True) |
|
11 |
+ |
|
12 |
+ lattice = models.CharField(_(u'code'), max_length=361, blank=True, null=True, help_text=u'361 字节的 01 点阵,用于支持生成 19 * 19 的微型码,0 为白,1 为黑') |
|
13 |
+ code = models.CharField(_(u'code'), max_length=16, blank=True, null=True, help_text=u'九位的字符串原始码', db_index=True) |
|
14 |
+ code_index = models.IntegerField(_(u'code_index'), default=0, help_text=u'该码在批次中的偏移量 ') |
|
15 |
+ code_url = models.CharField(_(u'code_url'), max_length=128, blank=True, null=True, help_text=u'28位普通码字符 ', db_index=True) |
|
16 |
+ |
|
17 |
+ has_used = models.BooleanField(_(u'has_used'), default=False, help_text=_(u'是否已使用'), db_index=True) |
|
18 |
+ |
|
19 |
+ class Meta: |
|
20 |
+ verbose_name = _(u'一物一码信息') |
|
21 |
+ verbose_name_plural = _(u'一物一码信息') |
|
22 |
+ |
|
23 |
+ def __unicode__(self): |
|
24 |
+ return unicode(self.pk) |
@@ -0,0 +1,6 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.test import TestCase |
|
5 |
+ |
|
6 |
+# Create your tests here. |
@@ -0,0 +1,6 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.shortcuts import render |
|
5 |
+ |
|
6 |
+# Create your views here. |
@@ -0,0 +1,25 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.26 on 2020-01-13 10:32 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ('mch', '0041_activityinfo_coupon_id'), |
|
12 |
+ ] |
|
13 |
+ |
|
14 |
+ operations = [ |
|
15 |
+ migrations.AlterField( |
|
16 |
+ model_name='modelinfo', |
|
17 |
+ name='integral', |
|
18 |
+ field=models.IntegerField(default=100, help_text='\u3010\u9500\u552e\u5458\u3011\u5361\u8def\u91cc', verbose_name='integral'), |
|
19 |
+ ), |
|
20 |
+ migrations.AlterField( |
|
21 |
+ model_name='modelinfo', |
|
22 |
+ name='shot_member_integral', |
|
23 |
+ field=models.IntegerField(default=0, help_text='\u3010\u6d88\u8d39\u8005\u3011\u955c\u5934\u4f1a\u5458\u79ef\u5206', verbose_name='shot_member_integral'), |
|
24 |
+ ), |
|
25 |
+ ] |
@@ -0,0 +1,41 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.conf import settings |
|
4 |
+from pywe_marketcode import applycodedownload |
|
5 |
+from pywe_storage import RedisStorage |
|
6 |
+ |
|
7 |
+from marketcode.models import MarketCodeInfo |
|
8 |
+from utils.redis.connect import r |
|
9 |
+ |
|
10 |
+ |
|
11 |
+WECHAT = settings.WECHAT |
|
12 |
+ |
|
13 |
+ |
|
14 |
+def marketcodedownload(application_id, code_start, code_end, isv_application_id=''): |
|
15 |
+ wxcfg = WECHAT.get('JSAPI', {}) |
|
16 |
+ |
|
17 |
+ appid = wxcfg.get('appID') |
|
18 |
+ secret = wxcfg.get('appsecret') |
|
19 |
+ |
|
20 |
+ codes = applycodedownload(application_id=application_id, code_start=code_start, code_end=code_end, appid=appid, secret=secret, token=None, storage=RedisStorage(r)) |
|
21 |
+ |
|
22 |
+ lattice, code, code_index, code_url = '' |
|
23 |
+ for idx, item in enumerate(codes): |
|
24 |
+ if idx % 4 == 0: |
|
25 |
+ lattice = item |
|
26 |
+ if idx % 4 == 1: |
|
27 |
+ code = item |
|
28 |
+ if idx % 4 == 2: |
|
29 |
+ code_index = item |
|
30 |
+ if idx % 4 == 3: |
|
31 |
+ code_url = item |
|
32 |
+ MarketCodeInfo.objects.create( |
|
33 |
+ isv_application_id=isv_application_id, |
|
34 |
+ application_id=application_id, |
|
35 |
+ lattice=lattice, |
|
36 |
+ code=code, |
|
37 |
+ code_index=code_index, |
|
38 |
+ code_url=code_url |
|
39 |
+ ) |
|
40 |
+ |
|
41 |
+ |
@@ -1,6 +1,7 @@ |
||
1 | 1 |
pywe-component==1.0.1 |
2 | 2 |
pywe-component-preauthcode==1.0.3 |
3 | 3 |
pywe-jssdk==1.1.0 |
4 |
+pywe-marketcode==1.0.1 |
|
4 | 5 |
pywe-membercard==1.0.1 |
5 | 6 |
pywe-miniapp==1.1.5 |
6 | 7 |
pywe-oauth==1.0.7 |
@@ -90,6 +90,11 @@ class MemberCouponStatusCode(BaseStatusCode): |
||
90 | 90 |
USER_COUPON_HAS_EXPIRED = StatusCodeField(504012, 'User Coupon Has Expired', description=u'用户优惠券已过期') |
91 | 91 |
|
92 | 92 |
|
93 |
+class MarketCodeStatusCode(BaseStatusCode): |
|
94 |
+ """ 一物一码相关错误码 5050xx """ |
|
95 |
+ MARKET_CODE_NOT_FOUND = StatusCodeField(505001, 'Market Code Not Found', description=u'一物一码不存在') |
|
96 |
+ |
|
97 |
+ |
|
93 | 98 |
class LensmanStatusCode(BaseStatusCode): |
94 | 99 |
""" 摄影师相关错误码 4000xx """ |
95 | 100 |
LENSMAN_NOT_FOUND = StatusCodeField(400001, 'Lensman Not Found', description=u'摄影师不存在') |