提交 ee2ed195 编写于 作者: yu's avatar yu

sync with uni market

上级 9dfdd183
uni_modules
hbuilderx
node_modules
\ No newline at end of file
<script> <script>
import { ddp } from "./modules/core/ddp"; import {
console.log(ddp) ddp
ddp.subscribe("rooms.all") } from "./modules/core/ddp";
ddp.subscribe("rooms.mine") export default {
export default { onLaunch: function() {
onLaunch: function () { console.log("App Launch");
console.log("App Launch"); // #ifdef H5
}, uni.reLaunch({
onShow: function () { url: "/modules/user/signin/signin"
console.log("App Show"); })
}, // #endif
onHide: function () { },
console.log("App Hide"); onShow: function() {
}, console.log("App Show");
}; },
onHide: function() {
console.log("App Hide");
},
};
</script> </script>
<style> <style>
/*每个页面公共css */ /*每个页面公共css */
page { page {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
/* /*
min-height: 100%; */ min-height: 100%; */
background-color: #eeeeff; background-color: #eeeeff;
min-height: 100%; min-height: 100%;
} }
page-body {
background-color: red; page-body {
} background-color: red;
view{ }
box-sizing: border-box;
} view {
.frow, box-sizing: border-box;
.fcol { }
display: flex;
} .frow,
.fcol {
.frow { display: flex;
flex-direction: row; }
}
.frow {
.fcol { flex-direction: row;
flex-direction: column; }
}
.fcol {
.fcnt, flex-direction: column;
.cntx { }
justify-content: center;
} .fcnt,
.cntx {
.fcnt, justify-content: center;
.cnty { }
align-items: center;
} .fcnt,
.cnty {
.fbtw { align-items: center;
justify-content: space-between; }
}
.fbtw {
.fsc { justify-content: space-between;
align-self: center; }
}
.fsc {
.fse { align-self: center;
align-self: flex-end; }
}
.fse {
.fss { align-self: flex-end;
align-self: flex-start; }
}
.fss {
.pd { align-self: flex-start;
padding: 0.5rem; }
}
.pd {
.pdh { padding: 0.5rem;
padding: 0.5rem 0; }
}
.f1 { .pdh {
flex: 1; padding: 0.5rem 0;
} }
.pdv {
padding: 0 0.5rem; .f1 {
} flex: 1;
}
.mg {
margin: 0.5rem; .pdv {
} padding: 0 0.5rem;
}
.mgh {
margin: 0 0.5rem; .mg {
} margin: 0.5rem;
}
.mgv {
margin: 0.5rem 0; .mgh {
} margin: 0 0.5rem;
}
.mgt {
margin-top: 0.5rem; .mgv {
} margin: 0.5rem 0;
}
.mgb {
margin-bottom: 0.5rem; .mgt {
} margin-top: 0.5rem;
}
.mgb {
margin-bottom: 0.5rem;
}
</style> </style>
...@@ -4,87 +4,87 @@ import { publishComposite } from "meteor/reywood:publish-composite"; ...@@ -4,87 +4,87 @@ import { publishComposite } from "meteor/reywood:publish-composite";
Meteor.startup(() => { Meteor.startup(() => {
console.log(`Hi boot! -- ddp demo -- oh yeah -`); console.log(`Hi boot! -- ddp demo -- oh yeah -`);
}); });
const Users = Meteor.users; const Users = Meteor.users;
const Rooms = new Mongo.Collection<any>("rooms"); const Rooms = new Mongo.Collection<any>("rooms");
const Messages = new Mongo.Collection<any>("messages"); const Messages = new Mongo.Collection<any>("messages");
Messages.allow({
insert(user, doc) {
if (!user) throw new Meteor.Error("仅有登录用户能那啥");
if (!doc.roomId) throw new Meteor.Error("需要提供roomId");
doc.createdBy = user;
doc.createdAt = Date.now()
}
})
Meteor.methods({ Meteor.methods({
"message.add": function (data: any) { "room.create": function(name: string) {
if (!this.userId || !data.roomId) if (!this.userId) throw new Meteor.Error("仅有登录用户能那啥");
throw new Meteor.Error("仅有登录用户能那啥"); return Rooms.insert({
return Messages.insert({ name,
...data, createdBy: this.userId,
user: this.userId, createdAt: Date.now(),
}); members: [this.userId],
}, });
"room.create": function (name: string) { },
if (!this.userId) throw new Meteor.Error("仅有登录用户能那啥"); "room.join": function(id: string) {
return Rooms.insert({ if (!this.userId) throw new Meteor.Error("仅有登录用户能那啥");
name, const room = Rooms.findOne(id);
createdBy: this.userId, if (!room) throw new Meteor.Error("没房间不能那啥");
createdAt: Date.now(), return Rooms.update(id, {
members: [this.userId], $addToSet: {
}); members: this.userId,
}, },
"room.join": function (id: string) { });
if (!this.userId) throw new Meteor.Error("仅有登录用户能那啥"); },
const room = Rooms.findOne(id); "room.left": function(id: string) {
if (!room) throw new Meteor.Error("没房间不能那啥"); if (!this.userId) throw new Meteor.Error("仅有登录用户能那啥");
return Rooms.update(id, { const room = Rooms.findOne(id);
$addToSet: { if (!room) throw new Meteor.Error("没房间不能那啥");
members: this.userId, return Rooms.update(id, {
}, $pull: {
}); members: this.userId,
}, },
"room.left": function (id: string) { });
if (!this.userId) throw new Meteor.Error("仅有登录用户能那啥"); }
const room = Rooms.findOne(id);
if (!room) throw new Meteor.Error("没房间不能那啥");
return Rooms.update(id, {
$pull: {
members: this.userId,
},
});
}
}); });
Meteor.publish("rooms.all", function () { Meteor.publish("rooms.all", function() {
return Rooms.find({}, { fields: { name: 1, _id: 1 } }); return Rooms.find({}, { fields: { name: 1, _id: 1 } });
}); });
publishComposite("rooms.mine", function () { publishComposite("rooms.mine", function() {
const userId = this.userId; const userId = this.userId;
return { console.log(userId + "mine")
find() { return {
return Rooms.find( find() {
{ members: userId }, return Rooms.find(
{ fields: { name: 1, members: 1 } } { members: userId },
); { fields: { name: 1, members: 1, createdBy: 1 } }
}, );
collectionName: `rooms-mine`, },
children: [ children: [
{ {
find(room) { find(room) {
return Users.find( return Users.find(
{ id: { $in: room.membsers } }, { id: { $in: room.membsers } },
{ fields: { profile: 1 } } { fields: { profile: 1 } }
); );
}, },
}, },
{ {
find(room) { find(room) {
return Messages.find({ roomId: room._id }); return Messages.find({ roomId: room._id });
}, },
}, },
], ],
}; };
}); });
Meteor.onConnection((con) => { Meteor.onConnection((con) => {
console.log(`${con.id} connected`); console.log(`${con.id} connected`);
con.onClose(() => { con.onClose(() => {
console.log(`${con.id} closed`); console.log(`${con.id} closed`);
}); });
}); });
import { import {
useMongo,
ddp ddp
} from "../../core/ddp.js" } from "../../core/ddp.js"
import {
mineInfo
} from "../../user/service/index.js"
import { import {
reactive, reactive,
computed computed,
watchEffect
} from "vue" } from "vue"
export const myRooms = reactive([]) ddp.subscribe("rooms.all")
const allRooms = reactive([]) ddp.subscribe("rooms.mine")
console.log(ddp) const db = useMongo(mineInfo._id, ddp)
const MyRooms = ddp.db.collection('rooms-mine') const AllRooms = db.collection('rooms')
const AllRooms = ddp.db.collection('rooms') const Messages = db.collection('messages')
const Messages = ddp.db.collection('messages')
let currentRoom = null; let currentRoom = null;
ddp.map(MyRooms, myRooms) console.log(mineInfo._id)
ddp.map(AllRooms, allRooms) export const myRooms = AllRooms.liveQuery({
createdBy: mineInfo._id
})
export const roomMessages = reactive([]) export const roomMessages = reactive([])
export const otherRooms = computed(() => allRooms.filter(v => !myRooms.some(e => e._id === v._id))) export const otherRooms = AllRooms.liveQuery({
export const sendMessage = txt => new Promise(resolve => { createdBy: {
if (!currentRoom || !txt) return resolve(false) $ne: mineInfo._id
}
})
watchEffect(() => {
console.log(myRooms)
console.log(otherRooms)
})
export const sendMessage = async txt => {
if (!currentRoom || !txt) return
const data = { const data = {
roomId: currentRoom, roomId: currentRoom,
txt, txt,
_id: Date.now() _id: mineInfo._id + "-" + Date.now()
} }
ddp.call('message.add', { const res = await Messages.insert({
...data, ...data
_id: undefined }, {
}, (err, res) => { remote: 1
resolve(!err)
}) })
}) console.log(res)
}
export const createRoom = name => new Promise(resolve => { export const createRoom = name => new Promise(resolve => {
{ {
ddp.call('room.create', name, (err, res) => { ddp.call('room.create', name, (err, res) => {
...@@ -69,11 +82,9 @@ Messages.observe({ ...@@ -69,11 +82,9 @@ Messages.observe({
index > -1 && roomMessages.splice(i, 1, nv) index > -1 && roomMessages.splice(i, 1, nv)
} }
}); });
import {
user
} from "../../user/service"
export const joinRoom = id => new Promise(resolve => { export const joinRoom = id => new Promise(resolve => {
if (!user._id) return uni.navigateTo({ if (!mineInfo._id) return uni.navigateTo({
url: '/modules/user/signin/signin' url: '/modules/user/signin/signin'
}) })
ddp.call('room.join', id, (err, res) => { ddp.call('room.join', id, (err, res) => {
......
import {
import { init } from "../../uni_modules/hj-ddp/js_sdk"; watchEffect
import { hjMeteorAccount } from "../../uni_modules/hj-meteor-account/js_sdk"; } from "vue";
import {
connect
} from "../../uni_modules/hj-ddp/js_sdk";
import {
useMeteorAccount
} from "../../uni_modules/hj-meteor-account/js_sdk";
import {
useLocalMongo
}
from "../../uni_modules/hj-mongo-vue3/js_sdk";
export {
useLocalMongo as useMongo
}
from "../../uni_modules/hj-mongo-vue3/js_sdk";
// #ifdef H5 // #ifdef H5
export const ddp = init('ws://localhost:3002') export const ddp = connect('ws://localhost:3002')
// #endif // #endif
// #ifndef H5 // #ifndef H5
export const ddp = init('ws://10.0.2.2:3002') export const ddp = connect('ws://10.0.2.2:3002')
// #endif // #endif
export const account = useMeteorAccount(ddp)
export const db = useLocalMongo("shared", ddp)
ddp.use(hjMeteorAccount) watchEffect(()=>account.data.state, (nv,ov) => {
\ No newline at end of file if (nv === 2) {
uni.showLoading({
title: "登陆中"
})
}else if(ov!==2) {
uni.hideLoading()
}
})
import { import {
computed,
reactive reactive
} from "vue"; } from "vue";
export {account} from "../../core/ddp";
import { import {
ddp ddp,
useMongo,
db,
account
} from "../../core/ddp"; } from "../../core/ddp";
export const user = reactive({}) export const mineInfo = reactive({})
export const Users = ddp.db.collection('users') export const Users = db.collection('users')
ddp.user.onChange((info) => {
if (info) { export const ready = computed(()=>account.state===1)
for (const key in info) {
user[key] = info[key] account.onChange(nv => {
} const removes =new Set( Object.keys(mineInfo))
} else { if (nv) {
for (const key in user) { for (const key in nv) {
delete user[key] mineInfo[key] = nv[key]
removes.delete(key)
} }
} }
removes.forEach(key=>delete mineInfo[key])
}) })
export const signin = async (data) => { export const signin = async (data) => {
if (!data.username || !data.password) return if (!data.username || !data.password) return
ddp.loginWithPassword(data.username, data.password).catch(err => { account.loginWithPassword(data.username, data.password).catch(err => {
uni.showToast({ uni.showToast({
title: '密码或者用户名错误' title: '密码或者用户名错误'
}) })
...@@ -33,9 +40,10 @@ export const signin = async (data) => { ...@@ -33,9 +40,10 @@ export const signin = async (data) => {
export const signup = async (data) => { export const signup = async (data) => {
if (!data.username || !data.password || data.password !== data.password1) return if (!data.username || !data.password || data.password !== data.password1) return
ddp.createAccount(data.username, data.password).catch(err => { account.createAccount(data.username, data.password).catch(err => {
console.log(err)
uni.showToast({ uni.showToast({
title: '注册失败' title: '注册失败' + err?.reason
}) })
}); });
}; };
\ No newline at end of file
...@@ -11,9 +11,11 @@ ...@@ -11,9 +11,11 @@
<view class="dlbutton fsc" hover-class="dlbutton-hover" @tap="signin(data)"> <view class="dlbutton fsc" hover-class="dlbutton-hover" @tap="signin(data)">
<text>登录</text> <text>登录</text>
</view> </view>
<navigator url="../signup/signup" class="btn fsc mgv"> <view class=" fsc">
<button type="default">注册</button> <navigator url="../signup/signup" class="btn mgv">
</navigator> <button type="default">注册</button>
</navigator>
</view>
</view> </view>
</template> </template>
...@@ -24,17 +26,18 @@ ...@@ -24,17 +26,18 @@
} from "vue" } from "vue"
import { import {
signin, signin,
user mineInfo,
ready,
account
} from "../service"; } from "../service";
const data = reactive({ const data = reactive({
username: "", username: "",
password: "" password: ""
}) })
watch(user, (ov, nv) => { watch(() => account.data.state, (nv, ov) => {
console.log({ov,nv}) if (nv === 1) {
if (nv?._id) {
uni.reLaunch({ uni.reLaunch({
url: '/pages/index/index' url: '/pages/index/index'
}); });
} }
}, { }, {
...@@ -67,13 +70,16 @@ ...@@ -67,13 +70,16 @@
width: 100%; width: 100%;
} }
} }
.btn,.dlbutton{
.btn,
.dlbutton {
font-size: 34upx; font-size: 34upx;
width: 470upx; width: 470upx;
height: 100upx; height: 100upx;
border-radius: 50upx; border-radius: 50upx;
line-height: 100upx; line-height: 100upx;
} }
.dlbutton { .dlbutton {
color: #ffffff; color: #ffffff;
background: linear-gradient(-90deg, background: linear-gradient(-90deg,
...@@ -89,5 +95,4 @@ ...@@ -89,5 +95,4 @@
rgba(63, 205, 235, 0.9), rgba(63, 205, 235, 0.9),
rgba(188, 226, 158, 0.9)); rgba(188, 226, 158, 0.9));
} }
</style> </style>
...@@ -18,88 +18,84 @@ ...@@ -18,88 +18,84 @@
</template> </template>
<script setup> <script setup>
import { import {
reactive, reactive,
watch watch
} from "vue" } from "vue"
import { import {
signup, signup,
user user,
} from "../service"; account
const data = reactive({ } from "../service";
username: "", const data = reactive({
password: "", username: "",
password1: '' password: "",
}) password1: ''
watch(user, (ov, nv) => { })
console.log({ ov, nv })
if (nv?._id) { watch(() => account.data.state, (nv, ov) => {
uni.reLaunch({ if (nv === 1) {
url: '/pages/index/index' uni.reLaunch({
}); url: '/pages/index/index'
} });
}, { }
imediate: true }, {
}) imediate: true
})
</script> </script>
<style scoped="" lang="scss"> <style scoped="" lang="scss">
.input-list {
padding: 50upx 70upx;
}
.input-list { .list-call {
padding: 50upx 70upx; display: flex;
} flex-direction: row;
justify-content: space-between;
.list-call { align-items: center;
display: flex; height: 100upx;
flex-direction: row; color: #333333;
justify-content: space-between; border-bottom: 1upx solid rgba(230, 230, 230, 1);
align-items: center;
height: 100upx;
color: #333333;
border-bottom: 1upx solid rgba(230, 230, 230, 1);
input { input {
width: 100%; width: 100%;
}
} }
}
.dlbutton { .dlbutton {
color: #ffffff; color: #ffffff;
font-size: 34upx; font-size: 34upx;
width: 470upx; width: 470upx;
height: 100upx; height: 100upx;
background: linear-gradient( background: linear-gradient(-90deg,
-90deg, rgba(63, 205, 235, 1),
rgba(63, 205, 235, 1), rgba(188, 226, 158, 1));
rgba(188, 226, 158, 1) box-shadow: 0upx 0upx 13upx 0upx rgba(164, 217, 228, 0.2);
); border-radius: 50upx;
box-shadow: 0upx 0upx 13upx 0upx rgba(164, 217, 228, 0.2); line-height: 100upx;
border-radius: 50upx; text-align: center;
line-height: 100upx; margin-left: auto;
text-align: center; margin-right: auto;
margin-left: auto; margin-top: 100upx;
margin-right: auto; }
margin-top: 100upx;
}
.dlbutton-hover { .dlbutton-hover {
background: linear-gradient( background: linear-gradient(-90deg,
-90deg, rgba(63, 205, 235, 0.9),
rgba(63, 205, 235, 0.9), rgba(188, 226, 158, 0.9));
rgba(188, 226, 158, 0.9) }
);
}
.addition { .addition {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-size: 30upx; font-size: 30upx;
margin-top: 80upx; margin-top: 80upx;
color: #ffa800; color: #ffa800;
text-align: center; text-align: center;
height: 40upx; height: 40upx;
line-height: 40upx; line-height: 40upx;
} }
</style> </style>
{ {
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{ {
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "DDP Demo"
}
}
,{
"path" : "modules/user/signin/signin", "path" : "modules/user/signin/signin",
"style" : "style" :
{ {
...@@ -14,7 +8,14 @@ ...@@ -14,7 +8,14 @@
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
} },
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "DDP Demo"
}
}
,{ ,{
"path" : "modules/user/signup/signup", "path" : "modules/user/signup/signup",
"style" : "style" :
......
## 1.2.3(2022-04-16)
提供一个callAsync方法,返回promise简化rpc调用回调模式
## 1.2.2(2022-04-16) ## 1.2.2(2022-04-16)
更新readme 更新readme
## 1.2.1(2022-04-16) ## 1.2.1(2022-04-16)
......
...@@ -244,7 +244,7 @@ class DDPConnection extends EventEmitter { ...@@ -244,7 +244,7 @@ class DDPConnection extends EventEmitter {
}); });
if (oldIndex > -1) { if (oldIndex > -1) {
const oo = this.messages.splice(oldIndex, 1)[0]; const oo = this.messages.splice(oldIndex, 1)[0];
this.revokeCallBack(oo.id, [1, "ignored"]); this.revokeCallBack(oo.id, "忽略了相同参数的相同方法调用");
} }
} }
this.messages.push(data); this.messages.push(data);
...@@ -337,7 +337,7 @@ class DDPConnection extends EventEmitter { ...@@ -337,7 +337,7 @@ class DDPConnection extends EventEmitter {
} }
} }
var IDDPConnectionState; var IDDPConnectionState;
(function (IDDPConnectionState2) { (function(IDDPConnectionState2) {
IDDPConnectionState2[IDDPConnectionState2["CLOSED"] = 0] = "CLOSED"; IDDPConnectionState2[IDDPConnectionState2["CLOSED"] = 0] = "CLOSED";
IDDPConnectionState2[IDDPConnectionState2["CONNECTING"] = 1] = "CONNECTING"; IDDPConnectionState2[IDDPConnectionState2["CONNECTING"] = 1] = "CONNECTING";
IDDPConnectionState2[IDDPConnectionState2["CONNECTED"] = 2] = "CONNECTED"; IDDPConnectionState2[IDDPConnectionState2["CONNECTED"] = 2] = "CONNECTED";
...@@ -362,7 +362,9 @@ class Client { ...@@ -362,7 +362,9 @@ class Client {
if (this.connection.state === DDPConnectionState.CONNECTED) { if (this.connection.state === DDPConnectionState.CONNECTED) {
return resolve() return resolve()
} }
const cb = ({ state }) => { const cb = ({
state
}) => {
if (state === DDPConnectionState.CONNECTED) { if (state === DDPConnectionState.CONNECTED) {
this.connection.off(DDPConnectionEvent.STATE_CHANGE, cb) this.connection.off(DDPConnectionEvent.STATE_CHANGE, cb)
resolve() resolve()
...@@ -374,7 +376,9 @@ class Client { ...@@ -374,7 +376,9 @@ class Client {
if (this.connection.state !== DDPConnectionState.CONNECTED) { if (this.connection.state !== DDPConnectionState.CONNECTED) {
return resolve() return resolve()
} }
const cb = ({ state }) => { const cb = ({
state
}) => {
if (state !== DDPConnectionState.CONNECTED) { if (state !== DDPConnectionState.CONNECTED) {
this.connection.off(DDPConnectionEvent.STATE_CHANGE, cb) this.connection.off(DDPConnectionEvent.STATE_CHANGE, cb)
resolve() resolve()
...@@ -397,7 +401,9 @@ class Client { ...@@ -397,7 +401,9 @@ class Client {
return () => onCloses.delete(cb) return () => onCloses.delete(cb)
} }
let connected = false; let connected = false;
this.connection.on(DDPConnectionEvent.STATE_CHANGE, ({ state }) => { this.connection.on(DDPConnectionEvent.STATE_CHANGE, ({
state
}) => {
const newState = state === DDPConnectionState.CONNECTED; const newState = state === DDPConnectionState.CONNECTED;
if (newState === connected) return; if (newState === connected) return;
connected = newState; connected = newState;
...@@ -409,6 +415,11 @@ class Client { ...@@ -409,6 +415,11 @@ class Client {
const callback = args.filter((el) => typeof el === "function"); const callback = args.filter((el) => typeof el === "function");
return this.connection.call(name, callArgs, callback[0], callback[1]); return this.connection.call(name, callArgs, callback[0], callback[1]);
} }
callAsync(name, ...args) {
return new Promise((res, rej) => {
this.connection.call(name, callArgs, (err, data) => err ? rej(err) : res(data));
})
}
subscribe(name, ...args) { subscribe(name, ...args) {
const callArgs = args.filter((el) => typeof el !== "function"); const callArgs = args.filter((el) => typeof el !== "function");
const callback = args.filter((el) => typeof el === "function"); const callback = args.filter((el) => typeof el === "function");
......
{ {
"id": "hj-ddp", "id": "hj-ddp",
"displayName": "DDP协议的Uniapp插件实现【附带MiniMongo Selector】", "displayName": "DDP协议的Uniapp插件实现【附带MiniMongo Selector】",
"version": "1.2.2", "version": "1.2.3",
"description": "一个uniapp的DDP客户端实现,助你成为全栈工程师,哈哈~", "description": "一个uniapp的DDP客户端实现,助你成为全栈工程师,哈哈~",
"keywords": [ "keywords": [
"hj-ddp", "hj-ddp",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册