Skip to content

Commit

Permalink
refactor: 自建服务
Browse files Browse the repository at this point in the history
  • Loading branch information
Honye committed Jun 23, 2024
1 parent 6ac19c0 commit 4f232dc
Show file tree
Hide file tree
Showing 83 changed files with 3,587 additions and 1,899 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,5 @@ sync_hook.script
project.private.config.json
private.key
private.*.key

backup
2 changes: 1 addition & 1 deletion @types/douban.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ declare namespace DouBan {
url: string;
}>;
title: string;
trailer: Trailer;
trailers: Trailer[];
type: SubjectType;
}

Expand Down
1 change: 1 addition & 0 deletions @types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ interface RequestController extends WechatMiniprogram.RequestTask {
interface RequestOption<T> extends Omit<WechatMiniprogram.RequestOption<T>, 'success' | 'fail' | 'complete'> {
baseURL?: string;
controller?: RequestController;
notAuthorization?: boolean
}

interface RequestSuccessResult<T> extends WechatMiniprogram.RequestSuccessCallbackResult<T> {
Expand Down
16 changes: 16 additions & 0 deletions @types/miniprogram.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// <reference path="./lib.wx.component.d.ts" />

declare namespace WechatMiniprogram {
interface FormEvent<Detail extends IAnyObject = IAnyObject> extends CustomEvent {
detail: {
value: Detail
formId: string
}
}

namespace Component {
interface A {
a: string
}
}
}
36 changes: 36 additions & 0 deletions @types/wxCloud.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
interface CloudFunctionBaseEvent {
userInfo: { appId: string; openId: string };
}

type CloudFunctionEvent<T extends Record<string, any> = {}> = CloudFunctionBaseEvent & T;
interface CloudFunctionContext {
callbackWaitsForEmptyEventLoop: boolean;
memory_limit_in_mb: number;
time_limit_in_ms: number;
request_id: string;
environment: string;
environ: string;
function_version: string;
function_name: string;
namespace: string;
tencentcloud_region: string;
tencentcloud_appid: string;
tencentcloud_uin: string;
}

interface CloudFunction<Event extends Record<string, any> = {}, Result = void> {
(event: CloudFunctionEvent<Event>, context: CloudFunctionContext): Result;
}

interface CallCloudOptions {
/** 是否显示加载提示框 */
loading?: boolean;
/** 是否显示错误提示框 */
showError?: boolean;
}

interface CallCloud {
(name: 'login', data: Record<string, any>, options: CallCloudOptions): Promise<any>;

(name: 'doouban', data: Record<string, any>, options: CallCloudOptions): Promise<any>;
}
95 changes: 90 additions & 5 deletions cloudfunctions/douban/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ exports.main = async (event, context) => {
/** 每日定时存储每日卡片信息 */
await storeTodayItem();
break;
case 'api.proxy':
// case 代理接口请求,伪装请求
return apiProxy(event.payload);
case 'login':
return login(event.payload);
case 'logout':
Expand Down Expand Up @@ -50,16 +53,13 @@ exports.main = async (event, context) => {
*/
const storeTodayItem = async () => {
// 云函数默认时区为 UTC+0
const date = new Date();
const utcTime = date.getTime() + date.getTimezoneOffset() * 60000;
const now = new Date(utcTime + 8 * 60 * 60 * 1000);
const res = await request({
headers: {
'User-Agent': 'api-client/0.1.3 com.douban.frodo/6.50.0'
'User-Agent': 'api-client/0.1.3 com.douban.frodo/8.0.0'
},
path: '/calendar/today',
data: {
date: now.toISOString().substring(0, 10),
date: new Intl.DateTimeFormat('zh-CN').format().replace(/\//g, '-'),
alt: 'json',
_sig: 'tuOyn+2uZDBFGAFBLklc2GkuQk4=',
_ts: 1610703479,
Expand Down Expand Up @@ -137,5 +137,90 @@ const logout = async () => {

throw new Error(`user openid=${wxContext.OPENID} not found`);
};

/**
*
* @param {WechatMiniprogram.RequestOption} params
*/
const apiProxy = (params) => {
const headers = Object.assign({},
{
Referer: 'https://servicewechat.com/wx2f9b06c1de1ccfca/81/page-frame.html',
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.2(0x18000236) NetType/WIFI Language/en'
},
params.header
);
return request({
url: params.url,
method: params.method,
data: params.data,
headers
});
}

/**
* @typedef {'movie_showing'|'movie_soon'} RankType
*/

/**
* 各个排行榜
* @param {object} params
* @param {RankType} params.type
* @param {object} params.params
*/
const getRankList = async (params) => {
const collectionName = params.type;
/** @type {Record<RankType, string>} */
const names = {
movie_showing: '正在热映',
movie_soon: '即将上映'
};
/**
* @type {{
* _id: string;
* update_time: Date;
* }}
*/
let stored;
try {
const ranks = await db.collection(collectionName)
.where({ key: collectionName })
.limit(1)
.get();
stored = ranks[0];
} catch (e) {
if (e.errCode === -502005) {
await db.createCollection(collectionName);
}
}
if (stored && stored.update_time.getTime() + 2 * 60 * 60 * 1000 > Date.now()) {
// 每两小时一更新
return stored.data;
}

const res = await apiProxy(params.params);
if (stored) {
// case 更新
db.collection(collectionName)
.doc(stored._id)
.update({
data: {
update_time: db.serverDate(),
data: res
}
});
} else {
// case 存储
db.collection(collectionName)
.add({
data: {
key: collectionName,
title: names[collectionName],
create_time: db.serverDate(),
update_time: db.serverDate(),
data: res
}
});
}
return res;
}
9 changes: 9 additions & 0 deletions miniprogram/apis/cloud/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const db = wx.cloud.database();

export const getBanners = () => {
return db.collection('banners')
.orderBy('id', 'desc')
.limit(4)
.get()
.then(({ data }) => data);
};
53 changes: 20 additions & 33 deletions miniprogram/apis/douban.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@
* @file 豆瓣 API
*/
import { request as baseRequest } from '../utils/request';
import wxCloud from '../utils/wxCloud';
import { store } from '../store/index';

const BASE_URL = 'https://d.imarkr.com/douban';
export let isLoginIng = false;
/**
* @param {boolean} value
*/
export const setLoginIng = (value) => {
isLoginIng = value;
};

const BASE_URL = 'https://mmovie.imarkr.com/douban/api';

/**
* @template T
Expand All @@ -14,55 +21,34 @@ const BASE_URL = 'https://d.imarkr.com/douban';
*/
const request = (params) => {
const accessToken = store.douban.accessToken;
const { header, data, ...rest } = {
const { header, notAuthorization, ...rest } = {
baseURL: BASE_URL,
...params,
};

return baseRequest({
header: {
...(accessToken && { Authorization: `Bearer ${accessToken}` }),
...(!notAuthorization && accessToken && { Authorization: `Bearer ${accessToken}` }),
...header,
},
data: {
apikey: '054022eaeae0b00e0fc068c0c0a2102a',
...data,
},
...rest,
})
.then((resp) => {
if (resp.ok) {
return resp.data;
} else if (resp.statusCode === 400 && [103, 106].includes(resp.data.code)) {
if (!isLoginIng) {
isLoginIng = true;
wx.navigateTo({
url: '/packages/douban/pages/login-phone/login-phone'
});
}
} else {
return Promise.reject(resp.data);
}
});
};

/**
* 使用云函数代理请求
* @param {WechatMiniprogram.RequestOption & { baseURL?: string }} params
*/
const request1 = (params) => {
const accessToken = store.douban.accessToken;
const { baseURL = BASE_URL } = params;
return wxCloud('douban', {
action: 'api.proxy',
payload: {
url: `${baseURL}${params.url}`,
header: Object.assign(
{},
accessToken && { Authorization: `Bearer ${accessToken}` },
params.header
),
data: {
apikey: '054022eaeae0b00e0fc068c0c0a2102a',
...(params.data || {})
}
}
});
};

/**
* 搜索
* @param {object} params
Expand Down Expand Up @@ -172,7 +158,8 @@ export const getTrailers = (params) => {
export const getHotMovies = (params) => {
return request({
url: '/subject_collection/movie_hot_gaia/items',
data: params
data: params,
notAuthorization: true
});
}

Expand Down
13 changes: 13 additions & 0 deletions miniprogram/apis/leancloud/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as AV from '../../libs/av-live-query-core-min';

/**
* @returns {Promise<any[]>}
*/
export const getBanners = async () => {
const query = new AV.Query('Banner');
const data = await query.find();
return data.map((item) => {
const { attributes, ...cols } = item;
return { ...cols, ... attributes };
});
};
73 changes: 73 additions & 0 deletions miniprogram/apis/server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { request } from '../../utils/request'

/**
* @param {RequestOption} config
*/
const fetch = async (config) => {
config.baseURL = 'https://sanphantom.com/go'
const resp = await request(config)
if (resp.ok) {
return resp
}
return Promise.reject(resp.data)
}

export const apiGetBanners = () => {
return fetch({ url: '/banners' })
}

export const apiGetHotMovies = (data) => {
return fetch({ url: '/douban/hot/items', data })
}

export const apiGetShowingMovies = (data) => {
return fetch({ url: '/douban/showing/items', data })
}

export const apiGetSoonMovies = (data) => {
return fetch({ url: '/douban/soon/items', data })
}

export const apiGetDetail = (params) => {
const { id, type = 'movie' } = params
return fetch({ url: `/douban/${type}/${id}` })
}

export const apiGetCelebrities = (params) => {
const { id, type = 'movie' } = params
return fetch({ url: `/douban/${type}/${id}/celebrities` })
}

export const apiSearch = (data) => {
return fetch({ url: '/douban/search', data })
}

export const apiGetPhotos = (params) => {
const { id, type = 'movie', ...data } = params
return fetch({ url: `/douban/${type}/${id}/photos`, data })
}

export const apiGetInterests = (params) => {
const { id, type = 'movie', ...data } = params
return fetch({ url: `/douban/${type}/${id}/interests`, data })
}

export const apiGetUserInterests = (userID, data) => {
return fetch({ url: `/douban/user/${userID}/interests`, data })
}

export const apiGetCaptcha = (data) => {
return fetch({
url: '/douban/login/request_phone_code',
method: 'POST',
data
})
}

export const apiVerifyCaptcha = (data) => {
return fetch({
url: '/douban/login/verify_phone_code',
method: 'POST',
data
})
}
Loading

0 comments on commit 4f232dc

Please sign in to comment.