提交 ce73caea 编写于 作者: H hdx

feat(unicloud-db组件): 新增联系人示例

上级 e5b5622d
......@@ -193,6 +193,32 @@
"style": {
"navigationBarTitleText": "general-event"
}
},
{
"path": "pages/component/unicloud-db-contacts/list",
"style": {
"navigationBarTitleText": "联系人",
"enablePullDownRefresh": true
}
},
{
"path": "pages/component/unicloud-db-contacts/add",
"style": {
"navigationBarTitleText": "新增联系人"
}
},
{
"path": "pages/component/unicloud-db-contacts/edit",
"style": {
"navigationBarTitleText": "编辑联系人",
"navigationStyle": "custom"
}
},
{
"path": "pages/component/unicloud-db-contacts/detail",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/tabBar/API",
......
<template>
<view class="page">
<unicloud-db ref="udb" v-slot:default="{data, loading, error}" :collection="collection" loadtime="manual">
<view v-if="error" class="error">{{error}}</view>
</unicloud-db>
<view class="form-item">
<text class="form-item-label">姓名</text>
<input class="form-item-input" placeholder="姓名" v-model="username" />
</view>
<view class="form-item">
<text class="form-item-label">电话</text>
<input class="form-item-input" placeholder="电话" v-model="mobile" />
</view>
<view class="form-item">
<text class="form-item-label">邮箱</text>
<input class="form-item-input" placeholder="邮箱地址" v-model="email" />
</view>
<view class="form-item">
<text class="form-item-label">备注</text>
<textarea class="form-item-input" placeholder="备注" v-model="comment" />
</view>
<view class="form-item">
<text class="form-item-label">性别</text>
<radio-group class="radio-list" @change="radioChange">
<view class="radio-item" v-for="(item, _) in genderList" :key="item.value">
<radio :value="item.value" :checked="item.value == gender" />
<text>{{item.text}}</text>
</view>
</radio-group>
</view>
<button class="btn-add" type="primary" @click="submit">提交</button>
</view>
</template>
<script>
import { COLLECTION_NAME, GenderType, GenderList, UNICLOUD_DB_CONTACTS_ADD } from './types.uts'
export default {
data() {
return {
collection: COLLECTION_NAME,
username: "",
mobile: "",
gender: "",
comment: "",
email: "",
genderList: GenderList as GenderType[],
$uniCloudElement: null as UniCloudDBElement | null
}
},
onReady() {
this.$uniCloudElement = this.$refs['udb'] as UniCloudDBElement
},
methods: {
radioChange(e : RadioGroupChangeEvent) {
this.gender = e.detail.value
},
submit() {
const value = {
username: this.username,
gender: parseInt(this.gender),
mobile: this.mobile,
comment: this.comment,
email: this.email,
};
this.$uniCloudElement!.add(value, {
showToast: false,
needLoading: true,
loadingTitle: "正在保存...",
success: (_ : UniCloudDBAddResult) => {
// TODO 后续通过 EventChannel 实现
uni.$emit(UNICLOUD_DB_CONTACTS_ADD, '')
setTimeout(() => {
uni.navigateBack()
}, 500)
},
fail: (err : any | null) => {
const error = err as UniCloudError
uni.showModal({
content: error.errMsg,
showCancel: false
})
}
})
}
}
}
</script>
<style>
.page {
padding: 15px;
}
.form-item {
flex-direction: row;
margin-bottom: 15px;
align-items: center;
}
.form-item-label {
width: 45px;
margin-right: 10px;
}
.form-item-input {
flex: 1;
font-size: 14px;
color: #666;
border: 1px #e5e5e5 solid;
border-radius: 5px;
padding: 8px;
}
.radio-list {
flex-direction: row;
}
.radio-item {
flex-direction: row;
margin-right: 30px;
align-items: center;
}
.btn-add {
margin-top: 50px;
}
</style>
\ No newline at end of file
<template>
<scroll-view class="page">
<unicloud-db ref="udb" v-slot:default="{data, loading, error}" :collection="collection" :where="where"
loadtime="manual" page-data="replace">
<view v-if="error!=null" class="error">{{error.errMsg}}</view>
<view v-if="loading" class="loading">正在加载...</view>
<view v-if="data.length>0">
<view class="form-item">
<text class="form-item-label">姓名</text>
<text class="form-item-input">{{data[0]['username']}}</text>
</view>
<view class="form-item">
<text class="form-item-label">电话</text>
<text class="form-item-input">{{data[0]['mobile']}}</text>
</view>
<view class="form-item">
<text class="form-item-label">邮箱</text>
<text class="form-item-input">{{data[0]['email']}}</text>
</view>
<view class="form-item">
<text class="form-item-label">备注</text>
<text class="form-item-input">{{data[0]['comment']}}</text>
</view>
<view class="form-item">
<text class="form-item-label">性别</text>
<text class="form-item-input">{{displayGender(data[0]['gender'])}}</text>
</view>
<button class="btn-update" type="default" @click="updateAt(data[0].getString('_id'))">编辑</button>
</view>
</unicloud-db>
</scroll-view>
</template>
<script>
import { COLLECTION_NAME, GenderType, GenderList, UNICLOUD_DB_CONTACTS_UPDATE } from './types.uts'
export default {
data() {
return {
collection: COLLECTION_NAME,
where: '',
$whereID: '',
$uniCloudElement: null as UniCloudDBElement | null
}
},
onLoad(options : Map<string, string>) {
this.$whereID = options['id'] as string;
this.where = `_id=='${this.$whereID}'`;
},
onShow() {
// TODO 后续通过 EventChannel 实现
uni.$off(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
},
onUnload() {
// TODO 后续通过 EventChannel 实现
uni.$off(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
},
onReady() {
this.$uniCloudElement = this.$refs['udb'] as UniCloudDBElement
this.$uniCloudElement!.loadData()
},
methods: {
displayGender(value : any | null) : string {
const str = (value ?? 0).toString()
return (GenderList as GenderType[]).find((item : GenderType) : boolean => {
return item.value == str
})!.text;
},
updateAt(id : string | null) {
// TODO 后续通过 EventChannel 实现
uni.$on(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
uni.navigateTo({
url: './edit?id=' + id
})
},
onQueryLoad(data : Array<UTSJSONObject>, _ : boolean, pagination : UTSJSONObject) {
const data1 = data[0];
},
onDataChange(id : string) {
this.$uniCloudElement!.loadData()
}
}
}
</script>
<style>
.page {
padding: 15px;
}
.loading {
align-items: center;
}
.form-item {
flex-direction: row;
margin-bottom: 15px;
align-items: center;
padding: 8px 0;
}
.form-item-label {
width: 45px;
margin-right: 10px;
}
.form-item-input {
flex: 1;
font-size: 14px;
color: #666;
}
</style>
<template>
<view class="page">
<navbar>
<template v-slot:left>
<text class="btn-cancel">取消</text>
</template>
<template v-slot:right>
<text class="btn-update" @click="update">保存</text>
</template>
</navbar>
<scroll-view class="scroll-view" :scroll-y="true">
<unicloud-db ref="udb" v-slot:default="{data, loading, error}" :collection="collection" :where="where"
page-data="replace" loadtime="manual" @load="onQueryLoad">
<view v-if="error!=null" class="error">{{error.errMsg}}</view>
<view v-if="loading" class="loading">正在加载...</view>
<view v-if="data.length>0">
<view class="form-item">
<text class="form-item-label">姓名</text>
<input class="form-item-input" placeholder="姓名" v-model="username" />
</view>
<view class="form-item">
<text class="form-item-label">电话</text>
<input class="form-item-input" placeholder="电话" v-model="mobile" />
</view>
<view class="form-item">
<text class="form-item-label">邮箱</text>
<input class="form-item-input" placeholder="邮箱地址" v-model="email" />
</view>
<view class="form-item">
<text class="form-item-label">备注</text>
<textarea class="form-item-input" placeholder="备注" v-model="comment" />
</view>
<view class="form-item">
<text class="form-item-label">性别</text>
<radio-group class="radio-list" @change="radioChange">
<view class="radio-item" v-for="(item, _) in genderList" :key="item.value">
<radio :value="item.value" :checked="item.value == gender" />
<text>{{item.text}}</text>
</view>
</radio-group>
</view>
<button class="btn-delete" type="warn"
@click="remove(data[0].getString('_id'), data[0].getString('username'))">删除联系人</button>
</view>
</unicloud-db>
</scroll-view>
</view>
</template>
<script>
import { COLLECTION_NAME, GenderType, GenderList, UNICLOUD_DB_CONTACTS_UPDATE, UNICLOUD_DB_CONTACTS_DELETE } from './types.uts'
import navbar from './navbar.uvue'
export default {
components: {
navbar
},
data() {
return {
collection: COLLECTION_NAME,
where: '',
username: "",
mobile: "",
gender: '',
comment: "",
email: "",
genderList: GenderList as GenderType[],
$whereID: '',
$uniCloudElement: null as UniCloudDBElement | null
}
},
onLoad(options : Map<string, string>) {
this.$whereID = options['id'] as string;
this.where = `_id=='${this.$whereID}'`;
},
onReady() {
this.$uniCloudElement = this.$refs['udb'] as UniCloudDBElement
this.$uniCloudElement!.loadData()
},
methods: {
radioChange(e : RadioGroupChangeEvent) {
this.gender = e.detail.value
},
update() {
const value = {
username: this.username,
gender: parseInt(this.gender),
mobile: this.mobile,
comment: this.comment,
email: this.email,
};
this.$uniCloudElement!.update(this.$whereID, value, {
showToast: false,
needLoading: true,
needConfirm: false,
loadingTitle: "正在保存...",
success: (_ : UniCloudDBUpdateResult) => {
// TODO 后续通过 EventChannel 实现
uni.$emit(UNICLOUD_DB_CONTACTS_UPDATE, this.$whereID)
setTimeout(() => {
uni.navigateBack()
}, 500)
},
fail: (err : any | null) => {
const error = err as UniCloudError
uni.showModal({
content: error.errMsg,
showCancel: false
})
}
})
},
remove(id : string | null, name : string | null) {
this.$uniCloudElement!.remove(id!, {
needConfirm: true,
needLoading: true,
loadingTitle: "正在删除...",
confirmTitle: "确定删除?",
confirmContent: name,
success: (_ : UniCloudDBRemoveResult) => {
// TODO 后续通过 EventChannel 实现
uni.$emit(UNICLOUD_DB_CONTACTS_DELETE, this.$whereID)
setTimeout(() => {
uni.navigateBack({
delta: 2
})
}, 500)
},
fail: (err : any | null) => {
const error = err as UniCloudError
uni.showModal({
content: error.errMsg,
showCancel: false
})
}
})
},
onQueryLoad(data : Array<UTSJSONObject>, _ : boolean) {
if (data.length == 0) {
return
}
const data1 = data[0];
this.username = data1.getString('username') ?? "";
this.mobile = data1.getString('mobile') ?? "";
this.gender = data1.getNumber('gender')?.toString() ?? '0';
this.comment = data1.getString('comment') ?? "";
this.email = data1.getString('email') ?? "";
}
}
}
</script>
<style>
.page {
flex: 1;
}
.scroll-view {
padding: 15px;
flex: 1;
}
.loading {
align-items: center;
}
.form-item {
flex-direction: row;
margin-bottom: 15px;
align-items: center;
}
.form-item-label {
width: 45px;
margin-right: 10px;
}
.form-item-input {
flex: 1;
font-size: 14px;
color: #666;
border: 1px #e5e5e5 solid;
border-radius: 5px;
padding: 8px;
}
.radio-list {
flex-direction: row;
}
.radio-item {
flex-direction: row;
margin-right: 30px;
align-items: center;
}
.btn-cancel {
color: #fff;
margin-left: 15px;
}
.btn-update {
color: #fff;
margin-right: 15px;
}
.btn-delete {
margin-top: 350px;
}
</style>
<template>
<view class="page">
<unicloud-db ref="udb" v-slot:default="{data, pagination, loading, hasMore, error}" :collection="collection"
:page-size="10" :getcount="true" loadtime="manual">
<view v-if="error!=null" class="error">{{error.errMsg}}</view>
<list-view ref="listView" class="list-view" :scroll-y="true" @scrolltolower="loadMore()">
<list-item class="list-item" v-for="(item, _) in data" @click="gotoDetailPage(item['_id'] as string)">
<view class="list-item-fill">
<text class="name">{{item['username']}}</text>
<text class="mobile">{{item['mobile']}}</text>
</view>
</list-item>
</list-view>
<view v-if="loading" class="loading">正在加载...</view>
<view v-if="data.length>0" class="pagination">
<text class="pagination-item">{{data.length}} / {{pagination.count}}</text>
</view>
</unicloud-db>
<view class="btn-plus" @click="gotoAddPage">
<text class="btn-plus-text">+</text>
</view>
</view>
</template>
<script>
import { COLLECTION_NAME, UNICLOUD_DB_CONTACTS_ADD, UNICLOUD_DB_CONTACTS_UPDATE, UNICLOUD_DB_CONTACTS_DELETE } from './types.uts'
export default {
data() {
return {
collection: COLLECTION_NAME,
$uniCloudElement: null as UniCloudDBElement | null
}
},
onReady() {
// TODO 后续通过 EventChannel 实现
uni.$on(UNICLOUD_DB_CONTACTS_DELETE, this.onDataChange);
this.$uniCloudElement = this.$refs['udb'] as UniCloudDBElement
this.$uniCloudElement!.loadData()
},
onUnload() {
// TODO 后续通过 EventChannel 实现
uni.$off(UNICLOUD_DB_CONTACTS_ADD, this.onDataChange);
uni.$off(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
uni.$off(UNICLOUD_DB_CONTACTS_DELETE, this.onDataChange);
},
onShow() {
// TODO 后续通过 EventChannel 实现
uni.$off(UNICLOUD_DB_CONTACTS_ADD, this.onDataChange);
uni.$off(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
},
onPullDownRefresh() {
this.$uniCloudElement!.loadData({
clear: true,
success: (_ : UniCloudDBGetResult) => {
uni.stopPullDownRefresh()
}
})
},
methods: {
loadMore() {
this.$uniCloudElement!.loadMore()
},
gotoAddPage() {
// TODO 后续通过 EventChannel 实现
uni.$on(UNICLOUD_DB_CONTACTS_ADD, this.onDataChange);
uni.navigateTo({
url: './add'
})
},
gotoDetailPage(id : string) {
// TODO 后续通过 EventChannel 实现
uni.$on(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
uni.navigateTo({
url: './detail?id=' + id
})
},
onDataChange(id : string) {
this.$uniCloudElement!.loadData({
clear: true
})
}
}
}
</script>
<style>
.page {
flex: 1;
flex-direction: column;
}
.loading {
align-items: center;
padding: 20px;
}
.list-view {
flex: 1;
flex-direction: column;
}
.list-item {
flex-direction: row;
padding: 10px;
background-color: #fff;
margin-bottom: 1px;
}
.mobile {
margin-top: 5px;
}
.btn-plus {
position: absolute;
width: 64px;
height: 64px;
right: 20px;
bottom: 20px;
align-items: center;
justify-content: center;
background-color: #1e90ff;
border-radius: 64px;
}
.btn-plus-text {
font-size: 30px;
color: #fff;
}
.pagination {
align-items: center;
background-color: #f8f8f8;
padding: 15px;
}
</style>
<template>
<view class="navigation-bar">
<view :style="statusBarStyle"></view>
<view class="navigation-bar-header">
<view class="navbar-left" @click="back">
<slot name="left">1</slot>
</view>
<view class="navbar-content">
<slot name="middle"></slot>
</view>
<view class="navbar-right">
<slot name="right"></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: "navbar",
props: {
},
data() {
return {
statusBarHeight: 0
};
},
computed: {
statusBarStyle() : string {
return `padding-top:${this.statusBarHeight}px`
},
},
created() {
this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
setTimeout(() => {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#007AFF'
})
}, 100)
},
methods: {
back() {
uni.navigateBack({})
}
}
}
</script>
<style>
.navigation-bar {
background-color: #007AFF;
flex-direction: column;
}
.navigation-bar-header {
position: relative;
flex-direction: row;
align-items: center;
height: 45px;
}
.navbar-content {
flex: 1;
align-items: center;
}
</style>
export const COLLECTION_NAME = 'opendb-contacts'
export type GenderType = {
text : string,
value : string,
}
export const GenderList = [
{
text: "未知",
value: "0"
},
{
text: "男",
value: "1"
},
{
text: "女",
value: "2"
},
] as GenderType[]
export const UNICLOUD_DB_CONTACTS_ADD = 'unicloud-db-contacts-add'
export const UNICLOUD_DB_CONTACTS_UPDATE = 'unicloud-db-contacts-update'
export const UNICLOUD_DB_CONTACTS_DELETE = 'unicloud-db-contacts-delete'
......@@ -220,6 +220,17 @@ export default {
url: '/pages/component/web-view-local/web-view-local',
},
] as Page[],
},
{
id: 'unicloud-db',
name: 'uniCloud-db',
pages: [
{
name: '联系人',
enable: true,
url: '/pages/component/unicloud-db-contacts/list'
}
] as Page[],
},
/*
{
......
{
"bsonType": "object",
"permission": {
"read": true,
"create": true,
"update": true,
"delete": true
},
"required": ["username", "mobile"],
"properties": {
"_id": {
"description": "存储文档 ID(用户 ID),系统自动生成"
},
"username": {
"bsonType": "string",
"title": "姓名",
"description": "姓名",
"order": 1,
"trim": "both"
},
"gender": {
"bsonType": "int",
"title": "性别",
"description": "用户性别:0 未知 1 男性 2 女性",
"order": 2,
"defaultValue": 0,
"enum": [{
"text": "未知",
"value": 0
},
{
"text": "男",
"value": 1
},
{
"text": "女",
"value": 2
}
]
},
"mobile": {
"bsonType": "string",
"title": "电话",
"order": 3,
"description": "电话",
"pattern": "^\\+?[0-9-]{3,20}$",
"trim": "both"
},
"email": {
"bsonType": "string",
"format": "email",
"title": "邮箱",
"order": 4,
"description": "邮箱地址",
"trim": "both"
},
"comment": {
"bsonType": "string",
"title": "备注",
"order": 5,
"description": "备注",
"trim": "both",
"component": {
"name": "textarea"
}
},
"create_date": {
"bsonType": "timestamp",
"description": "创建时间",
"forceDefaultValue": {
"$env": "now"
}
}
},
"version": "0.0.1"
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册