Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello uni-app x
提交
3ffd0037
H
hello uni-app x
项目概览
DCloud
/
hello uni-app x
通知
6132
Star
98
Fork
169
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
19
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-app x
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
19
Issue
19
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
3ffd0037
编写于
10月 17, 2023
作者:
DCloud-yyl
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dev' into alpha
上级
1ce1ed10
1891bb5b
变更
24
隐藏空白更改
内联
并排
Showing
24 changed file
with
1722 addition
and
331 deletion
+1722
-331
hybrid/html/local.html
hybrid/html/local.html
+6
-6
pages.json
pages.json
+53
-9
pages/API/element-draw/element-draw.uvue
pages/API/element-draw/element-draw.uvue
+312
-0
pages/API/element-takesnapshot/element-takesnapshot.test.js
pages/API/element-takesnapshot/element-takesnapshot.test.js
+30
-0
pages/API/element-takesnapshot/element-takesnapshot.uvue
pages/API/element-takesnapshot/element-takesnapshot.uvue
+89
-0
pages/component/list-view/list-view.uvue
pages/component/list-view/list-view.uvue
+44
-2
pages/component/slider-100/slider-100.uvue
pages/component/slider-100/slider-100.uvue
+4
-4
pages/component/sticky-header/sticky-header.test.js
pages/component/sticky-header/sticky-header.test.js
+15
-0
pages/component/sticky-header/sticky-header.uvue
pages/component/sticky-header/sticky-header.uvue
+92
-0
pages/component/text/text.uvue
pages/component/text/text.uvue
+81
-70
pages/component/unicloud-db-contacts/add.uvue
pages/component/unicloud-db-contacts/add.uvue
+129
-0
pages/component/unicloud-db-contacts/detail.uvue
pages/component/unicloud-db-contacts/detail.uvue
+109
-0
pages/component/unicloud-db-contacts/edit.uvue
pages/component/unicloud-db-contacts/edit.uvue
+212
-0
pages/component/unicloud-db-contacts/list.uvue
pages/component/unicloud-db-contacts/list.uvue
+136
-0
pages/component/unicloud-db-contacts/navbar.uvue
pages/component/unicloud-db-contacts/navbar.uvue
+67
-0
pages/component/unicloud-db-contacts/types.uts
pages/component/unicloud-db-contacts/types.uts
+25
-0
pages/component/view/view.uvue
pages/component/view/view.uvue
+0
-8
pages/pages.test.js
pages/pages.test.js
+3
-1
pages/tabBar/API.uvue
pages/tabBar/API.uvue
+9
-0
pages/tabBar/component.uvue
pages/tabBar/component.uvue
+15
-1
pages/tabBar/template.uvue
pages/tabBar/template.uvue
+1
-1
pages/template/list-news/list-news.uvue
pages/template/list-news/list-news.uvue
+206
-194
pages/template/long-list/long-list-page.uvue
pages/template/long-list/long-list-page.uvue
+8
-35
uniCloud-aliyun/database/opendb-contacts.schema.json
uniCloud-aliyun/database/opendb-contacts.schema.json
+76
-0
未找到文件。
hybrid/html/local.html
浏览文件 @
3ffd0037
...
...
@@ -55,29 +55,29 @@
console
.
log
(
action
);
switch
(
action
)
{
case
'
switchTab
'
:
uni
.
switchTab
({
uni
.
webView
.
switchTab
({
url
:
'
/pages/tabBar/API
'
});
break
;
case
'
reLaunch
'
:
uni
.
reLaunch
({
uni
.
webView
.
reLaunch
({
url
:
'
/pages/tabBar/component
'
});
break
;
case
'
navigateBack
'
:
uni
.
navigateBack
({
uni
.
webView
.
navigateBack
({
delta
:
1
});
break
;
case
'
getEnv
'
:
uni
.
getEnv
((
res
)
=>
{
uni
.
webView
.
getEnv
((
res
)
=>
{
uni
.
postMessage
({
data
:
res
})
});
break
;
default
:
uni
[
action
]({
uni
.
webView
[
action
]({
url
:
'
/pages/component/button/button
'
});
break
;
...
...
@@ -86,7 +86,7 @@
})
// });
document
.
querySelector
(
"
#postMessage
"
).
addEventListener
(
'
click
'
,
function
()
{
uni
.
postMessage
({
uni
.
webView
.
postMessage
({
data
:
{
action
:
'
message
'
}
...
...
pages.json
浏览文件 @
3ffd0037
...
...
@@ -14,12 +14,6 @@
"navigationBarTitleText"
:
"view"
}
},
{
"path"
:
"pages/component/view/view-draw"
,
"style"
:
{
"navigationBarTitleText"
:
"DrawableContext"
}
},
{
"path"
:
"pages/component/scroll-view/scroll-view"
,
"style"
:
{
...
...
@@ -199,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"
,
...
...
@@ -844,7 +864,7 @@
{
"path"
:
"pages/template/scroll-sticky/scroll-sticky"
,
"style"
:
{
"navigationBarTitleText"
:
"滚动吸顶"
"navigationBarTitleText"
:
"
scroll-view自定义
滚动吸顶"
}
},
{
...
...
@@ -958,7 +978,31 @@
"navigationBarTitleText"
:
""
,
"enablePullDownRefresh"
:
false
}
}
},
{
"path"
:
"pages/component/sticky-header/sticky-header"
,
"style"
:
{
"navigationBarTitleText"
:
"sticky-header"
,
"enablePullDownRefresh"
:
false
}
},
{
"path"
:
"pages/API/element-takesnapshot/element-takesnapshot"
,
"style"
:
{
"navigationBarTitleText"
:
"takeSnapshot"
,
"enablePullDownRefresh"
:
false
}
},
{
"path"
:
"pages/API/element-draw/element-draw"
,
"style"
:
{
"navigationBarTitleText"
:
"getDrawableContext"
,
"enablePullDownRefresh"
:
false
}
}
],
"globalStyle"
:
{
"pageOrientation"
:
"portrait"
,
...
...
@@ -1009,4 +1053,4 @@
"query"
:
""
//启动参数,在页面的onLoad函数里面得到
}]
}
}
\ No newline at end of file
}
pages/
component/view/view
-draw.uvue
→
pages/
API/element-draw/element
-draw.uvue
浏览文件 @
3ffd0037
...
...
@@ -3,14 +3,14 @@
<scroll-view style="flex: 1">
<!-- #endif -->
<view>
<view
ref
="draw-text-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
ref
="draw-line-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
ref
="draw-circle-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
ref
="draw-dash-line" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
ref
="draw-house" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
ref
="draw-style" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
ref
="draw-odd" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
ref
="draw-arcto" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
id
="draw-text-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
id
="draw-line-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
id
="draw-circle-view" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
id
="draw-dash-line" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
id
="draw-house" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
id
="draw-style" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
id
="draw-odd" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
<view
id
="draw-arcto" style="width: 750rpx;height: 550rpx; background-color: lightgray;margin: 30rpx 0rpx;"></view>
</view>
<!-- #ifdef APP -->
</scroll-view>
...
...
@@ -57,68 +57,68 @@
},
methods: {
drawText() {
let element =
(this.$refs['draw-text-view'] as Element
)
let ctx = element.getDrawableContext()
let element =
uni.getElementById('draw-text-view'
)
let ctx = element
!
.getDrawableContext()
let width = element.getBoundingClientRect().width
ctx!
!
.reset()
ctx
!!
.font = "15px"
ctx
!
.textAlign = "center"
ctx!.reset()
ctx.font = "15px"
ctx.textAlign = "center"
for (var i = 0; i < this.texts.length; i++) {
let value = this.texts[i]
if (i % 2 == 0) {
ctx
!!
.fillText(value, width / 2, (20 * (i + 1)))
ctx.fillText(value, width / 2, (20 * (i + 1)))
} else {
ctx
!!
.strokeText(value, width / 2, (20 * (i + 1)))
ctx.strokeText(value, width / 2, (20 * (i + 1)))
}
}
ctx
!!
.update()
ctx.update()
},
drawLines() {
let ctx =
(this.$refs['draw-line-view'] as Element)
.getDrawableContext()
ctx!
!
.reset()
ctx
!!
.lineWidth = 10;
let ctx =
uni.getElementById('draw-line-view')!
.getDrawableContext()
ctx!.reset()
ctx.lineWidth = 10;
["round", "bevel", "miter"].forEach((join, i) => {
ctx
!
.lineJoin = join;
ctx
!
.beginPath();
ctx
!
.moveTo(5, 10 + i * 40);
ctx
!
.lineTo(50, 50 + i * 40);
ctx
!
.lineTo(90, 10 + i * 40);
ctx
!
.lineTo(130, 50 + i * 40);
ctx
!
.lineTo(170, 10 + i * 40);
ctx
!
.stroke();
ctx.lineJoin = join;
ctx.beginPath();
ctx.moveTo(5, 10 + i * 40);
ctx.lineTo(50, 50 + i * 40);
ctx.lineTo(90, 10 + i * 40);
ctx.lineTo(130, 50 + i * 40);
ctx.lineTo(170, 10 + i * 40);
ctx.stroke();
});
ctx
!!
.lineWidth = 1
ctx.lineWidth = 1
var space = 170
ctx
!
.strokeStyle = '#09f';
ctx
!
.beginPath();
ctx
!
.moveTo(10 + space, 10);
ctx
!
.lineTo(140 + space, 10);
ctx
!
.moveTo(10 + space, 140);
ctx
!
.lineTo(140 + space, 140);
ctx
!
.stroke();
ctx.strokeStyle = '#09f';
ctx.beginPath();
ctx.moveTo(10 + space, 10);
ctx.lineTo(140 + space, 10);
ctx.moveTo(10 + space, 140);
ctx.lineTo(140 + space, 140);
ctx.stroke();
// Draw lines
ctx
!
.strokeStyle = 'black';
ctx.strokeStyle = 'black';
['butt', 'round', 'square'].forEach((lineCap, i) => {
ctx
!
.lineWidth = 15;
ctx
!
.lineCap = lineCap;
ctx
!
.beginPath();
ctx
!
.moveTo(25 + space + i * 50, 10);
ctx
!
.lineTo(25 + space + i * 50, 140);
ctx
!
.stroke();
ctx.lineWidth = 15;
ctx.lineCap = lineCap;
ctx.beginPath();
ctx.moveTo(25 + space + i * 50, 10);
ctx.lineTo(25 + space + i * 50, 140);
ctx.stroke();
});
ctx
!
.lineWidth = 1;
this.drawDashedLine([], ctx
!
);
this.drawDashedLine([2, 2], ctx
!
);
this.drawDashedLine([10, 10], ctx
!
);
this.drawDashedLine([20, 5], ctx
!
);
this.drawDashedLine([15, 3, 3, 3], ctx
!
);
this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx
!
);
ctx
!
.lineDashOffset = 18;
this.drawDashedLine([12, 3, 3], ctx
!
);
ctx
!
.lineDashOffset = 0
ctx
!
.setLineDash([0])
ctx
!!
.update()
ctx.lineWidth = 1;
this.drawDashedLine([], ctx);
this.drawDashedLine([2, 2], ctx);
this.drawDashedLine([10, 10], ctx);
this.drawDashedLine([20, 5], ctx);
this.drawDashedLine([15, 3, 3, 3], ctx);
this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx);
ctx.lineDashOffset = 18;
this.drawDashedLine([12, 3, 3], ctx);
ctx.lineDashOffset = 0
ctx.setLineDash([0])
ctx.update()
},
drawDashedLine(pattern : Array<number>, ctx : DrawableContext) {
ctx.beginPath();
...
...
@@ -129,12 +129,12 @@
y += 15;
},
drawCircles() {
let ctx =
(this.$refs['draw-circle-view'] as Element)
.getDrawableContext()
ctx!
!
.reset()
let ctx =
uni.getElementById('draw-circle-view')!
.getDrawableContext()
ctx!.reset()
// Draw shapes
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 3; j++) {
ctx
!!
.beginPath();
ctx.beginPath();
var x = 25 + j * 50; // x coordinate
var y = 25 + i * 50; // y coordinate
var radius = 20; // Arc radius
...
...
@@ -142,22 +142,22 @@
var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
var clockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
ctx
!
.arc(x, y, radius, startAngle, endAngle, clockwise);
ctx.arc(x, y, radius, startAngle, endAngle, clockwise);
if (i > 1) {
ctx
!
.fill();
ctx.fill();
} else {
ctx
!
.stroke();
ctx.stroke();
}
}
}
ctx
!!
.update()
ctx.update()
},
drawStar() {
let ctx =
(this.$refs['draw-dash-line'] as Element)
.getDrawableContext()
ctx!
!
.reset()
ctx
!!
.beginPath();
let ctx =
uni.getElementById('draw-dash-line')!
.getDrawableContext()
ctx!.reset()
ctx.beginPath();
var horn = 5; // 画5个角
var angle = 360 / horn; // 五个角的度数
// 两个圆的半径
...
...
@@ -169,45 +169,45 @@
for (var i = 0; i < horn; i++) {
// 角度转弧度:角度/180*Math.PI
// 外圆顶点坐标
ctx
!
.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y);
ctx.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y);
// 內圆顶点坐标
ctx
!
.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y);
ctx.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y);
}
// closePath:关闭路径,将路径的终点与起点相连
ctx
!
.closePath();
ctx
!
.lineWidth = 3;
ctx
!
.fillStyle = '#E4EF00';
ctx
!
.strokeStyle = "red";
ctx
!
.fill();
ctx
!
.stroke();
ctx.closePath();
ctx.lineWidth = 3;
ctx.fillStyle = '#E4EF00';
ctx.strokeStyle = "red";
ctx.fill();
ctx.stroke();
ctx
!
.lineWidth = 10;
ctx
!
.beginPath()
ctx
!
.moveTo(170, 100)
ctx
!
.lineTo(255, 15)
ctx
!
.lineTo(340, 100)
ctx
!
.closePath()
ctx
!
.fill()
ctx
!
.strokeStyle = "blue"
ctx
!
.stroke()
ctx
!
.beginPath()
ctx
!
.moveTo(170, 145)
ctx
!
.lineTo(255, 45)
ctx
!
.lineTo(340, 145)
ctx
!
.closePath()
ctx
!
.fill()
ctx
!
.strokeStyle = "gray"
ctx
!
.stroke()
ctx.lineWidth = 10;
ctx.beginPath()
ctx.moveTo(170, 100)
ctx.lineTo(255, 15)
ctx.lineTo(340, 100)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "blue"
ctx.stroke()
ctx.beginPath()
ctx.moveTo(170, 145)
ctx.lineTo(255, 45)
ctx.lineTo(340, 145)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "gray"
ctx.stroke()
// 未设置beginPath,导致上下表现一致,与前端一致
ctx
!
.moveTo(170, 190)
ctx
!
.lineTo(255, 90)
ctx
!
.lineTo(340, 190)
ctx
!
.closePath()
ctx
!
.fillStyle = "orange"
ctx
!
.fill()
ctx
!
.strokeStyle = "khaki"
ctx
!
.stroke()
ctx
!!
.update()
ctx.moveTo(170, 190)
ctx.lineTo(255, 90)
ctx.lineTo(340, 190)
ctx.closePath()
ctx.fillStyle = "orange"
ctx.fill()
ctx.strokeStyle = "khaki"
ctx.stroke()
ctx.update()
},
hex(num : number) : string {
if (num == 0) {
...
...
@@ -226,82 +226,82 @@
return result
},
drawhouse() {
let ctx =
(this.$refs['draw-house'] as Element)
.getDrawableContext()
ctx!
!
.reset()
ctx
!!
.lineWidth = 10;
let ctx =
uni.getElementById('draw-house')!
.getDrawableContext()
ctx!.reset()
ctx.lineWidth = 10;
// Wall
ctx
!
.strokeRect(75, 140, 150, 110);
ctx.strokeRect(75, 140, 150, 110);
// Door
ctx
!
.fillRect(130, 190, 40, 60);
ctx.fillRect(130, 190, 40, 60);
// Roof
ctx
!
.beginPath();
ctx
!
.moveTo(50, 140);
ctx
!
.lineTo(150, 60);
ctx
!
.lineTo(250, 140);
ctx
!
.closePath();
ctx
!
.stroke();
ctx
!!
.update()
ctx.beginPath();
ctx.moveTo(50, 140);
ctx.lineTo(150, 60);
ctx.lineTo(250, 140);
ctx.closePath();
ctx.stroke();
ctx.update()
},
drawPoint() {
let ctx =
(this.$refs['draw-style'] as Element)
.getDrawableContext()
ctx!
!
.reset()
let ctx =
uni.getElementById('draw-style')!
.getDrawableContext()
ctx!.reset()
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx
!!
.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`;
ctx
!
.beginPath();
ctx
!
.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx
!
.stroke();
ctx.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`;
ctx.beginPath();
ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx.stroke();
}
}
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx
!!
.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`;
ctx
!
.fillRect(180 + j * 25, i * 25, 25, 25);
ctx.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`;
ctx.fillRect(180 + j * 25, i * 25, 25, 25);
}
}
ctx
!!
.update()
ctx.update()
},
drawRect() {
let ctx =
(this.$refs['draw-odd'] as Element)
.getDrawableContext()
ctx!
!
.reset()
let ctx =
uni.getElementById('draw-odd')!
.getDrawableContext()
ctx!.reset()
// Create path
ctx
!!
.moveTo(30, 90);
ctx
!
.lineTo(110, 20);
ctx
!
.lineTo(240, 130);
ctx
!
.lineTo(60, 130);
ctx
!
.lineTo(190, 20);
ctx
!
.lineTo(270, 90);
ctx
!
.closePath();
ctx.moveTo(30, 90);
ctx.lineTo(110, 20);
ctx.lineTo(240, 130);
ctx.lineTo(60, 130);
ctx.lineTo(190, 20);
ctx.lineTo(270, 90);
ctx.closePath();
// Fill path
ctx
!
.fillStyle = "green";
ctx
!
.fill("evenodd");
ctx
!!
.update()
ctx.fillStyle = "green";
ctx.fill("evenodd");
ctx.update()
},
drawArcTo() {
let ctx =
(this.$refs['draw-arcto'] as Element)
.getDrawableContext()
let ctx =
uni.getElementById('draw-arcto')!
.getDrawableContext()
ctx!.reset()
ctx
!
.beginPath();
ctx
!
.moveTo(50, 20);
ctx
!
.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx
!
.stroke();
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx.stroke();
ctx
!
.fillStyle = "blue";
ctx.fillStyle = "blue";
// start point
ctx
!
.fillRect(50, 20, 10, 10);
ctx.fillRect(50, 20, 10, 10);
// end point
ctx
!
.fillRect(50, 100, 10, 10);
ctx.fillRect(50, 100, 10, 10);
ctx
!
.fillStyle = "red";
ctx.fillStyle = "red";
// control point one
ctx
!
.fillRect(230, 30, 10, 10);
ctx.fillRect(230, 30, 10, 10);
// control point two
ctx
!
.fillRect(150, 70, 10, 10);
ctx
!
.update()
ctx.fillRect(150, 70, 10, 10);
ctx.update()
}
}
}
...
...
pages/API/element-takesnapshot/element-takesnapshot.test.js
0 → 100644
浏览文件 @
3ffd0037
const
PAGE_PATH
=
"
/pages/API/element-takesnapshot/element-takesnapshot
"
;
describe
(
"
element-takesnapshot
"
,
()
=>
{
let
page
;
function
getData
(
key
=
''
)
{
return
new
Promise
(
async
(
resolve
,
reject
)
=>
{
const
data
=
await
page
.
data
()
resolve
(
key
?
data
[
key
]
:
data
)
})
}
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
600
);
});
it
(
"
takeSnapshot
"
,
async
()
=>
{
await
page
.
waitFor
(
600
)
let
btnTakeSnapshot
=
await
page
.
$
(
'
.btn-TakeSnapshot
'
)
await
btnTakeSnapshot
.
tap
()
page
.
waitFor
(
600
)
const
image
=
await
getData
(
'
snapImage
'
)
console
.
log
(
image
)
///storage/emulated/0/Android/data/io.dcloud.uniappx/apps/__UNI__3584C99/cache/temp/screenshot/1697513148915.png
expect
(
image
.
length
).
toBeGreaterThan
(
20
)
});
});
pages/API/element-takesnapshot/element-takesnapshot.uvue
0 → 100644
浏览文件 @
3ffd0037
<template>
<view>
<page-head id="page-head" title="getElementById"></page-head>
<view class="uni-padding-wrap" id="snapshot-content">
<text id="text">this is text</text>
<view id="view" class="uni-common-mt" style="border: 1px solid red">this is view</view>
</view>
<button class="uni-btn" @click="changeViewStyle">
修改 view 宽高及背景色
</button>
<button class="uni-btn btn-TakeSnapshot" type="primary" @tap="takeSnapshotClick">
点击截图
</button>
<image style="margin-top: 20px;" :src="snapImage" mode="aspectFit" @longpress="saveToAlbum"></image>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
snapImage: "/static/uni.png"
}
},
methods: {
changeViewStyle() {
const text = uni.getElementById('text')!
text.style.setProperty('color', 'red')
const view = uni.getElementById('view')!
view.style.setProperty('width', '90%')
view.style.setProperty('height', '50px')
view.style.setProperty('backgroundColor', '#007AFF')
},
takeSnapshotClick() {
const view = uni.getElementById('snapshot-content')!
view.takeSnapshot({
success: function (res) {
console.log(res.tempFilePath)
this.snapImage = res.tempFilePath
uni.showToast({
title: '截图成功,路径:' + res.tempFilePath,
icon: "none"
})
},
fail: function (res) {
console.log(res)
uni.showToast({
icon: 'error',
title: '截图失败'
})
}
})
},
saveToAlbum(e : TouchEvent) {
// console.log(e.currentTarget!.getAttribute("src"));
let filePath : string = e.currentTarget!.getAttribute("src") as string
uni.showActionSheet({
itemList: ["保存"],
success: res => {
// console.log(res.tapIndex);
if (res.tapIndex == 0) {
uni.saveImageToPhotosAlbum({
filePath: filePath,
success() {
uni.showToast({
position: "center",
icon: "none",
title: "图片保存成功,请到手机相册查看"
})
},
fail(e) {
uni.showModal({
content: "保存相册失败,errCode:" + e.errCode + ",errMsg:" + e.errMsg + ",errSubject:" + e.errSubject,
showCancel: false
});
}
})
}
},
fail: () => { },
complete: () => { }
});
}
}
}
</script>
pages/component/list-view/list-view.uvue
浏览文件 @
3ffd0037
...
...
@@ -18,7 +18,11 @@
scrollData: [] as Array<string>,
size_enum: [{ "value": 0, "name": "item---0" }, { "value": 3, "name": "item---3" }] as ItemType[],
scrollIntoView: "",
refresherrefresh: false
refresherrefresh: false,
refresher_default_style_input: "black",
text: ['继续下拉执行刷新', '释放立即刷新', '刷新中', ""],
state: 3,
reset: true
}
},
onLoad() {
...
...
@@ -36,17 +40,30 @@
list_view_touchend() { console.log("手指触摸动作结束") },
list_view_tap() { console.log("手指触摸后马上离开") },
list_view_longpress() { console.log("如果一个组件被绑定了 longpress 事件,那么当用户长按这个组件时,该事件将会被触发。") },
list_view_refresherpulling() { console.log("下拉刷新控件被下拉") },
list_view_refresherpulling(e : RefresherEvent) {
console.log("下拉刷新控件被下拉")
if(this.reset) {
if(e.detail.dy > 45) {
this.state = 1
} else {
this.state = 0
}
}
},
list_view_refresherrefresh() {
console.log("下拉刷新被触发 ")
this.refresherrefresh = true
this.refresher_triggered_boolean = true
this.state = 2
this.reset = false;
setTimeout(function(){
this.refresher_triggered_boolean = false
}, 1500)
},
list_view_refresherrestore() {
this.refresherrefresh = false
this.state = 3
this.reset = true
console.log("下拉刷新被复位")
},
list_view_refresherabort() { console.log("下拉刷新被中止") },
...
...
@@ -90,6 +107,13 @@
return true
}
return false
},
change_refresher_style_boolean(checked : boolean) {
if(checked) {
this.refresher_default_style_input = "none"
} else {
this.refresher_default_style_input = "black"
}
}
}
}
...
...
@@ -102,6 +126,7 @@
:scroll-left="scroll_left_input" :show-scrollbar="show_scrollbar_boolean" :scroll-into-view="scrollIntoView"
:scroll-with-animation="scroll_with_animation_boolean" :refresher-enabled="refresher_enabled_boolean"
:refresher-background="refresher_background_input" :refresher-triggered="refresher_triggered_boolean"
:refresher-default-style="refresher_default_style_input"
@click="list_view_click" @touchstart="list_view_touchstart" @touchmove="list_view_touchmove"
@touchcancel="list_view_touchcancel" @touchend="list_view_touchend" @tap="list_view_tap"
@longpress="list_view_longpress" @refresherpulling="list_view_refresherpulling"
...
...
@@ -115,6 +140,9 @@
class="list-item">
<text>{{key}}</text>
</list-item>
<list-item slot="refresher" class="refresh-box">
<text class="tip-text">{{text[state]}}</text>
</list-item>
</list-view>
</view>
...
...
@@ -125,6 +153,7 @@
<boolean-data :defaultValue="false" title="设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发"
@change="change_refresher_triggered_boolean"></boolean-data>
<boolean-data :defaultValue="false" title="开启下拉刷新" @change="change_refresher_enabled_boolean"></boolean-data>
<boolean-data :defaultValue="false" title="开启自定义样式" @change="change_refresher_style_boolean"></boolean-data>
<boolean-data :defaultValue="false" title="是否在设置滚动条位置时使用滚动动画,设置false没有滚动动画"
@change="change_scroll_with_animation_boolean"></boolean-data>
<boolean-data :defaultValue="true" title="控制是否出现滚动条" @change="change_show_scrollbar_boolean"></boolean-data>
...
...
@@ -163,4 +192,17 @@
align-items: center;
justify-content: center;
}
.tip-text {
color: #888;
font-size: 12px;
}
.refresh-box {
justify-content: center;
align-items: center;
flex-direction: row;
height: 45px;
width: 100%;
}
</style>
pages/component/slider-100/slider-100.uvue
浏览文件 @
3ffd0037
...
...
@@ -45,16 +45,16 @@
// this.sliderValue = value
// TODO 跳过vue框架,直接修改原生组件
(this.$refs["slider1"]! as SliderElement[]).forEach((item) => {
(this.$refs["slider1"]! as
Uni
SliderElement[]).forEach((item) => {
item.value = value
});
(this.$refs["slider2"]! as SliderElement[]).forEach((item) => {
(this.$refs["slider2"]! as
Uni
SliderElement[]).forEach((item) => {
item.value = value
});
(this.$refs["slider3"]! as SliderElement[]).forEach((item) => {
(this.$refs["slider3"]! as
Uni
SliderElement[]).forEach((item) => {
item.value = value
});
(this.$refs["slider4"]! as SliderElement[]).forEach((item) => {
(this.$refs["slider4"]! as
Uni
SliderElement[]).forEach((item) => {
item.value = value
});
}
...
...
pages/component/sticky-header/sticky-header.test.js
0 → 100644
浏览文件 @
3ffd0037
describe
(
'
component-native-sticky-header
'
,
()
=>
{
let
page
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
'
/pages/component/sticky-header/sticky-header
'
)
await
page
.
waitFor
(
200
)
})
//检测吸顶效果
it
(
'
check_sticky_header
'
,
async
()
=>
{
await
page
.
callMethod
(
'
confirm_scroll_top_input
'
,
600
)
await
page
.
waitFor
(
400
)
const
image
=
await
program
.
screenshot
();
expect
(
image
).
toMatchImageSnapshot
();
})
})
pages/component/sticky-header/sticky-header.uvue
0 → 100644
浏览文件 @
3ffd0037
<template>
<list-view :scroll-y="true" class="page" rebound="false" :scroll-top="scroll_top_input" :refresher-enabled="refresher_enabled_boolean"
:refresher-triggered="refresher_triggered_boolean" @refresherrefresh="list_view_refresherrefresh">
<list-item type = 1>
<swiper indicator-dots="true" circular="true">
<swiper-item v-for="i in 3" :item-id="i">
<image src="/static/shuijiao.jpg" style="height: 240px;"></image>
<text style="position: absolute;">{{i}}</text>
</swiper-item>
</swiper>
</list-item>
<list-item class="content-item" type = 2>
<text class="text">向上滑动页面,体验sticky-header吸顶效果。</text>
</list-item>
<sticky-header>
<scroll-view style="background-color: #f5f5f5; flex-direction: row;" :scroll-x="true" :scroll-y="false" :show-scrollbar="false">
<view class="flex-row" style="align-self: flex-start; flex-direction: row;">
<text ref="swipertab" class="sift-item"
v-for="(name,index) in sift_item" @click="clickTH(index)">
{{name}}
</text>
</view>
</scroll-view>
</sticky-header>
<list-item v-for="(item,index) in list_item" :key="index" class="content-item" type = 3>
<text class="text">{{item}}</text>
</list-item>
</list-view>
</template>
<script>
export default {
data() {
return {
sift_item: ["排序", "筛选"],
list_item: [] as Array<string>,
refresher_enabled_boolean: true,
refresher_triggered_boolean: false,
scroll_top_input: 0
}
},
onLoad() {
let lists : Array<string> = []
for (let i = 0; i < 40; i++) {
lists.push("item---" + i)
}
this.list_item = lists
},
methods: {
list_view_refresherrefresh() {
console.log("下拉刷新被触发 ")
this.refresher_triggered_boolean = true
setTimeout(function(){
this.refresher_triggered_boolean = false
}, 1500)
},
confirm_scroll_top_input(value : number) {
this.scroll_top_input = value
},
clickTH(index:number){
console.log("点击表头:" + index);
}
}
}
</script>
<style>
.page {
flex: 1;
background-color: #f5f5f5;
}
.content-item {
padding: 15px;
margin: 5px 0;
background-color: #fff;
}
.text {
font-size: 14px;
color: #666;
line-height: 20px;
}
.sift-item {
color: #555;
font-size: 16px;
padding: 12px 15px;
}
</style>
pages/component/text/text.uvue
浏览文件 @
3ffd0037
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="text-box" scroll-y="true">
<text class="text">{{text}}</text>
</view>
<view class="uni-btn-v">
<button class="uni-btn" type="primary" :disabled="!canAdd" @click="add">add line</button>
<button class="uni-btn" type="warn" :disabled="!canRemove" @click="remove">remove line</button>
<button class="uni-btn" type="primary" @click="textProps">更多属性示例</button>
</view>
</view>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="text-box" scroll-y="true">
<text class="text">{{ text }}</text>
</view>
<view class="uni-btn-v">
<button class="uni-btn" type="primary" :disabled="!canAdd" @click="add">
add line
</button>
<button
class="uni-btn"
type="warn"
:disabled="!canRemove"
@click="remove"
>
remove line
</button>
<button class="uni-btn" type="primary" @click="textProps">
更多属性示例
</button>
</view>
</view>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
title: 'text',
texts: [
'HBuilderX,轻巧、极速,极客编辑器',
'uni-app x,终极跨平台方案',
'uniCloud,js serverless云服务',
'uts,大一统语言',
'uniMPSdk,让你的App具备小程序能力',
'uni-admin,开源、现成的全端管理后台',
'uni-id,开源、全端的账户中心',
'uni-pay,开源、云端一体、全平台的支付',
'uni-ai,聚合ai能力',
'uni-cms,开源、云端一体、全平台的内容管理平台',
'uni-im,开源、云端一体、全平台的im即时消息',
'uni统计,开源、完善、全平台的统计报表',
'......'
] as string[],
text: '',
canAdd: true,
canRemove: false,
extraLine: [] as string[]
}
export default {
data() {
return {
title: 'text',
texts: [
'HBuilderX,轻巧、极速,极客编辑器',
'uni-app x,终极跨平台方案',
'uniCloud,js serverless云服务',
'uts,大一统语言',
'uniMPSdk,让你的App具备小程序能力',
'uni-admin,开源、现成的全端管理后台',
'uni-id,开源、全端的账户中心',
'uni-pay,开源、云端一体、全平台的支付',
'uni-ai,聚合ai能力',
'uni-cms,开源、云端一体、全平台的内容管理平台',
'uni-im,开源、云端一体、全平台的im即时消息',
'uni统计,开源、完善、全平台的统计报表',
'......'
] as string[],
text: '',
canAdd: true,
canRemove: false,
extraLine: [] as string[]
}
},
methods: {
add: function () {
this.extraLine.push(this.texts[this.extraLine.length % 12]);
this.text = this.extraLine.join('\n');
this.canAdd = this.extraLine.length < 12;
this.canRemove = this.extraLine.length > 0;
},
methods:
{
add: function (
) {
this.extraLine.p
ush(this.texts[this.extraLine.length % 12]
);
remove: function ()
{
if (this.extraLine.length > 0
) {
this.extraLine.p
op(
);
this.text = this.extraLine.join('\n');
this.canAdd = this.extraLine.length < 12;
this.canRemove = this.extraLine.length > 0;
},
remove: function () {
if (this.extraLine.length > 0) {
this.extraLine.pop();
this.text = this.extraLine.join('\n');
this.canAdd = this.extraLine.length < 12;
this.canRemove = this.extraLine.length > 0;
}
},
textProps: function () {
uni.navigateTo({
url: '/pages/component/text/text-props'
})
}
}
}
},
textProps: function () {
uni.navigateTo({
url: '/pages/component/text/text-props'
})
}
}
}
</script>
<style>
.text-box {
margin-bottom: 40rpx;
padding: 40rpx 0;
display: flex;
min-height: 300rpx;
background-color: #FFFFFF
;
justify-content: center;
align-items: center;
}
.text-box {
margin-bottom: 40rpx;
padding: 40rpx 0;
display: flex;
min-height: 300rpx;
background-color: #ffffff
;
justify-content: center;
align-items: center;
}
.text {
font-size: 30rpx;
color: #353535;
line-height: 54rpx;
text-align: center;
}
</style>
\ No newline at end of file
.text {
font-size: 30rpx;
color: #353535;
line-height: 54rpx;
text-align: center;
}
</style>
pages/component/unicloud-db-contacts/add.uvue
0 → 100644
浏览文件 @
3ffd0037
<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
pages/component/unicloud-db-contacts/detail.uvue
0 → 100644
浏览文件 @
3ffd0037
<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="gotoUpdatePage(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;
},
gotoUpdatePage(id : string | null) {
// TODO 后续通过 EventChannel 实现
uni.$on(UNICLOUD_DB_CONTACTS_UPDATE, this.onDataChange);
uni.navigateTo({
url: './edit?id=' + id
})
},
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>
pages/component/unicloud-db-contacts/edit.uvue
0 → 100644
浏览文件 @
3ffd0037
<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>
pages/component/unicloud-db-contacts/list.uvue
0 → 100644
浏览文件 @
3ffd0037
<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>
pages/component/unicloud-db-contacts/navbar.uvue
0 → 100644
浏览文件 @
3ffd0037
<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>
pages/component/unicloud-db-contacts/types.uts
0 → 100644
浏览文件 @
3ffd0037
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'
pages/component/view/view.uvue
浏览文件 @
3ffd0037
...
...
@@ -12,9 +12,6 @@
<boolean-data :defaultValue="false" title="是否阻止本节点的祖先节点出现点击态" @change="change_stop_propagation_boolean"></boolean-data>
<enum-data :items="start_time_enum" title="按住后多久出现点击态" @change="radio_change_start_time_enum"></enum-data>
<enum-data :items="stay_time_enum" title="手指松开后点击态保留时间" @change="radio_change_stay_time_enum"></enum-data>
<view class="uni-padding-wrap uni-common-mt uni-common-mb">
<button class="uni-common-mt" @click="goGeneralAttribute('/pages/component/view/view-draw')">DrawableContext</button>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
...
...
@@ -46,11 +43,6 @@ export default {
radio_change_stay_time_enum(time : number) {
this.stay_time = time
},
goGeneralAttribute(path: string) {
uni.navigateTo({
url: path,
})
},
},
}
</script>
...
...
pages/pages.test.js
浏览文件 @
3ffd0037
...
...
@@ -34,7 +34,6 @@ const pages = [
'
/pages/component/text/text
'
,
'
/pages/component/textarea/textarea
'
,
// '/pages/component/video/video',
'
/pages/component/view/view-draw
'
,
'
/pages/component/view/view
'
,
// '/pages/component/web-view/web-view', // 动态内容
'
/pages/component/web-view-local/web-view-local
'
,
...
...
@@ -120,6 +119,9 @@ const pages = [
'
/pages/template/swiper-list/swiper-list
'
,
'
/pages/template/swiper-list2/swiper-list2
'
,
// '/pages/template/swiper-vertical-video/swiper-vertical-video'
// api
'
/pages/API/element-draw/element-draw
'
,
]
let
page
;
...
...
pages/tabBar/API.uvue
浏览文件 @
3ffd0037
...
...
@@ -146,6 +146,15 @@
name: 'element元素',
url: 'get-element-by-id',
api: ["getElementById"]
},
{
name: 'element draw',
url: 'element-draw',
api: ["Element.getDrawableContext"]
},{
name: 'element截图',
url: 'element-takesnapshot',
api: ["Element.takeSnapshot"]
},
{
name: 'node节点',
...
...
pages/tabBar/component.uvue
浏览文件 @
3ffd0037
...
...
@@ -87,7 +87,10 @@ export default {
*/
{
name: 'list-view',
},
},
{
name: 'sticky-header',
}
] as Page[],
},
{
...
...
@@ -217,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[],
},
/*
{
...
...
pages/tabBar/template.uvue
浏览文件 @
3ffd0037
...
...
@@ -141,7 +141,7 @@ export default {
{
id: 'scroll-sticky',
url: 'scroll-sticky',
name: '吸顶',
name: '
scroll-view自定义滚动
吸顶',
open: false,
pages: [] as Page[],
},
...
...
pages/template/list-news/list-news.uvue
浏览文件 @
3ffd0037
<template>
<view style="width: 100%;height: 100%;">
<view class="banner" @click="bannerClick(banner)">
<image class="banner-img" :src="banner.cover"></image>
<text class="banner-title">{{ banner.title }}</text>
</view>
<list-view class="uni-list-content" refresher-enabled=true @refresherrefresh="onRefresherrefresh"
:refresher-triggered="refresherTriggered" scroll-y = true>
<list-item v-for="(value, index) in listData" :key="index">
<view class="uni-list-cell" hover-class="uni-list-cell-hover" @click="goDetail(value)">
<view class="uni-media-list">
<image class="uni-media-list-logo" :src="value.cover"></image>
<view class="uni-media-list-body">
<text class="uni-media-list-text-top">{{ value.title }}</text>
<view class="uni-media-list-text-bottom">
<text class="uni-media-list-text">{{ value.author_name }}</text>
<text class="uni-media-list-text">{{ value.published_at }}</text>
</view>
</view>
</view>
</view>
</list-item>
</list-view>
</view>
<list-view style="flex: 1;" refresher-enabled=true @refresherrefresh="onRefresherrefresh"
:refresher-triggered="refresherTriggered">
<list-item class="banner" @click="bannerClick(banner)">
<image class="banner-img" :src="banner.cover"></image>
<text class="banner-title">{{ banner.title }}</text>
</list-item>
<sticky-header>
<view style="width: 100%;height:44px;background-color: #f5f5f5;flex-direction: row;justify-content:center;align-items:center;">
<button style="height: 40px;font-size: 13px;" v-for="(name,index) in th_item" @click="clickTH(index)">
{{name}}
</button>
</view>
</sticky-header>
<list-item v-for="(value, index) in listData" :key="index">
<view class="uni-list-cell" hover-class="uni-list-cell-hover" @click="goDetail(value)">
<view class="uni-media-list">
<image class="uni-media-list-logo" :src="value.cover"></image>
<view class="uni-media-list-body">
<text class="uni-media-list-text-top">{{ value.title }}</text>
<view class="uni-media-list-text-bottom">
<text class="uni-media-list-text">{{ value.author_name }}</text>
<text class="uni-media-list-text">{{ value.published_at }}</text>
</view>
</view>
</view>
</view>
</list-item>
</list-view>
</template>
<script>
type Banner = {
cover
: string | null,
title
: string | null,
post_id
: string | null
}
type Item = {
author_name
: string,
cover
: string,
id
: number,
post_id
: string,
published_at
: string,
title
: string
}
type Banner = {
cover
: string | null,
title
: string | null,
post_id
: string | null
}
type Item = {
author_name
: string,
cover
: string,
id
: number,
post_id
: string,
published_at
: string,
title
: string
}
export default {
data() {
return {
refresherTriggered: false,
banner: {} as Banner,
listData: [] as Item[],
last_id: '',
pageVisible: false
};
},
onLoad() {
this.pageVisible = true; //设这个变量是为了避免联网结束后页面已经关闭,此时还继续执行回调逻辑的问题。不是必须的
this.getBanner();
this.getList();
},
onUnload() {
this.pageVisible = false;
},
methods: {
getBanner() {
let data = {
column: 'id,post_id,title,author_name,cover,published_at' //需要的字段名
};
uni.request<Banner>({
url: 'https://unidemo.dcloud.net.cn/api/banner/36kr',
data: data,
success: data => {
if(this.pageVisible){
this.refresherTriggered = false
if (data.statusCode == 200) {
export default {
data() {
return {
th_item: ["排序", "筛选"],
refresherTriggered: false,
banner: {} as Banner,
listData: [] as Item[],
last_id: '',
pageVisible: false
};
},
onLoad() {
this.pageVisible = true; //设这个变量是为了避免联网结束后页面已经关闭,此时还继续执行回调逻辑的问题。不是必须的
this.getBanner();
this.getList();
},
onUnload() {
this.pageVisible = false;
},
methods: {
getBanner() {
let data = {
column: 'id,post_id,title,author_name,cover,published_at' //需要的字段名
};
uni.request<Banner>({
url: 'https://unidemo.dcloud.net.cn/api/banner/36kr',
data: data,
success: data => {
if (this.pageVisible) {
this.refresherTriggered = false
if (data.statusCode == 200) {
const result = data.data
if
(result != null)
{
if
(result != null)
{
this.banner = result;
}
}
}
},
fail: (e) => {
console.log('fail', e);
}
});
},
getList() {
let url = "https://unidemo.dcloud.net.cn/api/news?column=id,post_id,title,author_name,cover,published_at";
/* if (this.last_id != "") {
const minId = parseInt((this.last_id))
const time = new Date().getTime() + '';
const pageSize = 10;
url = url + "&minId=" + minId + "&time=" + time + "&pageSize=" + pageSize;
} */
}
}
},
fail: (e) => {
console.log('fail', e);
}
});
},
getList() {
let url = "https://unidemo.dcloud.net.cn/api/news?column=id,post_id,title,author_name,cover,published_at";
/* if (this.last_id != "") {
const minId = parseInt((this.last_id))
const time = new Date().getTime() + '';
const pageSize = 10;
url = url + "&minId=" + minId + "&time=" + time + "&pageSize=" + pageSize;
} */
uni.request<Item[]>({
url: url,
method:
"GET",
success: (res) => {
if(this.pageVisible)
{
if (res.statusCode == 200) {
uni.request<Item[]>({
url: url,
method:
"GET",
success: (res) => {
if (this.pageVisible)
{
if (res.statusCode == 200) {
console.log(res);
const result = res.data
if(result != null){
this.listData = result //因本接口没有更多分页数据,所以重新赋值。正常有分页的列表应该如下面push方式增加数组项
// this.listData.push(...result)
// this.last_id = this.listData[0].id + "";
}
this.refresherTriggered = false;
}
}
},
fail: (res) => {
if(this.pageVisible){
console.log('fail', res);
this.refresherTriggered = false
}
}
});
},
goDetail(e: Item) {
const detail = e;
const post_id = detail.post_id;
const cover = detail.cover;
const title = detail.title;
uni.navigateTo({
url: '/pages/template/list-news/detail/detail?post_id=' + post_id + "&cover=" + cover + "&title=" + title
});
},
bannerClick(e:Banner){
const detail = e;
const post_id = detail.post_id;
const cover = detail.cover;
const title = detail.title;
uni.navigateTo({
url: '/pages/template/list-news/detail/detail?post_id=' + post_id + "&cover=" + cover + "&title=" + title
});
},
onRefresherrefresh() {
if(this.pageVisible){
this.refresherTriggered = true
this.getBanner();
this.getList();
}
}
}
};
const result = res.data
if (result != null) {
this.listData = result //因本接口没有更多分页数据,所以重新赋值。正常有分页的列表应该如下面push方式增加数组项
// this.listData.push(...result)
// this.last_id = this.listData[0].id + "";
}
this.refresherTriggered = false;
}
}
},
fail: (res) => {
if (this.pageVisible) {
console.log('fail', res);
this.refresherTriggered = false
}
}
});
},
goDetail(e : Item) {
const detail = e;
const post_id = detail.post_id;
const cover = detail.cover;
const title = detail.title;
uni.navigateTo({
url: '/pages/template/list-news/detail/detail?post_id=' + post_id + "&cover=" + cover + "&title=" + title
});
},
bannerClick(e : Banner) {
const detail = e;
const post_id = detail.post_id;
const cover = detail.cover;
const title = detail.title;
uni.navigateTo({
url: '/pages/template/list-news/detail/detail?post_id=' + post_id + "&cover=" + cover + "&title=" + title
});
},
clickTH(index:number){
uni.showModal({
content: "点击表头项:" + index,
showCancel: false
});
},
onRefresherrefresh() {
if (this.pageVisible) {
this.refresherTriggered = true
this.getBanner();
this.getList();
}
}
}
};
</script>
<style>
.banner {
height: 360rpx;
overflow: hidden;
position: relative;
background-color: #ccc;
}
.banner {
height: 360rpx;
overflow: hidden;
position: relative;
background-color: #ccc;
}
.banner-img {
width: 100%;
}
.banner-img {
width: 100%;
}
.banner-title {
max-height: 84rpx;
overflow: hidden;
position: absolute;
left: 30rpx;
bottom: 30rpx;
width: 90%;
font-size: 32rpx;
font-weight: 400;
line-height: 42rpx;
color: white;
}
.banner-title {
max-height: 84rpx;
overflow: hidden;
position: absolute;
left: 30rpx;
bottom: 30rpx;
width: 90%;
font-size: 32rpx;
font-weight: 400;
line-height: 42rpx;
color: white;
}
.uni-media-list {
padding: 22rpx 30rpx;
box-sizing: border-box;
display: flex;
width: 100%;
flex-direction: row;
}
.uni-media-list {
padding: 22rpx 30rpx;
box-sizing: border-box;
display: flex;
width: 100%;
flex-direction: row;
}
.uni-media-list-logo {
width: 180rpx;
height: 140rpx;
}
.uni-media-list-logo {
width: 180rpx;
height: 140rpx;
}
.uni-media-list-body {
flex: 1;
padding-left: 15rpx;
justify-content: space-around;
}
.uni-media-list-body {
flex: 1;
padding-left: 15rpx;
justify-content: space-around;
}
.uni-list-content
{
background-color: #FFFFFF;
position: relative;
display: flex;
flex-direction: column;
border-bottom: 1px solid #c8c7cc;
flex: 1;
}
.uni-list-content
{
background-color: #FFFFFF;
position: relative;
display: flex;
flex-direction: column;
border-bottom: 1px solid #c8c7cc;
flex: 1;
}
.uni-media-list-text-top {
/* height: 74rpx; */
font-size: 28rpx;
lines:
2;
overflow: hidden;
}
.uni-media-list-text-top {
/* height: 74rpx; */
font-size: 28rpx;
lines:
2;
overflow: hidden;
}
.uni-media-list-text-bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.uni-media-list-text-bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.uni-media-list-text {
color: #9D9D9F;
font-size: 25rpx;
}
.uni-media-list-text {
color: #9D9D9F;
font-size: 25rpx;
}
</style>
pages/template/long-list/long-list-page.uvue
浏览文件 @
3ffd0037
...
...
@@ -2,10 +2,10 @@
<list-view ref="listView" class="list" :rebound="false" :scroll-y="true" :custom-nested-scroll="true"
@scrolltolower="loadData(null)">
<list-item class="list-item" v-for="(item, _) in dataList" :key="item.plugin_id">
<view class="list-item-icon"
v-if="item.plugin_id!=-1"
>
<view class="list-item-icon">
<image class="list-item-icon-image" :src="item.plugin_img_link"></image>
</view>
<view class="list-item-fill"
v-if="item.plugin_id!=-1"
>
<view class="list-item-fill">
<view class="flex-row">
<text class="title">{{item.plugin_name}}</text>
</view>
...
...
@@ -22,8 +22,9 @@
<text class="author">{{item.author_name}}</text>
</view>
</view>
<!-- TODO 暂时这样写才能保证 loading 在 list 底部 -->
<view v-if="item.plugin_id==-1" class="loading">
</list-item>
<list-item>
<view class="loading">
<text class="loading-text">{{loadingText}}</text>
</view>
</list-item>
...
...
@@ -81,35 +82,17 @@
} else {
return ""
}
}
,
}
},
created() {
this.insertLoadingData()
if (this.preload) {
this.loadData(null)
}
},
methods: {
// TODO 目前 list-item 不支持注释节点
// 暂时在数据末尾插入一条空数据用于显示 loading
insertLoadingData() {
const loadingData = {
plugin_id: -1,
plugin_img_link: '',
plugin_name: '',
plugin_intro: '',
score: 0,
tags: [],
update_date: '',
author_name: '',
} as ListItem
this.dataList.push(loadingData)
},
refreshData(loadComplete : (() => void) | null) {
this.dataList.length = 0
this.$currentPage = 1
this.insertLoadingData()
this.loadData(loadComplete)
},
loadData(loadComplete : (() => void) | null) {
...
...
@@ -131,9 +114,7 @@
return
}
// TODO
this.dataList.splice(this.dataList.length - 1, 0, ...responseData.data)
// this.dataList.push(...responseData.data)
this.dataList.push(...responseData.data)
if (responseData.data.length == 0) {
this.isEnded = true
...
...
@@ -254,20 +235,12 @@
}
.loading {
/* position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0; */
flex:1;
margin: -10px;
padding: 20px;
background-color: #f8f8f8;
margin-bottom: 1px;
justify-content: center;
}
.loading-text {
padding: 20px;
text-align: center;
}
</style>
uniCloud-aliyun/database/opendb-contacts.schema.json
0 → 100644
浏览文件 @
3ffd0037
{
"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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录