Commit cb1ed766 authored by vicotor's avatar vicotor

add code

parents
Pipeline #893 failed with stages
.idea
.vscode
-- WARNING: This schema is for context only and is not meant to be run.
-- Table order and constraints may not be valid for execution.
CREATE TABLE invitation (
user_id uuid NOT NULL,
inviter_id uuid,
wallet_address character varying NOT NULL,
real_name character varying NOT NULL DEFAULT ''::character varying,
x_name character varying,
wechat_name character varying,
created_at timestamp with time zone NOT NULL DEFAULT now(),
updated_at timestamp without time zone,
is_signed boolean DEFAULT false,
reward integer DEFAULT 0,
CONSTRAINT invitation_pkey PRIMARY KEY (user_id),
CONSTRAINT invitation_user_id_fkey FOREIGN KEY (user_id) REFERENCES auth.users(id),
CONSTRAINT invitation_inviter_id_fkey FOREIGN KEY (inviter_id) REFERENCES auth.users(id)
);
DROP TABLE IF EXISTS sign_config;
CREATE TABLE IF NOT EXISTS sign_config (
id SERIAL PRIMARY KEY,
qr_code_secret TEXT NOT NULL,
venue_latitude DECIMAL(10,8) NOT NULL,
venue_longitude DECIMAL(11,8) NOT NULL,
start_time TIMESTAMP NOT NULL,
end_time TIMESTAMP NOT NULL,
radius_km DECIMAL(5,2) DEFAULT 1.0,
reward_base_amount DECIMAL(10,0) DEFAULT 10,
reward_max_amount DECIMAL(10,0) DEFAULT 1000,
created_at TIMESTAMP DEFAULT NOW()
);
-- 签到记录表
CREATE TABLE IF NOT EXISTS sign_logs (
id SERIAL PRIMARY KEY,
user_id UUID REFERENCES auth.users(id),
qr_code TEXT NOT NULL,
user_latitude DECIMAL(10,8) NOT NULL,
user_longitude DECIMAL(11,8) NOT NULL,
distance_km DECIMAL(8,3),
is_successful BOOLEAN DEFAULT false,
error_reason TEXT,
signed_at TIMESTAMP DEFAULT NOW()
);
INSERT INTO sign_config (
qr_code_secret,
venue_latitude,
venue_longitude,
start_time,
end_time,
radius_km,
reward_base_amount,
reward_max_amount
) VALUES (
'meeting_checkin_2024_08_29_abcdefghijklmnopqrstuvwxyz123456789012',
22.2835121, --pier 1929
114.1743664,
'2025-08-28 11:30:00', -- UTC 时间,对应北京时间 19:30
'2025-08-29 12:30:00', -- UTC 时间,对应北京时间 20:30
1.0,
10,
1000
);
supabase init
supabase start
supabase functions new <func-name>
supabase login
supabase functions serve
supabase functions deploy <func-name>
user_id,inviter_id,wallet_address,real_name,x_name,wechat_name,created_at,updated_at,is_signed,reward
5eea1c4e-7139-4e51-b397-66de014f0420,8a650653-064d-4247-8e19-daa75b312691,0x4858091cda927d1Aa2f82Bdb1Fd76c64A66d575b,者也,者也,null,2025-08-25 19:15:35.236896+00,null,false,0
10218a22-7de3-4d1a-9e7a-37e8c7382d10,f60a993e-0001-4789-87d2-2f4ca5a267a5,0x2df73eb9fa43303958ef20de3042b7f3cc4c2231,索罗先生,@HacashBaokuai,null,2025-08-25 19:54:07.789516+00,null,false,0
b7088b02-d965-4fc7-8e66-9e0cb9f8458f,83eb00fc-bbba-46b8-8769-eb8393adbae4,0x72Db6aB1D06B8e90fAAe6A43240CeF3a20EC60D4,Angel,款姐,null,2025-08-25 21:50:07.692387+00,null,false,0
0acab699-b663-44f9-b9d6-240404e6a66f,c44b72d2-96cb-4efe-ba97-12cbbdb872b8,0x243bc00e1761f2be1e4918450978eb87ace3bd75,韭菜腾,腾,null,2025-08-25 23:52:22.65308+00,null,false,0
61388fbd-447b-466c-91ac-21ca0ffadd68,f60a993e-0001-4789-87d2-2f4ca5a267a5,0xB237Ca93361eB1E7Ba4DD316dfA2f26267b05119,王林娟,娟姐,null,2025-08-26 01:27:48.811184+00,null,false,0
d6c2f490-e3dc-42f3-99ca-e14d6b56e67a,8d194d01-ea08-40dd-901b-a5c032b6bfba,0xCb7559B648eE663A2B0C569837F510D5f0ABAaD1,Qw,Zx,Ee,2025-08-25 03:19:47.277779+00,2025-08-25 03:28:35.145018,false,0
8a650653-064d-4247-8e19-daa75b312691,8d194d01-ea08-40dd-901b-a5c032b6bfba,0xCb7559B648eE663A2B0C569837F510D5f0ABAaD1,TEST,Xx,Ww,2025-08-25 03:51:55.503276+00,null,false,0
3c884aee-80e2-41e5-9ff6-f33ae6d7316a,0acab699-b663-44f9-b9d6-240404e6a66f,0x7922e18538abe8d9d0306c8d65802823fd013e2c,复利人生,复利,null,2025-08-26 01:47:00.550642+00,null,false,0
062cf43f-922a-4087-9cdc-bbdd3d6b211d,8a650653-064d-4247-8e19-daa75b312691,0xCb7559B648eE663A2B0C569837F510D5f0ABAaD1,Chao,X,W,2025-08-25 04:44:17.410021+00,2025-08-25 04:48:55.216146,false,0
b6610257-fceb-4ad2-9dc6-67eda344c061,83eb00fc-bbba-46b8-8769-eb8393adbae4,0xfb30FE6EB6b5eB28700aC23a37d24a07855CF7D9,李秀美,mudan1568,null,2025-08-26 01:47:25.907713+00,null,false,0
03471de2-4c1a-4e84-a49e-3e8b1f7b21e3,0acab699-b663-44f9-b9d6-240404e6a66f,0xC7659e77E0728b80735aD8af4d8522dc9F12A723,陈文强,chenwenqiang19910717,null,2025-08-26 01:47:57.721404+00,null,false,0
7c68369d-3d00-4e32-b45d-c09da7f41a24,8a650653-064d-4247-8e19-daa75b312691,0xCb7559B648eE663A2B0C569837F510D5f0ABAaD1,luanle,qq,qw,2025-08-25 04:22:30.294423+00,2025-08-25 05:09:03.911259,false,0
56c15803-bbf5-47fc-be50-8c25f23d45d6,062cf43f-922a-4087-9cdc-bbdd3d6b211d,0xCb7559B648eE663A2B0C569837F510D5f0ABAaD1,Xq,A,W,2025-08-25 05:20:04.823137+00,null,false,0
26c731f2-ff9d-4e95-944a-9e543c43264a,062cf43f-922a-4087-9cdc-bbdd3d6b211d,0x3e3b4d16CE35840C28f90edb7f38e5bdd976C7E3,Vicotor,Vicotor,Vicotor,2025-08-25 05:28:18.554827+00,null,false,0
f3b551fa-b652-44e0-8c2e-a63aa7fc5886,8a650653-064d-4247-8e19-daa75b312691,0xCb7559B648eE663A2B0C569837F510D5f0ABAaD1,TEST NEW,w,q,2025-08-25 03:59:28.531686+00,2025-08-25 05:58:14.017302,false,0
5188fc0d-f02d-43eb-8442-3f3923d75524,0acab699-b663-44f9-b9d6-240404e6a66f,0x7400F78A7eE297Cf09ba94f177594ECf6b349022,若馨,0xruoxin,null,2025-08-26 01:48:35.523744+00,null,false,0
c4fd6e70-e60e-40bc-81f8-96bf8bdc3635,5270ab7b-47a9-4098-9ea8-ccec83c6cfce,0xCb7559B648eE663A2B0C569837F510D5f0ABAaD1,AA,Q,S,2025-08-25 06:08:35.844416+00,null,false,0
3c91e612-95d7-4e9e-8d2e-f8daf89ff869,a50305c2-1467-4674-9894-a14c342673f5,0x82f989684c97900a17479efbcbc80f40da5071bf,老王2,likeweb3,wangqizhebbiubi,2025-08-25 07:20:48.292297+00,null,false,0
f60a993e-0001-4789-87d2-2f4ca5a267a5,8a650653-064d-4247-8e19-daa75b312691,0x0c96E710949cA86342AB0b3c460Ab6Ba3CfeAa49,文文,可爱,Btc151319,2025-08-25 17:43:09.906351+00,2025-08-27 16:40:23.428382,false,0
d1c35adc-f69a-4374-9c98-e3c10a5988a2,0acab699-b663-44f9-b9d6-240404e6a66f,0x8af42c591566548f3C7cCc1107Ce7dc08EB2c531,方舟,@ww2775375905,null,2025-08-26 01:49:16.766271+00,null,false,0
d1b1842c-9edc-49ab-b83e-c9ddd0a298ba,0acab699-b663-44f9-b9d6-240404e6a66f,0x0ffBE23D966D81aA2e655f9258E11b514409e35E,赵航翊,趙航翊,null,2025-08-26 01:49:20.433105+00,null,false,0
f7c6f2cd-41bf-4e9f-a99a-f3966a10b62e,8a650653-064d-4247-8e19-daa75b312691,0x1234567890123456789012345678901234567866,hi mova4,xxxxxyyyzzz,wwwwzzz000,2025-08-25 07:57:03.254194+00,2025-08-25 08:06:58.17193,false,0
a5a93f11-097c-4d03-a06b-70cd6c7fd813,8d194d01-ea08-40dd-901b-a5c032b6bfba,0xCb7559B648eE663A2B0C569837F510D5f0ABAaD1,q,q,q,2025-08-25 01:30:04.341088+00,2025-08-25 10:22:08.40837,false,0
06624037-5439-4bd3-9abf-bbcb86235c4c,8a650653-064d-4247-8e19-daa75b312691,0x014702f872C1E0A7314a8D25aC1034257F28BBf5,VChain,ViChain,Vicotor,2025-08-25 06:07:33.62698+00,2025-08-26 09:04:09.069514,false,0
c25d6fa5-0bba-4628-84b2-a17e9bc7ea77,f60a993e-0001-4789-87d2-2f4ca5a267a5,0x3d42718ccae836db1a89a636c1b716e534fc29c1,老王老王,123,123,2025-08-25 18:20:29.414424+00,null,false,0
8eeee7dc-b400-4037-ae60-dab0c624e44d,f60a993e-0001-4789-87d2-2f4ca5a267a5,0x212FC278bF781Df2D31294a0eb9bD4Cff4091960,梨浅,@liqiangrace,liqiangrace,2025-08-25 18:29:05.147952+00,null,false,0
c44b72d2-96cb-4efe-ba97-12cbbdb872b8,f60a993e-0001-4789-87d2-2f4ca5a267a5,0x3061148c2439013950adcbdaedb0e26471799722,Kienvizhu,0x小霸王,17503000777,2025-08-25 18:31:23.116788+00,2025-08-25 18:32:09.503547,false,0
83eb00fc-bbba-46b8-8769-eb8393adbae4,c44b72d2-96cb-4efe-ba97-12cbbdb872b8,0xE6D4c0Df449b2eDE76423758d713BB5b2dF65937,Jack Cai,csc41319,19913199131,2025-08-25 18:41:26.986864+00,null,false,0
5270ab7b-47a9-4098-9ea8-ccec83c6cfce,8a650653-064d-4247-8e19-daa75b312691,0xCb7559B648eE663A2B0C569837F510D5f0ABAaD1,Main,x/w,w,2025-08-25 06:07:27.953265+00,2025-08-26 08:44:32.182774,false,0
438b3acc-7bd2-48f3-8215-de3fe598b148,0acab699-b663-44f9-b9d6-240404e6a66f,0xDEe14D5c3D93EF20c13d50CEa38126997d197ec3,华仔,TOTTkaka,null,2025-08-26 01:50:14.366868+00,null,false,0
0e55b794-016f-45c5-a619-c4a79ad20aa0,0acab699-b663-44f9-b9d6-240404e6a66f,0xa2563ca6f79ad9da13c325ea912d51aaa916b42b,Alan214,Fashion6677825,null,2025-08-26 01:50:40.494297+00,null,false,0
d381c477-0fa1-42cb-a6da-85b4ee5bfdd4,0acab699-b663-44f9-b9d6-240404e6a66f,0x491de08eedc6637f12a141a9e0122f3a71da9b98,Fish,time_outside,null,2025-08-26 01:51:02.342321+00,null,false,0
07565e41-3ba1-4023-8314-08aa1ef8513f,0acab699-b663-44f9-b9d6-240404e6a66f,0x0eE42294EA2A7dBB35468c86B624508a640ca388,方胜,F188888888K,null,2025-08-26 01:52:11.64151+00,null,false,0
120b04f6-9ac1-41ca-9bfb-54d37e4af631,0acab699-b663-44f9-b9d6-240404e6a66f,0x7e3a91e64895933597adf5d0c6aa1a23b3493127,安欣,liuanxin319,null,2025-08-26 01:53:35.377312+00,null,false,0
2b1083d4-fbb3-4af2-a37c-6d21b98e6f65,0acab699-b663-44f9-b9d6-240404e6a66f,0x61ed913c86d0534fde3e7931df971c065e846c56,Top,Topshuai888,null,2025-08-26 01:53:36.874118+00,null,false,0
d94e9a7f-56b2-4e81-b641-5fe85e203658,0acab699-b663-44f9-b9d6-240404e6a66f,0xc95c66bcb0c0f34F8C9F739A48048A82bCB92859,黄兵,村长,null,2025-08-26 01:59:47.121251+00,2025-08-26 02:00:45.082221,false,0
91ef5a8e-9013-4e0c-beaa-c54f918acacd,0acab699-b663-44f9-b9d6-240404e6a66f,0xd35001d6eb7c5ea381c110c1105329cda468e7c6,Ox,成,null,2025-08-26 01:54:07.493101+00,null,false,0
4f171967-1d6e-4a0d-8b17-d26aeb7cc515,d1c35adc-f69a-4374-9c98-e3c10a5988a2,0x6cf9669065bfc4aa92c42db302b7307d1ece671e,鹿中王,cm520uu,null,2025-08-26 01:53:45.57449+00,2025-08-26 01:54:33.538583,false,0
da28e86d-039a-40fb-867a-9ba37ea0233c,0acab699-b663-44f9-b9d6-240404e6a66f,0x05a7c0f6f60ace4b2399e12acead26483458aaf6,吴晓峰,布熊,null,2025-08-26 01:54:52.089602+00,null,false,0
fc8fc47e-f7bc-4820-b7f8-87dfcce9689b,0acab699-b663-44f9-b9d6-240404e6a66f,0xc76c97b80d55677b4fb43e0a1c38d0477ca3b7b7,qukuaixiansheng,@dxwweb3,null,2025-08-26 01:54:53.304361+00,null,false,0
4ae627c1-c11c-4c79-98d1-8279e6f66240,0acab699-b663-44f9-b9d6-240404e6a66f,0x1d8c3aea34f4836e578acc9e1a63bb14bedc68e8,陈观添,Bingo,null,2025-08-26 01:55:01.261468+00,null,false,0
7d68efb5-92b3-4df4-ba30-18c2b51aa1b9,0acab699-b663-44f9-b9d6-240404e6a66f,0x6af26db50066eda31cdd635e9263e95a76ab7bf2,Pan,sdfxs1234,null,2025-08-26 01:55:53.87867+00,null,false,0
a44277a5-c7f7-4ae8-8eae-fad405d3e738,0acab699-b663-44f9-b9d6-240404e6a66f,0x40503501eAe4cD5A44780b96332FC2139d560D5C,Hank,@meta1088,null,2025-08-26 01:56:55.170314+00,null,false,0
47f5c239-9fc8-4482-b4cc-abb3e64affd5,0acab699-b663-44f9-b9d6-240404e6a66f,0xf801f754ab8a12e5e2a668b142f7b808b79162fc,林哥,@linlucky666,null,2025-08-26 01:55:48.623866+00,2025-08-26 01:57:27.433489,false,0
a7152140-5aee-4f70-b527-fc1c9f56a202,0acab699-b663-44f9-b9d6-240404e6a66f,0x2a6249e47716a2206dCc2A039165c0eC0e4328C5,罗,Celia,null,2025-08-26 01:57:50.823086+00,null,false,0
d6d7e535-76ef-4836-87a9-5266ccea6a2b,0acab699-b663-44f9-b9d6-240404e6a66f,0xAF12493E1f996e60eC3228A8A5e8Abe9c0009138,富有,1120177465,null,2025-08-26 01:58:18.144333+00,null,false,0
a3c502ac-29db-4dcd-a554-39c987df218e,0acab699-b663-44f9-b9d6-240404e6a66f,0x01e63874DF214b8020C0CBD339e47D6D1EA367a4,Ethan Lin,13356052839,null,2025-08-26 01:59:13.767104+00,null,false,0
59624e25-4ff9-48e8-bf75-c30767aaf106,0acab699-b663-44f9-b9d6-240404e6a66f,0x458e4ca84A4464A36A4b59cd136Cf26EA457AE0D,dreams,@risnainha95,null,2025-08-26 02:14:36.673917+00,null,false,0
a52a1b2a-2ac7-46cd-83c0-3080c67f23a4,0acab699-b663-44f9-b9d6-240404e6a66f,0x889cA8A45999cc89c05c56a74f71889D80c6B326,乔,金光,null,2025-08-26 02:04:46.336508+00,null,false,0
51bbe8d3-b466-4f5d-94c4-81693ad69270,f60a993e-0001-4789-87d2-2f4ca5a267a5,0x86Bfa610831980Ad35d290888f382Ea7A9B0Ede7,阿敏,岁月如歌,null,2025-08-26 02:07:06.239806+00,2025-08-26 02:08:42.058675,false,0
2a537d24-d295-4e29-8350-809bd98b0c33,0acab699-b663-44f9-b9d6-240404e6a66f,0xe4fA44a189c7009D14E743342A4cc6d65A8a6Cc2,林,彦,null,2025-08-26 02:02:22.975013+00,null,false,0
1263b763-f0b4-4af3-adf6-3a4e149684d4,0acab699-b663-44f9-b9d6-240404e6a66f,0x343422374300AA3c75Ce1165Ac9570FB59a6288e,宣姐,zlct1314,null,2025-08-26 01:57:56.614442+00,2025-08-26 02:07:28.416526,false,0
1741aed2-a924-48f0-b3e1-02bd3df70d9f,0acab699-b663-44f9-b9d6-240404e6a66f,0x0ed1bb1df83bae3caae43901063521229c4228e2,刘承业,@yugege56789,null,2025-08-26 02:27:53.127377+00,null,false,0
5fadf137-1b0d-4f1c-8ca7-a5506f79208b,0acab699-b663-44f9-b9d6-240404e6a66f,0x232BD2eD1b1A2Ad7B83abcdf90d0994D77b8eA9C,林卓勇,卓勇,null,2025-08-26 02:14:58.944237+00,null,false,0
deb2fc83-181c-479d-8e53-3007b49ef78b,0acab699-b663-44f9-b9d6-240404e6a66f,0x69F402818019BA0c80A4Ac4D7B30C7d6f6b2B755,苏文歆,乌骨质,null,2025-08-26 02:19:09.540374+00,null,false,0
3a1fbf56-b168-490c-a66c-d26377c01fb4,0acab699-b663-44f9-b9d6-240404e6a66f,0x575ba5cd42362fc2ae6b8ec45ac0b4ed4623cb3a,新,比特大叔,null,2025-08-26 02:20:39.850503+00,null,false,0
a50305c2-1467-4674-9894-a14c342673f5,8a650653-064d-4247-8e19-daa75b312691,0x82f989684c97900a17479efbcbc80f40da5071bf,老王,likeweb3,laowang,2025-08-25 07:17:40.973049+00,2025-08-26 06:48:03.230936,false,0
7765bc78-baf6-4b6b-8350-ba9be391b338,83eb00fc-bbba-46b8-8769-eb8393adbae4,0x8AaAAE86437988636AFd12aCC958dA760D004783,JOHNNY-Z,ZQBX__168,null,2025-08-26 02:30:43.081302+00,null,false,0
90ee8cb1-1e1d-470a-95ed-8f8df27cdd1b,0acab699-b663-44f9-b9d6-240404e6a66f,0x691b73790efd9ec97d6fce80bebaea8b8c8918b5,张向锋,向枫1222,null,2025-08-26 02:31:21.238951+00,null,false,0
ce3098bd-95d1-45af-ae47-af5002d29130,d1b1842c-9edc-49ab-b83e-c9ddd0a298ba,0xa4Eb1E764073752289aB0ef3E316688a436b103a,张沛锋,A清晨,null,2025-08-26 02:33:58.942997+00,null,false,0
6dc6f85b-485d-47a7-8046-c8ce8313bc3d,0acab699-b663-44f9-b9d6-240404e6a66f,0xeed22f6cd06927698b0d73d0ae52b8f22ac74c2a,胡斌,Mr.斌,null,2025-08-26 02:35:14.546124+00,null,false,0
edcd7a50-b8cc-4a2c-8c2d-3d5080693764,d1b1842c-9edc-49ab-b83e-c9ddd0a298ba,0x986c43ca8c1a541d94c76ed2839223ce93d59e4a,武,武,null,2025-08-26 02:35:20.024978+00,null,false,0
f587780a-2325-480b-bf68-ed772d8a064d,83eb00fc-bbba-46b8-8769-eb8393adbae4,0xE1098f3Eb09a00488021d7C81334221ECFc180B4,阿飞,"fjw66044 ",null,2025-08-26 02:36:19.998609+00,null,false,0
26c7512b-4d13-4ddd-9d4c-d5fe032d9e36,3c884aee-80e2-41e5-9ff6-f33ae6d7316a,0xe8053534269ad4569eae97e5f4243fb67fb1ba33,胡太阳,taiyang982145,null,2025-08-26 02:48:45.253125+00,null,false,0
d05ce0f6-66a4-4a5f-8335-b67ebdd666ad,c44b72d2-96cb-4efe-ba97-12cbbdb872b8,0xbfdf85ce91ed08a9ca5303d9265b16fd2bb85e10,sky zeng,766453148,null,2025-08-26 01:02:29.203302+00,2025-08-26 02:49:40.275957,false,0
098cb2a3-5795-42aa-becb-9393c978513b,c44b72d2-96cb-4efe-ba97-12cbbdb872b8,0x7e9E79D34687caBBFE5992700b12998Ef890035C,小贝,QCH_0_0,null,2025-08-26 02:59:05.543093+00,null,false,0
6cc0d049-1f6a-4d59-9e02-f481a5fb89a9,a44277a5-c7f7-4ae8-8eae-fad405d3e738,0x6D3364a8cCbF8639aDCc251cD7046eB5799E7127,郑耀炫,@众赢系统~炫,null,2025-08-26 03:07:05.874824+00,null,false,0
29b0dd60-095d-4c1d-960b-9ba90d58345e,d404b068-fa92-4ce1-aac0-9f5335a0df84,0xD13d03E5891FF8a35bbca1C973954Be51EEbfcec,"Luka ",luka,null,2025-08-26 06:38:33.774315+00,null,false,0
d1579a7f-6656-4054-acfa-ef47e652e7db,3c884aee-80e2-41e5-9ff6-f33ae6d7316a,0xCc7092A6fc055dD5F2bbe547fA4001A6fEa9917A," wangsonghua",@wangsonghua03,null,2025-08-26 03:09:24.454482+00,2025-08-26 03:13:40.436816,false,0
fde45f71-df68-4e95-8f3e-223e06c2a71c,3c884aee-80e2-41e5-9ff6-f33ae6d7316a,0xCc7092A6fc055dD5F2bbe547fA4001A6fEa9917A,wangsonghua,@wangsonghua03,null,2025-08-26 03:19:00.05487+00,null,false,0
01cf26c5-68a5-4a88-a831-4b38834aacdd,83eb00fc-bbba-46b8-8769-eb8393adbae4,0x01780eD67bf0c0e528357469b39Bfb63BbC14444,王仁发,bmw8652,null,2025-08-26 03:38:07.028327+00,null,false,0
e21faef2-c337-4982-bf44-5a8cf13ebc7b,d1b1842c-9edc-49ab-b83e-c9ddd0a298ba,0x7deEffd9feFc18dF2705900fAaDf66E2DF0Fbb6B,麦明深,mgd19800818,null,2025-08-26 03:39:48.451328+00,null,false,0
ea7f798f-66fb-4bbf-81fa-8cd0d44f961d,e21faef2-c337-4982-bf44-5a8cf13ebc7b,0x3BC91C0CF9007dEE9C963c44b31Cdf0239215B45,麦小雄,wxid_7u9vglydjkpg22,null,2025-08-26 03:45:21.548983+00,null,false,0
7a1b1a6f-bfd8-46ac-9971-757a88562ced,0acab699-b663-44f9-b9d6-240404e6a66f,0x150856053C317BBc5cdceEAA1b66bC2d30eBe2Bd,louis,thunder131499,null,2025-08-26 04:09:19.955035+00,null,false,0
699cad73-f20f-4f88-91af-0cc1d31bfe93,a44277a5-c7f7-4ae8-8eae-fad405d3e738,0xd048cfad310681759e22d8ffe28c05d10ace2014,芸枫,@yf1113523096699,null,2025-08-26 04:46:01.948413+00,null,false,0
c049e442-fc04-4ced-b172-b216184e4c94,098cb2a3-5795-42aa-becb-9393c978513b,0x8166475882D7f2D213c0Fa3E752bf65874c8d7bB,陈志远,czy2369540724,null,2025-08-26 05:07:06.306961+00,null,false,0
f0d88600-418b-45df-b9ad-80c716a49514,83eb00fc-bbba-46b8-8769-eb8393adbae4,0x0E841F4902c65C9758b76131714DFC3985665cf3,麦子,@xmletoo0592,null,2025-08-26 04:20:36.107808+00,2025-08-27 16:22:08.250794,false,0
f853617e-9a89-4ace-bba1-e5cd6a38e4b2,0acab699-b663-44f9-b9d6-240404e6a66f,0x506a2cbb9dc89b809e50fabe5178495518ef65d9,Kevin,@Defizooda,null,2025-08-26 05:14:02.576028+00,null,false,0
2909db90-abb4-4bc7-a986-81b414f1ab0c,8a650653-064d-4247-8e19-daa75b312691,0x8a0a5f18d81eb044b8246b140324297e67d487cc,jiangshen,jiangshen8848,null,2025-08-26 05:32:49.292028+00,null,false,0
88526239-19d9-49ef-aa7e-1db85d164846,098cb2a3-5795-42aa-becb-9393c978513b,0xd58a2fef8093b86bd13116baa3aaff3b2b20ec6f,宋成顺,s771300,null,2025-08-26 05:34:12.562783+00,null,false,0
afebd666-ef3e-4d30-a030-3a62d5f254a8,098cb2a3-5795-42aa-becb-9393c978513b,0x7f3977341701ad47c3a711f76bbc73be0953d540,尹杰,Vison,null,2025-08-26 05:37:53.172419+00,2025-08-26 05:38:32.882066,false,0
ac9c8e0b-ba8a-4d8d-ae80-2ebb5bf75c85,098cb2a3-5795-42aa-becb-9393c978513b,0x693dba0f3ff47024eb1bb0cc283badaf95cf7d75,张吕艳,Y.,null,2025-08-26 05:38:42.435405+00,null,false,0
2adf5d53-6e3e-419b-bcb9-5bbeabf1d153,8a650653-064d-4247-8e19-daa75b312691,0xD4aeF61838BBEE10102A00f7011E834948E81e76,Cavan,Cavan,null,2025-08-26 05:41:22.194051+00,null,false,0
7fc50d32-dbb2-4e22-9ac7-8e825b36bc38,88526239-19d9-49ef-aa7e-1db85d164846,0xe92de0c3e5eddeb4c2951b4a041c01a5fb9aab94,wang,qixi20201226,null,2025-08-26 05:41:42.846343+00,null,false,0
b61ebb5b-0f76-4da1-a1c7-300fc69d2643,098cb2a3-5795-42aa-becb-9393c978513b,0xa1372d1b6e5464059ad5d4eb4f2b90055eb99c37,杨喜玲,yxl26888888,null,2025-08-26 05:47:14.319815+00,null,false,0
a92aab0f-f873-412f-9d7f-3fd10b65cac6,3c884aee-80e2-41e5-9ff6-f33ae6d7316a,0x4583b5c0c004139a762fb7f59ce8ee0b1b174742,Shoki,Koshouki,null,2025-08-26 05:50:13.283335+00,null,false,0
57c9702f-13f3-485f-a8b4-a5f26ea675b2,83eb00fc-bbba-46b8-8769-eb8393adbae4,0xbBe5BC3FeD88f40a7074108114383BAdB89A88E8,郑翔,zheng9588,null,2025-08-26 05:53:19.208054+00,2025-08-26 05:54:38.704695,false,0
ca95f28e-646c-4a79-b477-015957915929,57c9702f-13f3-485f-a8b4-a5f26ea675b2,0x7aEd7115f05C62d129dCCD3cAC1A4a587d65BB59,郑金店,zhengdian6538,null,2025-08-26 05:58:08.537227+00,null,false,0
325a9b84-5eb2-47a5-87c8-e43e47c3b0d4,098cb2a3-5795-42aa-becb-9393c978513b,0x99153e48d356fcba412d8963ff5d98f87fa101d2,杨增才,San23698,null,2025-08-26 06:00:05.442928+00,null,false,0
8d2b9baf-747e-4d91-8087-73878d71e404,8a650653-064d-4247-8e19-daa75b312691,0x8776b606910D9b4C14143caFB60Db69c0800d650,A GE,MAX,null,2025-08-26 06:10:06.103426+00,2025-08-26 06:10:53.71166,false,0
0cb5d251-9b92-4e4f-a77d-48e9be203c49,8a650653-064d-4247-8e19-daa75b312691,0x4858091cda927d1Aa2f82Bdb1Fd76c64A66d575b,者也,者也,null,2025-08-26 06:11:04.872237+00,null,false,0
c0db3d40-ecc3-414b-a840-b938e871d502,8a650653-064d-4247-8e19-daa75b312691,0x3Fa5CA05336B714367CC38D879Dc9eA203E09167,神之一手,husun2hao,null,2025-08-26 06:12:03.44112+00,null,false,0
721a551d-08ea-43e8-a497-1b8e2d70f418,0acab699-b663-44f9-b9d6-240404e6a66f,0x211ef244e60e1adf835518f5408ae00eb429f645,xiaomingli,hubuj85866569,null,2025-08-26 06:26:23.516729+00,null,false,0
b280b361-6822-499b-a8cc-84454049ea3a,8a650653-064d-4247-8e19-daa75b312691,0x85b60D1781F19f57C1fe0A677c4a5F2F46B17d8d,晴晴,晴晴,null,2025-08-26 06:23:23.423166+00,2025-08-26 06:26:27.48237,false,0
164767ce-3425-4dae-8183-0aa136c7e2e3,8a650653-064d-4247-8e19-daa75b312691,0x8c681F7220484c6dA76B3D784305AB4A3a8b354E,天哥,1642254867,null,2025-08-26 06:26:15.442602+00,2025-08-26 06:26:27.575499,false,0
a57f3867-8e6d-477a-80e8-ce5b4eff6ace,8a650653-064d-4247-8e19-daa75b312691,0x8c681F7220484c6dA76B3D784305AB4A3a8b354E,天哥说财经,1642254867,null,2025-08-26 06:28:41.67044+00,null,false,0
d404b068-fa92-4ce1-aac0-9f5335a0df84,0cb5d251-9b92-4e4f-a77d-48e9be203c49,0x51487407E83E162187Ae2015e8cDEF823e8034cd,墨兵,@mobing99,null,2025-08-26 06:31:21.462671+00,null,false,0
62d7032a-219e-46bc-b8d2-1e5de36802b1,8a650653-064d-4247-8e19-daa75b312691,0xF0c5d5A4C9c576212abcf259C3369C52A711Ce23,旺旺,旺,null,2025-08-26 06:31:45.770024+00,2025-08-26 06:34:48.978343,false,0
97f44a01-1cc7-4cd7-8307-a75cb55f178e,8a650653-064d-4247-8e19-daa75b312691,0x57dd42DE2a431DC7b0863393bdD104168d876d94,船长,@tu_capta,null,2025-08-26 06:37:05.616484+00,2025-08-26 06:42:50.773094,false,0
1c3c0371-cd7c-4537-99f6-059e11257ca4,97f44a01-1cc7-4cd7-8307-a75cb55f178e,0x02c62f53c26bce25d940b11284640a79e27b1208,Leo,Rox5995,null,2025-08-26 06:50:58.670289+00,null,false,0
\ No newline at end of file
main
\ No newline at end of file
v2.39.2
\ No newline at end of file
# For detailed configuration reference documentation, visit:
# https://supabase.com/docs/guides/local-development/cli/config
# A string used to distinguish different Supabase projects on the same host. Defaults to the
# working directory name when running `supabase init`.
project_id = "checkin"
[api]
enabled = true
# Port to use for the API URL.
port = 54321
# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API
# endpoints. `public` and `graphql_public` schemas are included by default.
schemas = ["public", "graphql_public"]
# Extra schemas to add to the search_path of every request.
extra_search_path = ["public", "extensions"]
# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size
# for accidental or malicious requests.
max_rows = 1000
[api.tls]
# Enable HTTPS endpoints locally using a self-signed certificate.
enabled = false
[db]
# Port to use for the local database URL.
port = 54322
# Port used by db diff command to initialize the shadow database.
shadow_port = 54320
# The database major version to use. This has to be the same as your remote database's. Run `SHOW
# server_version;` on the remote database to check.
major_version = 17
[db.pooler]
enabled = false
# Port to use for the local connection pooler.
port = 54329
# Specifies when a server connection can be reused by other clients.
# Configure one of the supported pooler modes: `transaction`, `session`.
pool_mode = "transaction"
# How many server connections to allow per user/database pair.
default_pool_size = 20
# Maximum number of client connections allowed.
max_client_conn = 100
# [db.vault]
# secret_key = "env(SECRET_VALUE)"
[db.migrations]
# If disabled, migrations will be skipped during a db push or reset.
enabled = true
# Specifies an ordered list of schema files that describe your database.
# Supports glob patterns relative to supabase directory: "./schemas/*.sql"
schema_paths = []
[db.seed]
# If enabled, seeds the database after migrations during a db reset.
enabled = true
# Specifies an ordered list of seed files to load during db reset.
# Supports glob patterns relative to supabase directory: "./seeds/*.sql"
sql_paths = ["./seed.sql"]
[db.network_restrictions]
# Enable management of network restrictions.
enabled = false
# List of IPv4 CIDR blocks allowed to connect to the database.
# Defaults to allow all IPv4 connections. Set empty array to block all IPs.
allowed_cidrs = ["0.0.0.0/0"]
# List of IPv6 CIDR blocks allowed to connect to the database.
# Defaults to allow all IPv6 connections. Set empty array to block all IPs.
allowed_cidrs_v6 = ["::/0"]
[realtime]
enabled = true
# Bind realtime via either IPv4 or IPv6. (default: IPv4)
# ip_version = "IPv6"
# The maximum length in bytes of HTTP request headers. (default: 4096)
# max_header_length = 4096
[studio]
enabled = true
# Port to use for Supabase Studio.
port = 54323
# External URL of the API server that frontend connects to.
api_url = "http://127.0.0.1"
# OpenAI API Key to use for Supabase AI in the Supabase Studio.
openai_api_key = "env(OPENAI_API_KEY)"
# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they
# are monitored, and you can view the emails that would have been sent from the web interface.
[inbucket]
enabled = true
# Port to use for the email testing server web interface.
port = 54324
# Uncomment to expose additional ports for testing user applications that send emails.
# smtp_port = 54325
# pop3_port = 54326
# admin_email = "admin@email.com"
# sender_name = "Admin"
[storage]
enabled = true
# The maximum file size allowed (e.g. "5MB", "500KB").
file_size_limit = "50MiB"
# Image transformation API is available to Supabase Pro plan.
# [storage.image_transformation]
# enabled = true
# Uncomment to configure local storage buckets
# [storage.buckets.images]
# public = false
# file_size_limit = "50MiB"
# allowed_mime_types = ["image/png", "image/jpeg"]
# objects_path = "./images"
[auth]
enabled = true
# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
# in emails.
site_url = "http://127.0.0.1:3000"
# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
additional_redirect_urls = ["https://127.0.0.1:3000"]
# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
jwt_expiry = 3600
# Path to JWT signing key. DO NOT commit your signing keys file to git.
# signing_keys_path = "./signing_keys.json"
# If disabled, the refresh token will never expire.
enable_refresh_token_rotation = true
# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.
# Requires enable_refresh_token_rotation = true.
refresh_token_reuse_interval = 10
# Allow/disallow new user signups to your project.
enable_signup = true
# Allow/disallow anonymous sign-ins to your project.
enable_anonymous_sign_ins = false
# Allow/disallow testing manual linking of accounts
enable_manual_linking = false
# Passwords shorter than this value will be rejected as weak. Minimum 6, recommended 8 or more.
minimum_password_length = 6
# Passwords that do not meet the following requirements will be rejected as weak. Supported values
# are: `letters_digits`, `lower_upper_letters_digits`, `lower_upper_letters_digits_symbols`
password_requirements = ""
[auth.rate_limit]
# Number of emails that can be sent per hour. Requires auth.email.smtp to be enabled.
email_sent = 2
# Number of SMS messages that can be sent per hour. Requires auth.sms to be enabled.
sms_sent = 30
# Number of anonymous sign-ins that can be made per hour per IP address. Requires enable_anonymous_sign_ins = true.
anonymous_users = 30
# Number of sessions that can be refreshed in a 5 minute interval per IP address.
token_refresh = 150
# Number of sign up and sign-in requests that can be made in a 5 minute interval per IP address (excludes anonymous users).
sign_in_sign_ups = 30
# Number of OTP / Magic link verifications that can be made in a 5 minute interval per IP address.
token_verifications = 30
# Number of Web3 logins that can be made in a 5 minute interval per IP address.
web3 = 30
# Configure one of the supported captcha providers: `hcaptcha`, `turnstile`.
# [auth.captcha]
# enabled = true
# provider = "hcaptcha"
# secret = ""
[auth.email]
# Allow/disallow new user signups via email to your project.
enable_signup = true
# If enabled, a user will be required to confirm any email change on both the old, and new email
# addresses. If disabled, only the new email is required to confirm.
double_confirm_changes = true
# If enabled, users need to confirm their email address before signing in.
enable_confirmations = false
# If enabled, users will need to reauthenticate or have logged in recently to change their password.
secure_password_change = false
# Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email.
max_frequency = "1s"
# Number of characters used in the email OTP.
otp_length = 6
# Number of seconds before the email OTP expires (defaults to 1 hour).
otp_expiry = 3600
# Use a production-ready SMTP server
# [auth.email.smtp]
# enabled = true
# host = "smtp.sendgrid.net"
# port = 587
# user = "apikey"
# pass = "env(SENDGRID_API_KEY)"
# admin_email = "admin@email.com"
# sender_name = "Admin"
# Uncomment to customize email template
# [auth.email.template.invite]
# subject = "You have been invited"
# content_path = "./supabase/templates/invite.html"
[auth.sms]
# Allow/disallow new user signups via SMS to your project.
enable_signup = false
# If enabled, users need to confirm their phone number before signing in.
enable_confirmations = false
# Template for sending OTP to users
template = "Your code is {{ .Code }}"
# Controls the minimum amount of time that must pass before sending another sms otp.
max_frequency = "5s"
# Use pre-defined map of phone number to OTP for testing.
# [auth.sms.test_otp]
# 4152127777 = "123456"
# Configure logged in session timeouts.
# [auth.sessions]
# Force log out after the specified duration.
# timebox = "24h"
# Force log out if the user has been inactive longer than the specified duration.
# inactivity_timeout = "8h"
# This hook runs before a new user is created and allows developers to reject the request based on the incoming user object.
# [auth.hook.before_user_created]
# enabled = true
# uri = "pg-functions://postgres/auth/before-user-created-hook"
# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used.
# [auth.hook.custom_access_token]
# enabled = true
# uri = "pg-functions://<database>/<schema>/<hook_name>"
# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`.
[auth.sms.twilio]
enabled = false
account_sid = ""
message_service_sid = ""
# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead:
auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)"
# Multi-factor-authentication is available to Supabase Pro plan.
[auth.mfa]
# Control how many MFA factors can be enrolled at once per user.
max_enrolled_factors = 10
# Control MFA via App Authenticator (TOTP)
[auth.mfa.totp]
enroll_enabled = false
verify_enabled = false
# Configure MFA via Phone Messaging
[auth.mfa.phone]
enroll_enabled = false
verify_enabled = false
otp_length = 6
template = "Your code is {{ .Code }}"
max_frequency = "5s"
# Configure MFA via WebAuthn
# [auth.mfa.web_authn]
# enroll_enabled = true
# verify_enabled = true
# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,
# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`,
# `twitter`, `slack`, `spotify`, `workos`, `zoom`.
[auth.external.apple]
enabled = false
client_id = ""
# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:
secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)"
# Overrides the default auth redirectUrl.
redirect_uri = ""
# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,
# or any other third-party OIDC providers.
url = ""
# If enabled, the nonce check will be skipped. Required for local sign in with Google auth.
skip_nonce_check = false
# Allow Solana wallet holders to sign in to your project via the Sign in with Solana (SIWS, EIP-4361) standard.
# You can configure "web3" rate limit in the [auth.rate_limit] section and set up [auth.captcha] if self-hosting.
[auth.web3.solana]
enabled = false
# Use Firebase Auth as a third-party provider alongside Supabase Auth.
[auth.third_party.firebase]
enabled = false
# project_id = "my-firebase-project"
# Use Auth0 as a third-party provider alongside Supabase Auth.
[auth.third_party.auth0]
enabled = false
# tenant = "my-auth0-tenant"
# tenant_region = "us"
# Use AWS Cognito (Amplify) as a third-party provider alongside Supabase Auth.
[auth.third_party.aws_cognito]
enabled = false
# user_pool_id = "my-user-pool-id"
# user_pool_region = "us-east-1"
# Use Clerk as a third-party provider alongside Supabase Auth.
[auth.third_party.clerk]
enabled = false
# Obtain from https://clerk.com/setup/supabase
# domain = "example.clerk.accounts.dev"
[edge_runtime]
enabled = true
# Supported request policies: `oneshot`, `per_worker`.
# `per_worker` (default) — enables hot reload during local development.
# `oneshot` — fallback mode if hot reload causes issues (e.g. in large repos or with symlinks).
policy = "per_worker"
# Port to attach the Chrome inspector for debugging edge functions.
inspector_port = 8083
# The Deno major version to use.
deno_version = 2
# [edge_runtime.secrets]
# secret_key = "env(SECRET_VALUE)"
[analytics]
enabled = true
port = 54327
# Configure one of the supported backends: `postgres`, `bigquery`.
backend = "postgres"
# Experimental features may be deprecated any time
[experimental]
# Configures Postgres storage engine to use OrioleDB (S3)
orioledb_version = ""
# Configures S3 bucket URL, eg. <bucket_name>.s3-<region>.amazonaws.com
s3_host = "env(S3_HOST)"
# Configures S3 bucket region, eg. us-east-1
s3_region = "env(S3_REGION)"
# Configures AWS_ACCESS_KEY_ID for S3 bucket
s3_access_key = "env(S3_ACCESS_KEY)"
# Configures AWS_SECRET_ACCESS_KEY for S3 bucket
s3_secret_key = "env(S3_SECRET_KEY)"
[functions.sign]
enabled = true
verify_jwt = true
import_map = "./functions/sign/deno.json"
# Uncomment to specify a custom file path to the entrypoint.
# Supported file extensions are: .ts, .js, .mjs, .jsx, .tsx
entrypoint = "./functions/sign/index.ts"
# Specifies static files to be bundled with the function. Supports glob patterns.
# For example, if you want to serve static HTML pages in your function:
# static_files = [ "./functions/sign/*.html" ]
[functions.sign_time_range]
enabled = true
verify_jwt = true
import_map = "./functions/sign_time_range/deno.json"
# Uncomment to specify a custom file path to the entrypoint.
# Supported file extensions are: .ts, .js, .mjs, .jsx, .tsx
entrypoint = "./functions/sign_time_range/index.ts"
# Specifies static files to be bundled with the function. Supports glob patterns.
# For example, if you want to serve static HTML pages in your function:
# static_files = [ "./functions/sign_time_range/*.html" ]
# Configuration for private npm package dependencies
# For more information on using private registries with Edge Functions, see:
# https://supabase.com/docs/guides/functions/import-maps#importing-from-private-registries
// supabase/functions/sign/index.ts
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import { createClient } from 'jsr:@supabase/supabase-js@2';
console.log("Sign function started")
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type'
};
// Haversine公式计算距离
function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
const R = 6371 // 地球半径(千米)
const dLat = (lat2 - lat1) * Math.PI / 180
const dLon = (lon2 - lon1) * Math.PI / 180
const a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2)
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
return R * c
}
Deno.serve(async (req) => {
if (req.method === 'OPTIONS') {
return new Response('ok', {
headers: corsHeaders
});
}
try {
// 验证参数有效性
const { user_id, qr_code, latitude, longitude } = await req.json()
if (!user_id || !qr_code || typeof latitude !== 'number' || typeof longitude !== 'number') {
console.error('invalid parameters')
return new Response(JSON.stringify({
error: 'Invalid parameters'
}), {
status: 400,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// 获取用户认证信息
const authHeader = req.headers.get('Authorization');
if (!authHeader) {
console.error('no auth header')
return new Response(JSON.stringify({
error: 'No Authorization'
}), {
status: 401,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// 创建Supabase客户端
const supabaseClient = createClient(Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_ANON_KEY') ?? '', {
global: {
headers: {
Authorization: authHeader
}
}
});
// 获取当前用户
const { data: { user }, error: userError } = await supabaseClient.auth.getUser();
if (userError || !user) {
console.error('Auth error:', userError)
return new Response(JSON.stringify({
error: 'Auth Fail',
details: userError?.message
}), {
status: 401,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
console.info(`Sign request from user ${user.id}: QR=${qr_code}, Lat=${latitude}, Lon=${longitude}`)
if (user.id !== user_id) {
console.error(`User ID mismatch: ${user.id} !== ${user_id}`)
return new Response(JSON.stringify({
error: 'User ID mismatch'
}), {
status: 403,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// console.log(`Sign request from user ${user_id}: QR=${qr_code}, Lat=${latitude}, Lon=${longitude}`)
// 获取签到配置
const { data: config, error: configError } = await supabaseClient
.from('sign_config')
.select('*')
.order('created_at', { ascending: false })
.limit(1)
.single()
if (configError || !config) {
console.error('get sign config error:', configError)
return new Response(JSON.stringify({
success: false,
message: 'not found config'
}), {
status: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// 验证时间范围
const now = new Date()
const beijingTime = new Date(now.getTime() + (8 * 60 * 60 * 1000))
const startTime = new Date(config.start_time)
const endTime = new Date(config.end_time)
console.info(`Current Beijing time: ${beijingTime.toISOString()}, Sign time range: ${startTime.toISOString()} - ${endTime.toISOString()}`)
if (beijingTime < startTime || beijingTime > endTime) {
console.error('Not in sign time range')
return new Response(JSON.stringify({
success: false,
message: 'not in sign time range'
}), {
status: 400,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// 从 invitation 表中 获取用户签到状态.
const { data: userInfo, error: getError } = await supabaseClient
.from('invitation')
.select('*')
.eq('user_id', user_id)
.limit(1)
.single()
if (getError) {
console.error('Get sign status error:', getError)
return new Response(JSON.stringify({
success: false,
message: 'User sign status fetch failed'
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// console.log(`Fetched user info: ${JSON.stringify(userInfo)}`)
if (userInfo.is_signed) {
console.error('User has already signed in', user.id)
return new Response(JSON.stringify({
success: true,
message: 'You have already signed in'
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// 验证二维码
if (qr_code !== config.qr_code_secret) {
console.error(`QR code mismatch: ${qr_code} !== ${config.qr_code_secret}`)
return new Response(JSON.stringify({
success: false,
message: 'Invalid QR code'
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// 验证定位距离
const distance = calculateDistance(
config.venue_latitude,
config.venue_longitude,
latitude,
longitude
)
if (distance > config.radius_km) {
console.error(`User ${user_id} is too far: ${distance.toFixed(2)} km away, limit is ${config.radius_km} km`)
return new Response(JSON.stringify({
success: false,
message: `You are ${distance.toFixed(2)} kilometers away from the venue, exceeding the ${config.radius_km}-kilometer range.`
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// Fetch the count of invitations where inviter_id matches the user's ID
const { count: count, error: countError } = await supabaseClient
.from('invitation')
.select('user_id', {count:'exact'})
.eq('inviter_id', user_id);
const invitedCount = count || 0;
if (countError) {
console.error('Error fetching invitation count:', countError);
return new Response(JSON.stringify({
success: false,
message: 'Failed to fetch invitation count'
}), {
status: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
});
}
console.info(`Invitation count for user ${user_id}: ${invitedCount}`);
// 验证邀请人数
if ((invitedCount || 0) <= 1) {
console.error(`Not enough invitations: ${invitedCount} (minimum 2 required)`)
return new Response(JSON.stringify({
success: false,
message: 'Minimum 2 invitations required to sign in'
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// 计算奖励金额
let rewardAmount = config.reward_base_amount * invitedCount
if (rewardAmount > config.reward_max_amount) {
rewardAmount = config.reward_max_amount
}
// 更新用户签到状态
const { error: updateError } = await supabaseClient
.from('invitation')
.update({
is_signed: true,
reward: rewardAmount
})
.eq('user_id', user_id)
if (updateError) {
console.error('Update error:', updateError)
return new Response(JSON.stringify({
success: false,
message: 'Sign in failed, please try again'
}), {
status: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// 记录签到日志
await supabaseClient
.from('sign_logs')
.insert({
user_id: user_id,
qr_code: qr_code,
user_latitude: latitude,
user_longitude: longitude,
distance_km: distance,
is_successful: true,
error_reason: null
})
console.info(`Sign successful for user ${user_id}, reward: ${rewardAmount}`)
return new Response(JSON.stringify({
success: true,
message: 'sign success',
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
} catch (error) {
console.error('Function error:', error)
return new Response(JSON.stringify({
success: false,
message: 'Internal error'
}), {
status: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
})
\ No newline at end of file
# Configuration for private npm package dependencies
# For more information on using private registries with Edge Functions, see:
# https://supabase.com/docs/guides/functions/import-maps#importing-from-private-registries
// supabase/functions/sign/index.ts
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import { createClient } from 'jsr:@supabase/supabase-js@2';
console.log("Sign function started")
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type'
};
Deno.serve(async (req) => {
if (req.method === 'OPTIONS') {
return new Response('ok', {
headers: corsHeaders
});
}
try {
// 创建Supabase客户端
// const supabaseClient = createClient(Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_ANON_KEY') ?? '', {
// });
const authHeader = req.headers.get('Authorization');
if (!authHeader) {
return new Response(JSON.stringify({
error: 'No Authorization'
}), {
status: 401,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
console.log('auth header found')
// 创建Supabase客户端
const supabaseClient = createClient(Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_ANON_KEY') ?? '', {
global: {
headers: {
Authorization: authHeader
}
}
});
// 获取签到配置
const { data: config, error: configError } = await supabaseClient
.from('sign_config')
.select('*')
.order('created_at', { ascending: false })
.limit(1)
.single()
if (configError || !config) {
console.error('Config error:', configError)
return new Response(JSON.stringify({
success: false,
message: 'not found sign config'
}), {
status: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
return new Response(JSON.stringify({
starttime: config.start_time,
endtime: config.end_time,
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
} catch (error) {
console.error('Function error:', error)
return new Response(JSON.stringify({
success: false,
message: 'Internal error'
}), {
status: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
})
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment