Initial commit of akmon project

This commit is contained in:
2026-01-20 08:04:15 +08:00
commit 77a2bab985
1309 changed files with 343305 additions and 0 deletions

View File

@@ -0,0 +1,212 @@
<template>
<view class="test-container">
<text class="title">Supabase Realtime 测试</text>
<view class="section">
<text>WS地址></text>
<input v-model="wsUrl" placeholder="ws(s)://..." />
</view>
<view class="section">
<text>频道></text>
<input v-model="channel" placeholder="realtime:public:ak_info" />
</view>
<view class="section">
<text>Token></text>
<input v-model="token" placeholder="可选JWT" />
</view>
<view class="section">
<button @click="connect">连接</button>
<button @click="close">断开</button>
</view>
<view class="section">
<button @click="testSignIn">signIn</button>
</view>
<view class="section">
<button @click="subscribeInsert">订阅INSERT</button>
</view>
<view class="section">
<button @click="sendTestMessage">手动发送消息</button>
</view>
<view class="section">
<text>消息></text>
<scroll-view style="height: 300rpx; border: 1px solid #ccc; padding: 8rpx;" scroll-y>
<view v-for="(msg, idx) in messages" :key="idx" style="font-size: 24rpx; color: #333; margin-bottom: 8rpx;">
{{ msg }}
</view>
</scroll-view>
</view>
</view>
</template>
<script lang="uts">
import supa from '@/components/supadb/aksupainstance.uts';
import { AkSupaRealtime } from '@/components/supadb/aksuparealtime.uts';
import { AkReq } from '@/uni_modules/ak-req/ak-req.uts';
import { SUPA_URL, SUPA_KEY ,WS_URL } from '@/ak/config.uts';
export default {
data() {
return {
email: 'akoo@163.com',
password: 'Hf2152111',
wsUrl: WS_URL,
channel: 'realtime:public:ps_push_msg_raw',
token: '',
messages: [] as string[],
realtime: null as AkSupaRealtime | null
};
},
methods: {
async testSignIn() {
try {
const res = await supa.signIn(this.email, this.password);
} catch (e) {
console.log(e)
}
},
connect() {
// 先安全关闭 realtime 实例
const oldRealtime = this.realtime;
if (oldRealtime != null) {
oldRealtime.close({}); // 传递空对象,兼容 UTS 类型
this.realtime = null;
}
let token = AkReq.getToken();
console.log(token);
if (token == null || token === "") {
this.messages.push('未检测到 access_token请先登录');
return;
}
// wsUrl/channel 直接 String(this.wsUrl) 兼容 UTS
const wsUrl: string = this.wsUrl as string;
const channel: string = this.channel!!;
const self = this;
const newRealtime = new AkSupaRealtime({
url: wsUrl,
channel: channel,
token: token,
apikey: SUPA_KEY, // 如需 apikey 可补充
onOpen(res) {
console.log(res)
self.messages.push('WebSocket 已连接');
},
onClose(res) {
console.log(res)
self.messages.push('WebSocket 已断开');
},
onError(err) {
self.messages.push('WebSocket 错误: ' + JSON.stringify(err));
},
onMessage(data) {
self.messages.push('收到消息: ' + JSON.stringify(data));
}
});
this.realtime = newRealtime;
newRealtime.connect();
this.messages.push('正在连接...');
},
close() {
const oldRealtime = this.realtime;
if (oldRealtime != null) {
oldRealtime.close({}); // 传递空对象,兼容 UTS 类型
this.realtime = null;
this.messages.push('手动断开连接');
}
},
subscribeInsert() {
// 先安全关闭旧实例
const oldRealtime = this.realtime;
if (oldRealtime != null) {
oldRealtime.close({});
this.realtime = null;
}
let token = AkReq.getToken();
if (!token) {
this.messages.push('未检测到 access_token请先登录');
return;
}
const wsUrl: string = this.wsUrl as string;
// 频道名可自定义为 'elder',事件类型和表名按需传递
const newRealtime = new AkSupaRealtime({
url: wsUrl,
channel: 'elder',
token: token,
apikey: SUPA_KEY,
onOpen: () => {
this.messages.push('订阅已连接');
// 订阅 Postgres INSERT 事件
newRealtime.subscribePostgresChanges({
event: 'INSERT',
schema: 'public',
table: 'ps_push_msg_raw',
onChange: (payload) => {
this.messages.push('Change received! ' + JSON.stringify(payload));
console.log('Change received!', payload);
}
});
},
onClose: () => {
this.messages.push('订阅已断开');
},
onError: (err) => {
this.messages.push('订阅错误: ' + JSON.stringify(err));
},
onMessage: (data) => {
console.log(data)
// 可选:收到其它消息
}
});
this.realtime = newRealtime;
newRealtime.connect();
this.messages.push('正在订阅 INSERT...');
},
sendTestMessage() {
if (!this.realtime || !this.realtime.isOpen) {
this.messages.push('WebSocket 未连接,无法发送');
return;
}
const testMsg = {
event: 'phx_test',
payload: { msg: 'Hello from client', time: Date.now() },
ref: Date.now().toString(),
topic: this.channel
};
this.realtime.send({
data: testMsg,
success: (res) => {
this.messages.push('消息发送成功: ' + JSON.stringify(res));
},
fail: (err) => {
this.messages.push('消息发送失败: ' + JSON.stringify(err));
}
});
},
}
};
</script>
<style>
.test-container {
padding: 32rpx;
}
.title {
font-size: 36rpx;
font-weight: bold;
margin-bottom: 32rpx;
}
.section {
margin-bottom: 24rpx;
}
input {
border: 1px solid #ccc;
border-radius: 8rpx;
padding: 8rpx 16rpx;
margin-left: 12rpx;
}
button {
margin-right: 16rpx;
}
</style>