基本完成清单功能

master
barney 2 years ago
parent 7d27d891f1
commit d1a3070aab
  1. BIN
      db.sqlite3
  2. 12
      django_weixinapp/settings.py
  3. 175
      frontend/pages/index/index.js
  4. 0
      identifier.sqlite
  5. 4
      weixin/admin.py
  6. 26
      weixin/migrations/0001_initial.py
  7. 28
      weixin/models.py
  8. 5
      weixin/urls.py
  9. 77
      weixin/views.py

Binary file not shown.

@ -108,11 +108,11 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_TZ = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
@ -124,3 +124,11 @@ STATIC_URL = 'static/'
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication', # 使用simplejwt
)
}

@ -1,18 +1,10 @@
Component({
data: {
// 数据
// 测试数据
items: [{
id: 3,
id: 1,
content: '打游戏',
checked: false
}, {
id: 2,
content: '吃饭',
checked: false,
}, {
id: 1,
content: '睡觉',
checked: false,
}],
// 输入框当前内容
inputedValue: "",
@ -20,6 +12,13 @@ Component({
methods: {
// 监听多选框的状态改变事件
checkboxChange(e) {
// 登录后才可以修改待办事项的状态
this.login(() => {
this._checkboxChange(e);
})
},
// 多选框状态改变实际处理函数
_checkboxChange(e) {
// 页面特有的数据
// 获取本地数据的写法为this.data.xxx
const items = JSON.parse(JSON.stringify(this.data.items));
@ -51,6 +50,9 @@ Component({
// 打印的内容会展现在调试器中
// console.log(this.data.items)
// 上传数据到后端
this.uploadData(items);
},
// 监听键盘输入事件
keyInput(e) {
@ -58,10 +60,18 @@ Component({
inputedValue: e.detail.value
})
},
// 监听提交按钮
// 监听按钮点击事件
inputSubmit() {
// 登录之后才可以添加新的待办事项
this.login(() => {
this._inputSubmit();
})
},
// 点击提交按钮后实际执行的函数
_inputSubmit() {
// 读取数据
let items = JSON.parse(JSON.stringify(this.data.items));
// console.log("上传前: ",items);
// 设置新条目的id
let newId = 1;
if (this.data.inputedValue === "") {
@ -94,6 +104,117 @@ Component({
key: "items",
data: items
});
// items和this.data.items指向的值一模一样
// console.log("上传后: ", items);
// console.log("上传后:", this.data.items);
this.uploadData(items);
},
// 检查token是否过期
isTokenAvailable() {
const now = Date.parse(new Date());
try {
const accessTime = wx.getStorageSync('access_time');
// token的有效时间为5分钟
if ((accessTime !== '') && (now - accessTime < 5 * 60 * 1000)) {
return true;
}
} catch {
// do something
}
return false;
},
// 获取token
getToken(callback) {
// --------------
// 步骤一:获取code
// --------------
wx.login({
success(res) {
if (res.code) {
// 查看code
// console.log("code: ", res.code);
// --------------
// 步骤二:用code换取token
// --------------
wx.request({
url: 'http://127.0.0.1:8000/api/weixin/login/',
method: 'POST',
data: {
code: res.code,
},
success: res => {
// 查看是否收到token
// console.log(res.data);
console.log("重新获取token成功!");
const access = res.data.access;
// 将token保存到本地
wx.setStorage({
key: 'access',
data: access,
});
// 保存获取token的时间
wx.setStorage({
key: 'access_time',
data: Date.parse(new Date()),
});
// --------------
// 步骤三:用token获取用户数据
// --------------
// wx.request({
// url: 'http://127.0.0.1:8000/api/weixin/data/',
// type: 'GET',
// header: {
// 'Authorization': 'Bearer ' + access
// },
// success: res => {
// console.log(res.data);
// // 调用回调函数
// // 以便登录成功后执行后续操作
// // 因为wx.login,wx.request都是异步的,
// // 这样写才能保证callback一定晚于wx.login执行
// callback();
// }
// })
callback();
}
});
} else {
console.log("登录失败! " + res.errMsg);
}
}
});
},
// 登录函数
login(callback = (() => {})) {
if (!this.isTokenAvailable()) {
console.log("token已失效,需要重新向django请求token!");
// 获取token并传入callback
this.getToken(callback);
} else {
console.log("token有效!从缓存中直接读取!");
// const access = wx.getStorageSync('access');
// console.log("token: ", access);
callback();
}
},
// 将清单数据上传django
uploadData(items) {
const access = wx.getStorageSync('access');
wx.request({
url: 'http://127.0.0.1:8000/api/weixin/data/',
method: 'POST',
header: {
'Authorization': 'Bearer ' + access,
},
data: {
items: items,
},
success: res => {
// 上传成功后打印一下
console.log("上传成功");
console.log(res);
},
})
}
},
//生命周期函数
@ -106,19 +227,29 @@ Component({
key: 'items',
success: res => {
this.setData({
items: res.data.filter(v=>v.checked===false)
items: res.data.filter(v => v.checked === false)
})
}
});
// 请求后端数据
wx.request({
url: 'http://127.0.0.1:8000/api/weixin/login/',
success: res => {
console.log(res.data);
}
})
});
this.login(() => {
const access = wx.getStorageSync('access');
// 从后端获取items数据
wx.request({
url: 'http://127.0.0.1:8000/api/weixin/data/',
type: 'GET',
header: {
'authorization': 'Bearer ' + access,
},
success: res => {
console.log("读取数据成功!");
// 只读取未完成的清单
this.setData({
items: res.data.items.filter(v => v.checked === false)
})
// console.log(this.data.items);
}
})
});
}
}
})

@ -1,3 +1,5 @@
from django.contrib import admin
from weixin.models import Profile
# Register your models here.
admin.site.register(Profile)

@ -0,0 +1,26 @@
# Generated by Django 4.1.1 on 2022-10-06 16:48
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import weixin.models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('items', models.JSONField(default=weixin.models.empty_items)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

@ -1,3 +1,29 @@
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
# 默认items为空
def empty_items():
return {'items': []}
class Profile(models.Model):
# 与User外键链接
user = models.OneToOneField(User, on_delete=models.CASCADE)
# 待办事项的json字段
items = models.JSONField(default=empty_items)
# 每当User创建或者保存时通知对应的@receiver装饰的函数
# 创建或保存对应的Profile模型
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()

@ -1,7 +1,8 @@
from django.urls import path
from weixin.views import WeixinLogin
from weixin.views import WeixinLogin, UserData
app_name = 'weixin'
urlpatterns = [
path('login/', WeixinLogin.as_view(), name='login')
path('login/', WeixinLogin.as_view(), name='login'),
path('data/', UserData.as_view(), name='data'),
]

@ -1,10 +1,77 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from django.contrib.auth.models import User
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.permissions import IsAuthenticated
import requests
import json
class WeixinLogin(APIView):
# 获取用户数据
class UserData(APIView):
# 鉴权方式
permission_classes = [IsAuthenticated]
def get(self, request, format=None):
"""
提供get请求
"""
return Response({"data": "Hello World!"})
"""将当前用户的清单数据items返回"""
print('Get data: ',request.user.profile.items)
return Response({
'code': 'Get ok',
'items': request.user.profile.items['items']
})
def post(self, request, format=None):
"""将用户上传的数据更新到数据库"""
user = request.user
user.profile.items = request.data
user.save()
print('Post data: ', user.profile.items)
return Response({'code': 'Post ok'})
class WeixinLogin(APIView):
def post(self, request, format=None):
"""提供post请求"""
# 从请求中获取code
code = json.loads(request.body).get('code')
print("code: " + code);
# 填写测试号的AppID和AppSecret
appid = 'wxe35222de7aa53383'
appsecret = '424c7145423396a00c987ca0e5ea8ae9'
# 微信接口服务地址
base_url = 'https://api.weixin.qq.com/sns/jscode2session'
# 拼接参数形成完整url
url = base_url + '?appid=' + appid + '&secret=' + appsecret + '&js_code=' + code + '&grant_type=authorization_code'
response = requests.get(url)
# 获取openid和session_key
try:
openid = response.json()['openid']
session_key = response.json()['session_key'] # session_key是对用户数据进行了加密签名的密钥,不要泄露
except KeyError:
return Response({'code': 'failed'})
else:
# 打印到后端命令行
print("openid: " + openid)
print("session_key: " + session_key)
# 根据openid确定用户的本地身份
try:
user = User.objects.get(username=openid)
except User.DoesNotExist:
user = None
if user:
user = User.objects.get(username=openid)
# 如果用户不存在,则创建openid用户
else:
user = User.objects.create(
username=openid,
password=openid,
)
# 用于给用户提供临时token
refresh = RefreshToken.for_user(user)
return Response({
'code': 'success',
'refresh': str(refresh),
'access': str(refresh.access_token),
})

Loading…
Cancel
Save