mirror of
https://github.com/easychen/pushdeer.git
synced 2024-12-05 08:29:22 +08:00
快应用:基本完成API对接
This commit is contained in:
parent
4232570aba
commit
03f0e531ad
@ -12,15 +12,21 @@
|
||||
"gen": "node ./scripts/gen/index.js",
|
||||
"precommit-msg": "echo '🚧 start pre-commit checks ...' && exit 0",
|
||||
"prettier": "node ./scripts/selfCloseInputTag.js && prettier --write \"src/**/*.{ux,js,json,less,scss,css,pcss,md,vue}\"",
|
||||
"prettier-watcher": "onchange '**/*.md' \"src/**/**/*.{ux,js,json,less,scss,css,pcss,md,vue}\" -- prettier --write {{changed}}"
|
||||
"prettier-watcher": "onchange '**/*.md' \"src/**/**/*.{ux,js,json,less,scss,css,pcss,md,vue}\" -- prettier --write {{changed}}",
|
||||
"fa-build": "node node_modules/webpack/bin/webpack.js --config ./node_modules/fa-toolkit/webpack.config.js",
|
||||
"fa-watch": "node node_modules/webpack/bin/webpack.js --watch --config ./node_modules/fa-toolkit/webpack.config.js",
|
||||
"fa-release": "node ./node_modules/cross-env/src/bin/cross-env.js uglifyjs=true sign=release node_modules/webpack/bin/webpack.js --config ./node_modules/fa-toolkit/webpack.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"apex-ui": "^1.9.2"
|
||||
"apex-ui": "^1.9.2",
|
||||
"dayjs": "^1.10.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@types/quickapp": "npm:quickapp-interface@^1.0.0",
|
||||
"colors": "^1.4.0",
|
||||
"cross-env": "^7.0.2",
|
||||
"fa-toolkit": "file:fa-toolkit-11.6.1-Stable.300.tgz",
|
||||
"husky": "^7.0.1",
|
||||
"less": "^4.1.1",
|
||||
"less-loader": "^10.0.1",
|
||||
@ -55,4 +61,4 @@
|
||||
"browserslist": [
|
||||
"chrome 65"
|
||||
]
|
||||
}
|
||||
}
|
@ -1,17 +1,62 @@
|
||||
<script>
|
||||
/**
|
||||
* 应用级别的配置,供所有页面公用
|
||||
*/
|
||||
/**
|
||||
* 应用级别的配置,供所有页面公用
|
||||
*/
|
||||
|
||||
const $utils = require('./helper/utils').default
|
||||
const $apis = require('./helper/apis').default
|
||||
const $utils = require('./helper/utils').default
|
||||
const $apis = require('./helper/apis').default
|
||||
const $storage = require('@system.storage')
|
||||
|
||||
/* @desc: 注入方法至全局 global,以便页面调用 */
|
||||
const hook2global = global.__proto__ || global
|
||||
hook2global.$utils = $utils
|
||||
hook2global.$apis = $apis
|
||||
console.log('app: create channel');
|
||||
const appInitC = new BroadcastChannel('init');
|
||||
|
||||
export default {
|
||||
onCreate() {}
|
||||
}
|
||||
/* @desc: 注入方法至全局 global,以便页面调用 */
|
||||
const hook2global = Object.getPrototypeOf(global) || global;
|
||||
hook2global.$utils = $utils
|
||||
hook2global.API = $apis
|
||||
|
||||
const _promiseFactory = (pointer, params = {}) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
params = Object.assign({
|
||||
success: (data) => { resolve(data); },
|
||||
fail: (err, code) => { reject(err, code) }
|
||||
}, params);
|
||||
pointer(params);
|
||||
});
|
||||
}
|
||||
hook2global.promiseFactory = _promiseFactory;
|
||||
|
||||
const userinfoFromToken = async (token) => {
|
||||
$apis.setToken(token)
|
||||
let userinfo = await $apis.userInfo()
|
||||
userinfo.token = token
|
||||
hook2global.$userinfo = userinfo
|
||||
_promiseFactory($storage.set, { key: 'token', value: token })
|
||||
appInitC.postMessage(1)
|
||||
appInitC.close()
|
||||
}
|
||||
|
||||
export default {
|
||||
onCreate() {
|
||||
console.log('app: init oncreate');
|
||||
appInitC.onmessage = ({ data: token }) => {
|
||||
console.log('app: login success, data=', JSON.stringify(token));
|
||||
userinfoFromToken(token)
|
||||
}
|
||||
(async () => {
|
||||
let token = await _promiseFactory($storage.get, { key: 'token' })
|
||||
.catch((data, code) => {
|
||||
console.warn(`get token from storage fail, code = ${code}`)
|
||||
})
|
||||
console.log(`app: get token = ${token} from storage success`)
|
||||
if (token.length === 0) {
|
||||
console.log('app: init token.length==0, send init message');
|
||||
appInitC.postMessage(0)
|
||||
return
|
||||
}
|
||||
userinfoFromToken(token)
|
||||
})()
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
BIN
quickapp/src/assets/images/trash.png
Normal file
BIN
quickapp/src/assets/images/trash.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -6,7 +6,7 @@ import $utils from './utils'
|
||||
|
||||
const TIMEOUT = 20000
|
||||
|
||||
Promise.prototype.finally = function(callback) {
|
||||
Promise.prototype.finally = function (callback) {
|
||||
const P = this.constructor
|
||||
return this.then(
|
||||
value => P.resolve(callback()).then(() => value),
|
||||
@ -25,24 +25,21 @@ function fetchPromise(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$fetch
|
||||
.fetch({
|
||||
url: params.url,
|
||||
method: params.method,
|
||||
data: params.data
|
||||
...params,
|
||||
responseType: 'json',
|
||||
})
|
||||
.then(response => {
|
||||
const result = response.data
|
||||
const content = JSON.parse(result.data)
|
||||
/* @desc: 可跟具体不同业务接口数据,返回你所需要的部分,使得使用尽可能便捷 */
|
||||
content.success ? resolve(content.value) : resolve(content.message)
|
||||
.then(res => {
|
||||
// console.log('ajax then', res)
|
||||
const data = res.data.data
|
||||
data.code === 0 ?
|
||||
resolve(data.content)
|
||||
: reject({ code: data.code, msg: data.error })
|
||||
})
|
||||
.catch((error, code) => {
|
||||
console.log(`🐛 request fail, code = ${code}`)
|
||||
reject(error)
|
||||
})
|
||||
.finally(() => {
|
||||
console.log(`✔️ request @${params.url} has been completed.`)
|
||||
resolve()
|
||||
.catch(err => {
|
||||
console.warn('ajax catch', err.data, err.code);
|
||||
reject({ msg: err.data, code: err.code })
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@ -66,20 +63,20 @@ function requestHandle(params, timeout = TIMEOUT) {
|
||||
}
|
||||
|
||||
export default {
|
||||
post: function(url, params) {
|
||||
post: function (url, params) {
|
||||
return requestHandle({
|
||||
method: 'post',
|
||||
url: url,
|
||||
data: params
|
||||
})
|
||||
},
|
||||
get: function(url, params) {
|
||||
get: function (url, params) {
|
||||
return requestHandle({
|
||||
method: 'get',
|
||||
url: $utils.queryString(url, params)
|
||||
})
|
||||
},
|
||||
put: function(url, params) {
|
||||
put: function (url, params) {
|
||||
return requestHandle({
|
||||
method: 'put',
|
||||
url: url,
|
||||
|
75
quickapp/src/helper/apis.js
Normal file
75
quickapp/src/helper/apis.js
Normal file
@ -0,0 +1,75 @@
|
||||
import $ajax from './ajax'
|
||||
|
||||
/**
|
||||
* @desc 在实际开发中,您可以将 baseUrl 替换为您的请求地址前缀;
|
||||
*
|
||||
* 已将 $apis 挂载在 global,您可以通过如下方式,进行调用:
|
||||
* $apis.example.getApi().then().catch().finally()
|
||||
*
|
||||
* 备注:如果您不需要发起请求,删除 apis 目录,以及 app.ux 中引用即可;
|
||||
*/
|
||||
const baseUrl = 'https://pushdeer.qiyanghong.cn:5443/'
|
||||
|
||||
let token = ""
|
||||
|
||||
function to(promise) {
|
||||
return promise
|
||||
.catch(err => { $utils.showToast(err) });
|
||||
}
|
||||
|
||||
export default {
|
||||
setToken(t) {
|
||||
token = t
|
||||
},
|
||||
login() {
|
||||
return to($ajax.get(`${baseUrl}login/fake`).then(res => res.token))
|
||||
},
|
||||
userInfo() {
|
||||
return to($ajax.post(`${baseUrl}user/info`, { token }))
|
||||
},
|
||||
// device
|
||||
deviceReg(name, device_id) {
|
||||
return to($ajax.post(`${baseUrl}device/reg`, { token, is_clip: 1, name, device_id }))
|
||||
.then(res => res.devices)
|
||||
},
|
||||
deviceList() {
|
||||
return to($ajax.post(`${baseUrl}device/list`, { token }))
|
||||
.then(res => res.devices)
|
||||
},
|
||||
deviceRename(id, name) {
|
||||
return to($ajax.post(`${baseUrl}device/rename`, { token, id, name }))
|
||||
},
|
||||
deviceRemove(id) {
|
||||
return to($ajax.post(`${baseUrl}device/remove`, { token, id }))
|
||||
},
|
||||
// key
|
||||
keyGen() {
|
||||
return to($ajax.post(`${baseUrl}key/gen`, { token }))
|
||||
.then(res => res.keys)
|
||||
},
|
||||
keyList() {
|
||||
return to($ajax.post(`${baseUrl}key/list`, { token }))
|
||||
.then(res => res.keys)
|
||||
},
|
||||
keyRename(id, name) {
|
||||
return to($ajax.post(`${baseUrl}key/rename`, { token, id, name }))
|
||||
},
|
||||
keyRegen(id) {
|
||||
return to($ajax.post(`${baseUrl}key/regen`, { token, id }))
|
||||
},
|
||||
keyRemove(id) {
|
||||
return to($ajax.post(`${baseUrl}key/remove`, { token, id }))
|
||||
},
|
||||
// message
|
||||
messageList() {
|
||||
return to($ajax.post(`${baseUrl}message/list`, { token }))
|
||||
.then(res => res.messages)
|
||||
// [{"id":3,"uid":"1","text":"\u8fd9\u662f\u4ec0\u4e48\u54401111","desp":"","type":"markdown","created_at":"2021-12-22T12:09:46.000000Z"},{"id":2,"uid":"1","text":"\u8fd9\u662f\u4ec0\u4e48\u5440234","desp":"","type":"markdown","created_at":"2021-12-22T12:08:32.000000Z"}]
|
||||
},
|
||||
messagePush(text, desp, type) {
|
||||
return to($ajax.post(`${baseUrl}message/push`, { token, text, desp, type }))
|
||||
},
|
||||
messageRemove(id) {
|
||||
return to($ajax.post(`${baseUrl}message/remove`, { token, id }))
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import $ajax from '../ajax'
|
||||
|
||||
/**
|
||||
* @desc 在实际开发中,您可以将 baseUrl 替换为您的请求地址前缀;
|
||||
*
|
||||
* 已将 $apis 挂载在 global,您可以通过如下方式,进行调用:
|
||||
* $apis.example.getApi().then().catch().finally()
|
||||
*
|
||||
* 备注:如果您不需要发起请求,删除 apis 目录,以及 app.ux 中引用即可;
|
||||
*/
|
||||
const baseUrl = 'https://api.exampel.com/'
|
||||
|
||||
export default {
|
||||
getApi(data) {
|
||||
return $ajax.get(`${baseUrl}your-project-api`, data)
|
||||
},
|
||||
postOtherApi(data) {
|
||||
return $ajax.post(`${baseUrl}your-project-api`, data)
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
/**
|
||||
* 导出 apis 下目录的所有接口
|
||||
*/
|
||||
const files = require.context('.', true, /\.js/)
|
||||
const modules = {}
|
||||
|
||||
files.keys().forEach(key => {
|
||||
if (key === './index.js') {
|
||||
return
|
||||
}
|
||||
modules[key.replace(/(^\.\/|\.js$)/g, '')] = files(key).default
|
||||
})
|
||||
|
||||
export default modules
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"package": "com.pushdeer.app",
|
||||
"package": "dev.pushdeer.app",
|
||||
"name": "pushdeer",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": 1,
|
||||
@ -17,6 +17,12 @@
|
||||
},
|
||||
{
|
||||
"name": "system.fetch"
|
||||
},
|
||||
{
|
||||
"name": "system.storage"
|
||||
},
|
||||
{
|
||||
"name": "system.device"
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
@ -24,7 +30,6 @@
|
||||
"origin": "*"
|
||||
}
|
||||
],
|
||||
"template/official": "demo-template",
|
||||
"config": {
|
||||
"logLevel": "debug"
|
||||
},
|
||||
@ -37,6 +42,12 @@
|
||||
"pages/Home": {
|
||||
"component": "index",
|
||||
"launchMode": "singleTask"
|
||||
},
|
||||
"pages/component": {
|
||||
"component": "devpage"
|
||||
},
|
||||
"pages/swipe":{
|
||||
"component": "index"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1,31 +0,0 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<text class="title">{{ title }}</text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: {
|
||||
title: "Hello World. Quickapp Component."
|
||||
},
|
||||
|
||||
props: [],
|
||||
|
||||
onInit() {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
||||
@import './../../assets/styles/style.less';
|
||||
|
||||
.wrapper {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
width: 100%;
|
||||
}
|
||||
.title {
|
||||
text-align: center;
|
||||
color: #212121;
|
||||
}
|
||||
</style>
|
@ -1,4 +1,5 @@
|
||||
<import name="dev-card" src="./card"></import>
|
||||
<import name="swipe-item" src="../swipeItem"></import>
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<!-- <text class="title">device</text>
|
||||
@ -9,50 +10,99 @@
|
||||
</div>
|
||||
<list style="width: 80%">
|
||||
<list-item type="devitem" for="{{ dev in devs}}">
|
||||
<dev-card dev-obj="{{ dev }}" idx="{{ $idx }}"></dev-card>
|
||||
<swipe-item>
|
||||
<dev-card
|
||||
slot="content"
|
||||
dev-obj="{{ dev }}"
|
||||
idx="{{ $idx }}"
|
||||
></dev-card>
|
||||
<div
|
||||
slot="right"
|
||||
style="height: 60px;width: 100px;padding: 0 20px;justify-content: center;"
|
||||
@click="handleDeleteClick($idx)"
|
||||
>
|
||||
<image src="/assets/images/trash.png"></image>
|
||||
</div>
|
||||
</swipe-item>
|
||||
</list-item>
|
||||
</list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: {
|
||||
devs: [
|
||||
{ icon: "/assets/images/device-ipad.svg", name: "Easy’s iPad(当前设备)" },
|
||||
{ icon: "/assets/images/device-ipad.svg", name: "备用机iPhone2" },
|
||||
],
|
||||
},
|
||||
import device from '@system.device'
|
||||
|
||||
onPlusBtnClick() {
|
||||
// $utils.showToast('aaaaa')
|
||||
this.devs.push({ icon: "/assets/images/device-iphone.svg", name: "备用机iPhone" + (this.devs.length + 1) })
|
||||
},
|
||||
|
||||
onInit() {
|
||||
console.log('device', 'init')
|
||||
const devIcon = {
|
||||
"ios": "/assets/images/device-iphone.png",
|
||||
"default": "/assets/images/device-iphone.png",
|
||||
}
|
||||
|
||||
const handleDevResult = (data) => data.map((item) => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
icon: item.type in devIcon ? devIcon[item.type] : devIcon["default"],
|
||||
}
|
||||
})
|
||||
|
||||
export default {
|
||||
data: {
|
||||
devs: [],
|
||||
},
|
||||
|
||||
async onPlusBtnClick() {
|
||||
try {
|
||||
let devId = await promiseFactory(device.getDeviceId, {})
|
||||
.then(res => res.deviceId)
|
||||
let devList = await API.deviceReg($userinfo.name + '的手机', devId)
|
||||
// console.log('devList: ', JSON.stringify(devList));
|
||||
this.devs = handleDevResult(devList)
|
||||
} catch (e) {
|
||||
$utils.showToast(e.name + ':' + e.message)
|
||||
}
|
||||
},
|
||||
|
||||
async handleDeleteClick(idx) {
|
||||
const id = this.devs[idx].id
|
||||
console.log(`device: del item: idx=${idx}, id=${id}`);
|
||||
this.devs.splice(idx)
|
||||
API.deviceRemove(id)
|
||||
},
|
||||
|
||||
onInit() {
|
||||
console.log('device', 'init');
|
||||
(async () => {
|
||||
let devList = await API.deviceList()
|
||||
// console.log('devList: ', JSON.stringify(devList));
|
||||
this.devs = handleDevResult(devList)
|
||||
// console.log('devs: ', JSON.stringify(this.devs));
|
||||
// [{"uid":"1","is_clip":0,"device_id":"f787bbf3-fffd-a2d7-fef9-716ff1bf1809","name":"新设备","id":1,"type":"ios"},{"uid":"1","is_clip":1,"device_id":"f787bbf3-fffd-a2d7-fef9-716ff1bf1809","name":"easychen+new","id":2,"type":"ios"}]
|
||||
})()
|
||||
},
|
||||
onReady() {
|
||||
console.log('device', 'onready')
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import '../../../assets/styles/style.less';
|
||||
@import '../../../assets/styles/style.less';
|
||||
|
||||
.wrapper {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 84px;
|
||||
.wrapper {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 84px;
|
||||
|
||||
.header {
|
||||
margin-bottom: 24px;
|
||||
width: 80%;
|
||||
justify-content: space-between;
|
||||
.header {
|
||||
margin-bottom: 24px;
|
||||
width: 80%;
|
||||
justify-content: space-between;
|
||||
|
||||
text {
|
||||
font-size: 48px;
|
||||
color: #000000;
|
||||
text {
|
||||
font-size: 48px;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -2,116 +2,133 @@
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<image style="height: 80px" src="/assets/images/avatar.svg" />
|
||||
<text class="name" @click="onKeyNameClick">{{ key.name }}</text>
|
||||
<input
|
||||
id="keyname"
|
||||
class="name"
|
||||
enterkeytype="go"
|
||||
@enterkeyclick="onKeynameEdited"
|
||||
value="{{ key.name }}"
|
||||
></input>
|
||||
<image style="height: 36px" src="/assets/images/calander.svg" />
|
||||
<text class="date">{{ key.date }}</text>
|
||||
</div>
|
||||
<text class="value">{{ key.value }} </text>
|
||||
<text class="value">{{ key.value }}</text>
|
||||
<!-- <div class="divider"></div> -->
|
||||
<image class="divider" src="/assets/images/divider.png"></image>
|
||||
<div class="footer">
|
||||
<text style="color: #3b4789; border-color: #3b4789">重置</text>
|
||||
<text
|
||||
style="color: #3b4789; border-color: #3b4789"
|
||||
@click="onResetBtnClick"
|
||||
>
|
||||
重置
|
||||
</text>
|
||||
<text
|
||||
style="color: #ffffff; background-color: #3b4789"
|
||||
@click="onCopyBtnClick"
|
||||
>复制</text
|
||||
>
|
||||
复制
|
||||
</text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import clipboard from '@system.clipboard'
|
||||
export default {
|
||||
import clipboard from '@system.clipboard'
|
||||
export default {
|
||||
|
||||
props: ['key', 'idx'],
|
||||
props: ['key', 'idx'],
|
||||
|
||||
onKeyNameClick() {
|
||||
$utils.showToast('改名功能待实现')
|
||||
},
|
||||
onKeynameEdited({ value: newname }) {
|
||||
this.$element('keyname').focus({ focus: false })
|
||||
this.$emit('keyRename', { idx: this.idx, newname })
|
||||
},
|
||||
|
||||
onCopyBtnClick() {
|
||||
clipboard.set({
|
||||
text: this.key.value,
|
||||
success: () => {
|
||||
$utils.showToast('key已经复制到剪贴板')
|
||||
}
|
||||
})
|
||||
},
|
||||
onResetBtnClick() {
|
||||
this.$emit('keyReset', { idx: this.idx });
|
||||
},
|
||||
|
||||
onInit() {
|
||||
// console.log('key', this.key, this.idx)
|
||||
// console.log('card', 'name', this.devObj.name)
|
||||
onCopyBtnClick() {
|
||||
clipboard.set({
|
||||
text: this.key.value,
|
||||
success: () => {
|
||||
$utils.showToast('key已经复制到剪贴板')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onInit() {
|
||||
// console.log('key', this.key, this.idx)
|
||||
// console.log('card', 'name', this.devObj.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@primary-color: #3b4789;
|
||||
@secondry-color: #d6d6d6;
|
||||
@font-color: #a7a7a7;
|
||||
@primary-color: #3b4789;
|
||||
@secondry-color: #d6d6d6;
|
||||
@font-color: #a7a7a7;
|
||||
|
||||
.card {
|
||||
flex-direction: column;
|
||||
border-color: @primary-color;
|
||||
border-radius: 16px;
|
||||
border-width: 3px;
|
||||
padding: 32px;
|
||||
margin: 24px 0;
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
/* justify-content: center;
|
||||
align-items: center; */
|
||||
|
||||
.header {
|
||||
align-items: flex-end;
|
||||
|
||||
.date {
|
||||
font-size: 24px;
|
||||
color: @font-color;
|
||||
}
|
||||
|
||||
.name {
|
||||
color: @primary-color;
|
||||
font-size: 36px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
margin: 48px 0;
|
||||
padding: 16px;
|
||||
font-size: 24px;
|
||||
border-width: 2px;
|
||||
border-radius: 8px;
|
||||
border-color: @secondry-color;
|
||||
color: @font-color;
|
||||
lines: 1;
|
||||
}
|
||||
|
||||
.divider {
|
||||
.card {
|
||||
flex-direction: column;
|
||||
border-color: @primary-color;
|
||||
border-radius: 16px;
|
||||
border-width: 3px;
|
||||
padding: 32px;
|
||||
margin: 24px 0;
|
||||
background-color: #ffffff;
|
||||
width: 100%;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
/* justify-content: center;
|
||||
align-items: center; */
|
||||
|
||||
.footer {
|
||||
justify-content: space-between;
|
||||
.header {
|
||||
align-items: flex-end;
|
||||
|
||||
text {
|
||||
font-size: 30px;
|
||||
padding: 16px 48px;
|
||||
.date {
|
||||
font-size: 24px;
|
||||
color: @font-color;
|
||||
}
|
||||
|
||||
.name {
|
||||
color: @primary-color;
|
||||
font-size: 36px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
margin: 48px 0;
|
||||
padding: 16px;
|
||||
font-size: 24px;
|
||||
border-width: 2px;
|
||||
border-radius: 16px;
|
||||
border-radius: 8px;
|
||||
border-color: @secondry-color;
|
||||
color: @font-color;
|
||||
lines: 1;
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 100%;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
justify-content: space-between;
|
||||
|
||||
text {
|
||||
font-size: 30px;
|
||||
padding: 16px 48px;
|
||||
border-width: 2px;
|
||||
border-radius: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* .wrapper {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.title {
|
||||
text-align: center;
|
||||
color: #212121;
|
||||
} */
|
||||
/* .wrapper {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.title {
|
||||
text-align: center;
|
||||
color: #212121;
|
||||
} */
|
||||
</style>
|
||||
|
@ -1,4 +1,5 @@
|
||||
<import name="key-card" src="./card"></import>
|
||||
<import name="swipe-item" src="../swipeItem"></import>
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<!-- <text class="title">device</text>
|
||||
@ -9,52 +10,107 @@
|
||||
</div>
|
||||
<list style="width: 80%">
|
||||
<list-item type="keyitem" for="{{ key in keys}}">
|
||||
<key-card key="{{ key }}" idx="{{ $idx }}"></key-card>
|
||||
<swipe-item>
|
||||
<key-card
|
||||
slot="content"
|
||||
key="{{ key }}"
|
||||
idx="{{ $idx }}"
|
||||
@key-reset="onKeyReset"
|
||||
@key-rename="onKeyRename"
|
||||
></key-card>
|
||||
<div
|
||||
slot="right"
|
||||
style="height: 60px;width: 100px;justify-content: center;"
|
||||
@click="onDelBtnClick($idx)"
|
||||
>
|
||||
<image src="/assets/images/trash.png"></image>
|
||||
</div>
|
||||
</swipe-item>
|
||||
</list-item>
|
||||
</list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: {
|
||||
keys: [
|
||||
{ name: "Default", value: "PDU1DSE543JDZpq8Lx2gsSE543JD…", date: "2021/12/01" },
|
||||
{ name: "点击改Key名", value: "PDU1DSE543JDZpq8Lx2gsSE543JD…", date: "2021/12/01" },
|
||||
],
|
||||
},
|
||||
import dayjs from 'dayjs'
|
||||
const handleKeyResult = (data) => data.map((item) => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
value: item.key,
|
||||
date: dayjs(item.created_at).format('YYYY/MM/DD'),
|
||||
}
|
||||
})
|
||||
export default {
|
||||
data: {
|
||||
keys: [],
|
||||
},
|
||||
|
||||
onPlusBtnClick() {
|
||||
// $utils.showToast('aaaaa')
|
||||
this.keys.push(
|
||||
{ name: "Default", value: "PDU1DSE543JDZpq8Lx2gsSE543JD…", date: "2021/12/01" },
|
||||
)
|
||||
},
|
||||
async onPlusBtnClick() {
|
||||
let keyList = await API.keyGen()
|
||||
this.keys = handleKeyResult(keyList)
|
||||
},
|
||||
|
||||
onInit() {
|
||||
console.log('key', 'init', this.keys)
|
||||
async handleRename(e) {
|
||||
console.log(JSON.stringify(e));
|
||||
},
|
||||
|
||||
async onDelBtnClick(idx) {
|
||||
const id = this.keys[idx].id
|
||||
console.log(`key: del item: idx=${idx}, id=${id}`);
|
||||
this.keys.splice(idx)
|
||||
API.keyRemove(id)
|
||||
},
|
||||
|
||||
async onKeyReset({ detail: { idx } }) {
|
||||
console.log(`key: onKeyReset: idx=${idx}`);
|
||||
const id = this.keys[idx].id
|
||||
let result = await API.keyRegen(id)
|
||||
if (!result) { return }
|
||||
let keyList = await API.keyList()
|
||||
this.keys = handleKeyResult(keyList)
|
||||
},
|
||||
|
||||
async onKeyRename({ detail: { idx, newname } }) {
|
||||
const id = this.keys[idx].id
|
||||
console.log(`key: onKeyRename: idx=${idx}, newname=${newname}`);
|
||||
let result = await API.keyRename(id, newname)
|
||||
if (result) {
|
||||
this.keys[idx].name = newname
|
||||
}
|
||||
},
|
||||
|
||||
onInit() {
|
||||
(async () => {
|
||||
let keyList = await API.keyList()
|
||||
// console.log('devList: ', JSON.stringify(devList));
|
||||
this.keys = handleKeyResult(keyList)
|
||||
console.log('keys: ', JSON.stringify(this.keys));
|
||||
})().catch(e => {
|
||||
console.log(e);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import '../../../assets/styles/style.less';
|
||||
@import '../../../assets/styles/style.less';
|
||||
|
||||
.wrapper {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 84px;
|
||||
.wrapper {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 84px;
|
||||
|
||||
.header {
|
||||
margin-bottom: 24px;
|
||||
width: 80%;
|
||||
justify-content: space-between;
|
||||
.header {
|
||||
margin-bottom: 24px;
|
||||
width: 80%;
|
||||
justify-content: space-between;
|
||||
|
||||
text {
|
||||
font-size: 48px;
|
||||
color: #000000;
|
||||
text {
|
||||
font-size: 48px;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,6 +1,4 @@
|
||||
<import name="msg-text" src="./msg-text"></import>
|
||||
<import name="msg-image" src="./msg-image"></import>
|
||||
<import name="msg-markdown" src="./msg-markdown"></import>
|
||||
<import name="msg-card" src="./msg-card"></import>
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
@ -11,9 +9,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div if="{{!collapsed}}" class="pushmsg-region">
|
||||
<textarea class="textarea" @change="onTextAreaChange">{{
|
||||
input
|
||||
}}</textarea>
|
||||
<textarea class="textarea" @change="onTextAreaChange">{{input}}</textarea>
|
||||
<text class="pushbtn" @click="onPushBtnClick">推送测试</text>
|
||||
</div>
|
||||
<list>
|
||||
@ -22,108 +18,116 @@
|
||||
if="{{supportType.includes(msg.type)}}"
|
||||
for="{{ msg in msgs}}"
|
||||
>
|
||||
<component is="{{ 'msg-'+msg.type}}" msg="{{ msg}}"></component>
|
||||
<msg-card msg="{{ msg}}"></msg-card>
|
||||
|
||||
</list-item>
|
||||
</list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: {
|
||||
collapsed: false,
|
||||
supportType: ['text', 'image', 'markdown'],
|
||||
input: '',
|
||||
msgs: [
|
||||
{
|
||||
name: "Default", created_at: "5分钟前", type: "text",
|
||||
text: `纯文本的效果。长文字需要自动换行。
|
||||
长文字需要自动换行。行间距24。
|
||||
长按可以复制文本内容。左滑显示删除。`
|
||||
},
|
||||
{
|
||||
name: "推送Key的名字", created_at: "5分钟前", type: "markdown",
|
||||
text: `<p>支持Markdown语法。比如可以插入<a href="https://www.baidu.com/">链接</a> ,
|
||||
点击后使用系统浏览器直接打开。</p>`
|
||||
},
|
||||
{
|
||||
name: "Default", created_at: "5分钟前", type: "image",
|
||||
text: `https://wikipic.ftqq.com/wp-content/uploads/2021/08/jessy-smith-zFOm6KzA-7g-unsplash.jpg`
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
onArrowBtnClick() {
|
||||
this.collapsed = !this.collapsed
|
||||
},
|
||||
onTextAreaChange(e) {
|
||||
// 只能在change事件里取值,不知道作者怎么想的。。。
|
||||
this.input = e.text
|
||||
},
|
||||
onPushBtnClick() {
|
||||
if (this.input.length == 0) {
|
||||
$utils.showToast("消息内容为空")
|
||||
return
|
||||
import dayjs from 'dayjs'
|
||||
var md = require('markdown-it')();
|
||||
const handleMessageResult = (data) => data.map((item) => {
|
||||
const created_at = dayjs(item.created_at)
|
||||
const diffMinute = dayjs().diff(created_at, 'm')
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.pushkey_name,
|
||||
type: item.type,
|
||||
text: item.type === 'markdown' ? md.render(item.text) : item.text,
|
||||
desp: item.desp,
|
||||
created_at: diffMinute >= 0 && diffMinute <= 10 ? `${diffMinute}分钟前` : created_at.format('YYYY/MM/DD hh:mm:ss'),
|
||||
}
|
||||
console.log('message', 'onPushBtnClick', this.input)
|
||||
this.msgs.unshift({ name: "本设备", created_at: "刚刚", type: "text", text: this.input })
|
||||
this.input = ""
|
||||
},
|
||||
}).reverse()
|
||||
|
||||
onInit() {
|
||||
console.log('message', 'init')
|
||||
export default {
|
||||
data: {
|
||||
collapsed: false,
|
||||
supportType: ['text', 'image', 'markdown'],
|
||||
input: '',
|
||||
msgs: [],
|
||||
},
|
||||
|
||||
onArrowBtnClick() {
|
||||
this.collapsed = !this.collapsed
|
||||
},
|
||||
onTextAreaChange(e) {
|
||||
// 只能在change事件里取值,不知道作者怎么想的。。。
|
||||
this.input = e.text
|
||||
},
|
||||
onPushBtnClick() {
|
||||
if (this.input.length == 0) {
|
||||
$utils.showToast("消息内容为空")
|
||||
return
|
||||
}
|
||||
console.log('message', 'onPushBtnClick', this.input)
|
||||
this.msgs.unshift({ name: "本设备", created_at: "刚刚", type: "text", text: this.input })
|
||||
this.input = ""
|
||||
},
|
||||
|
||||
onInit() {
|
||||
console.log('message', 'init');
|
||||
(async () => {
|
||||
let messageList = await API.messageList()
|
||||
console.log('messageList: ', JSON.stringify(messageList));
|
||||
this.msgs = handleMessageResult(messageList)
|
||||
console.log('msgs: ', JSON.stringify(this.msgs));
|
||||
})().catch(e => {
|
||||
console.log(e);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import '../../../assets/styles/style.less';
|
||||
@import '../../../assets/styles/style.less';
|
||||
|
||||
.wrapper {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 84px;
|
||||
.wrapper {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 84px;
|
||||
|
||||
.header {
|
||||
margin-bottom: 24px;
|
||||
width: 80%;
|
||||
justify-content: space-between;
|
||||
flex-shrink: 0;
|
||||
.header {
|
||||
margin-bottom: 24px;
|
||||
width: 80%;
|
||||
justify-content: space-between;
|
||||
flex-shrink: 0;
|
||||
|
||||
text {
|
||||
font-size: 48px;
|
||||
color: #000000;
|
||||
text {
|
||||
font-size: 48px;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
.pushmsg-region {
|
||||
margin: 24px 0;
|
||||
width: 80%;
|
||||
height: 30%;
|
||||
flex-direction: column;
|
||||
/* justify-content: space-between; */
|
||||
align-items: flex-start;
|
||||
|
||||
.textarea {
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
padding: 24px;
|
||||
font-size: 32px;
|
||||
border-color: @primary-color;
|
||||
border-width: 3px;
|
||||
border-radius: 8px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.pushbtn {
|
||||
color: #ffffff;
|
||||
font-size: 30px;
|
||||
margin-top: 48px;
|
||||
padding: 24px;
|
||||
border-radius: 16px;
|
||||
background-color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pushmsg-region {
|
||||
margin: 24px 0;
|
||||
width: 80%;
|
||||
height: 30%;
|
||||
flex-direction: column;
|
||||
/* justify-content: space-between; */
|
||||
align-items: flex-start;
|
||||
|
||||
.textarea {
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
padding: 24px;
|
||||
font-size: 32px;
|
||||
border-color: @primary-color;
|
||||
border-width: 3px;
|
||||
border-radius: 8px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.pushbtn {
|
||||
color: #ffffff;
|
||||
font-size: 30px;
|
||||
margin-top: 48px;
|
||||
padding: 24px;
|
||||
border-radius: 16px;
|
||||
background-color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
58
quickapp/src/pages/component/Message/msg-card.ux
Normal file
58
quickapp/src/pages/component/Message/msg-card.ux
Normal file
@ -0,0 +1,58 @@
|
||||
<import name="msg-header" src="./msg-header"></import>
|
||||
<import name="swipe-item" src="../swipeItem"></import>
|
||||
<template>
|
||||
<div class="card">
|
||||
<msg-header title="{{msg.name +' · '+ msg.created_at}}"></msg-header>
|
||||
|
||||
<text if="{{msg.type === 'text'}}" class="text">{{ msg.text }}</text>
|
||||
|
||||
<div if="{{msg.type ==='markdown'}}" class="text">
|
||||
<richtext type="html">{{msg.text}}</richtext>
|
||||
</div>
|
||||
|
||||
<image if="{{msg.type ==='image'}}" class="image" src="{{msg.text}}"></image>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import clipboard from '@system.clipboard'
|
||||
export default {
|
||||
|
||||
props: ['msg'],
|
||||
|
||||
onInit() {
|
||||
// console.log('msg-text',this.msg)
|
||||
if (this.msg.type !== 'image' && this.msg.desp.length > 0) {
|
||||
this.msg.text += "\n" + this.msg.desp
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import '../../../assets/styles/style.less';
|
||||
|
||||
.card {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
margin: 24px 0;
|
||||
width: 100%;
|
||||
|
||||
.text {
|
||||
width: 80%;
|
||||
margin-top: 32px;
|
||||
color: #535353;
|
||||
font-size: 24px;
|
||||
line-height: 48px;
|
||||
padding: 24px;
|
||||
border-width: 2px;
|
||||
border-radius: 8px;
|
||||
border-color: @primary-color;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,34 +0,0 @@
|
||||
<import name="msg-header" src="./msg-header"></import>
|
||||
<template>
|
||||
<div class="card">
|
||||
<msg-header title="{{msg.name +' · '+ msg.created_at}}"></msg-header>
|
||||
<image class="image" src="{{msg.text}}"></image>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import clipboard from '@system.clipboard'
|
||||
export default {
|
||||
|
||||
props: ['msg'],
|
||||
|
||||
onInit() {
|
||||
// console.log('msg-text',this.msg)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import '../../../assets/styles/style.less';
|
||||
|
||||
.card {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
margin: 24px 0;
|
||||
width: 100%;
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,44 +0,0 @@
|
||||
<import name="msg-header" src="./msg-header"></import>
|
||||
<template>
|
||||
<div class="card">
|
||||
<msg-header title="{{msg.name +' · '+ msg.created_at}}"></msg-header>
|
||||
<div class="markdown">
|
||||
<richtext type="html" >{{msg.text}}</richtext>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import clipboard from '@system.clipboard'
|
||||
export default {
|
||||
|
||||
props: ['msg'],
|
||||
|
||||
onInit() {
|
||||
// console.log('msg-text',this.msg)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import '../../../assets/styles/style.less';
|
||||
|
||||
.card {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
margin: 24px 0;
|
||||
width: 100%;
|
||||
|
||||
.markdown {
|
||||
width: 80%;
|
||||
margin-top: 32px;
|
||||
color: #535353;
|
||||
font-size: 24px;
|
||||
line-height: 48px;
|
||||
padding: 24px;
|
||||
border-width: 2px;
|
||||
border-radius: 8px;
|
||||
border-color: @primary-color;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,42 +0,0 @@
|
||||
<import name="msg-header" src="./msg-header"></import>
|
||||
<template>
|
||||
<div class="card">
|
||||
<msg-header title="{{msg.name +' · '+ msg.created_at}}"></msg-header>
|
||||
<text class="text">{{ msg.text }}</text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import clipboard from '@system.clipboard'
|
||||
export default {
|
||||
|
||||
props: ['msg'],
|
||||
|
||||
onInit() {
|
||||
// console.log('msg-text',this.msg)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import '../../../assets/styles/style.less';
|
||||
|
||||
.card {
|
||||
.flex-box-mixins(column, flex-start, center);
|
||||
margin: 24px 0;
|
||||
width: 100%;
|
||||
|
||||
.text {
|
||||
width: 80%;
|
||||
margin-top: 32px;
|
||||
color: #535353;
|
||||
font-size: 24px;
|
||||
line-height: 48px;
|
||||
padding: 24px;
|
||||
border-width: 2px;
|
||||
border-radius: 8px;
|
||||
border-color: @primary-color;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
</style>
|
163
quickapp/src/pages/component/devpage.ux
Normal file
163
quickapp/src/pages/component/devpage.ux
Normal file
@ -0,0 +1,163 @@
|
||||
<!-- <import name="button" src="apex-ui/components/button/index"></import> -->
|
||||
<template>
|
||||
<!-- template里只能有一个根节点 -->
|
||||
<div class="wrapper">
|
||||
<list style="width: 50%">
|
||||
<list-item type="devitem" for="{{ s in btns}}">
|
||||
<text style="width: 100%;" @click="{{handleBtnClick($idx)}}">
|
||||
{{s.label}}
|
||||
</text>
|
||||
</list-item>
|
||||
</list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import device from '@system.device'
|
||||
export default {
|
||||
// 页面级组件的数据模型,影响传入数据的覆盖机制:private内定义的属性不允许被覆盖
|
||||
private: {
|
||||
btns: [
|
||||
{
|
||||
label: '获取userinfo', handle: async () => {
|
||||
let userinfo = await API.userInfo()
|
||||
console.log(`userinfo is `, userinfo)
|
||||
// {"updated_at":"2022-01-30T15:48:56.000000Z","level":1,"name":"easychen+new","created_at":"2022-01-30T15:48:56.000000Z","id":1,"apple_id":"theid999","email":"easychen+new@gmail.com"}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '获取deviceID', handle: async () => {
|
||||
let devId = await promiseFactory(device.getDeviceId, {})
|
||||
.then(res => res.deviceId)
|
||||
console.log(`deviceId is `, devId);
|
||||
}
|
||||
},
|
||||
// Device
|
||||
{
|
||||
label: '注册设备', handle: async () => {
|
||||
let devId = await promiseFactory(device.getDeviceId, {})
|
||||
.then(res => res.deviceId)
|
||||
let userinfo = await API.userInfo()
|
||||
console.log(`获取到name=${userinfo.name} ,deviceId=${devId}`);
|
||||
let result = await API.deviceReg(userinfo.name, devId)
|
||||
console.log('注册结果:', JSON.stringify(result));
|
||||
// [{"uid":"1","is_clip":0,"device_id":"f787bbf3-fffd-a2d7-fef9-716ff1bf1809","name":"新设备","id":1,"type":"ios"},{"uid":"1","is_clip":1,"device_id":"f787bbf3-fffd-a2d7-fef9-716ff1bf1809","name":"easychen+new","id":2,"type":"ios"}]
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '设备列表', handle: async () => {
|
||||
let devList = await API.deviceList()
|
||||
console.log('devList: ', JSON.stringify(devList));
|
||||
// [{"uid":"1","is_clip":0,"device_id":"f787bbf3-fffd-a2d7-fef9-716ff1bf1809","name":"新设备","id":1,"type":"ios"},{"uid":"1","is_clip":1,"device_id":"f787bbf3-fffd-a2d7-fef9-716ff1bf1809","name":"easychen+new","id":2,"type":"ios"}]
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '重命名设备', handle: async () => {
|
||||
let result = await API.deviceRename(1, '新设备')
|
||||
console.log('重命名结果: ', JSON.stringify(result));
|
||||
// {"message":"done"}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '移除设备', handle: async () => {
|
||||
let result = await API.deviceRemove(2)
|
||||
console.log('移除结果: ', JSON.stringify(result));
|
||||
// {"message":"done"}
|
||||
}
|
||||
},
|
||||
// Key
|
||||
{
|
||||
label: '生成Key', handle: async () => {
|
||||
let result = await API.keyGen()
|
||||
console.log('生成结果:', JSON.stringify(result));
|
||||
//[{"uid":"1","name":"KeydjzKuP4v","created_at":"2022-02-05T05:05:44.000000Z","id":1,"key":"PDU1TEkEzYvahqzI9BVsPLojC86XQJWX6AcWW"},{"uid":"1","name":"KeyD56XoKTR","created_at":"2022-02-05T05:06:08.000000Z","id":2,"key":"PDU1TYHP2rEnVGUpGjJ4uwm59nBwLAraN3QwV"}]
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Key列表', handle: async () => {
|
||||
let keyList = await API.keyList()
|
||||
console.log('keyList: ', JSON.stringify(keyList));
|
||||
//[{"uid":"1","name":"KeydjzKuP4v","created_at":"2022-02-05T05:05:44.000000Z","id":1,"key":"PDU1TEkEzYvahqzI9BVsPLojC86XQJWX6AcWW"},{"uid":"1","name":"KeyD56XoKTR","created_at":"2022-02-05T05:06:08.000000Z","id":2,"key":"PDU1TYHP2rEnVGUpGjJ4uwm59nBwLAraN3QwV"}]
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '重命名Key', handle: async () => {
|
||||
let result = await API.keyRename(1, '新Key')
|
||||
console.log('重命名结果: ', JSON.stringify(result));
|
||||
// {"message":"done"}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '移除Key', handle: async () => {
|
||||
let result = await API.keyRemove(4)
|
||||
console.log('移除结果: ', JSON.stringify(result));
|
||||
// {"message":"done"}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '消息列表', handle: async () => {
|
||||
let messageList = await API.messageList()
|
||||
console.log('messageList: ', JSON.stringify(messageList));
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '发送消息', handle: async () => {
|
||||
let result = await API.messagePush('text', 'desp', 'text')
|
||||
console.log('发送结果: ', JSON.stringify(result));
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '移除message', handle: async () => {
|
||||
let result = await API.messageRemove(1)
|
||||
console.log('移除结果: ', JSON.stringify(result));
|
||||
// {"message":"done"}
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
handleBtnClick(idx) {
|
||||
this.btns[idx].handle()
|
||||
},
|
||||
|
||||
onInit() {
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.wrapper {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
.logo {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 60%;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
/* .btn-group {
|
||||
flex-direction: column;
|
||||
width: 50%; */
|
||||
/* margin: 0 auto; */
|
||||
|
||||
text {
|
||||
margin: 16px 0;
|
||||
padding: 24px;
|
||||
border-width: 3px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
}
|
||||
.btn-wx {
|
||||
color: #296c05;
|
||||
border-color: #296c05;
|
||||
}
|
||||
}
|
||||
/* } */
|
||||
</style>
|
108
quickapp/src/pages/component/swipeItem.ux
Normal file
108
quickapp/src/pages/component/swipeItem.ux
Normal file
@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<stack
|
||||
class="swipe_item"
|
||||
@touchstart="dealTouchStart"
|
||||
@touchmove="dealTouchMove"
|
||||
@touchend="dealTouchEnd"
|
||||
@touchcancel="dealTouchEnd"
|
||||
>
|
||||
<div id="right">
|
||||
<slot name="right"></slot>
|
||||
</div>
|
||||
<div id="content">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
</stack>
|
||||
</template>
|
||||
<style lang="less">
|
||||
.swipe_item {
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
let $animation = null
|
||||
module.exports = {
|
||||
data: {
|
||||
movestartX: 0,
|
||||
threshold: 30,
|
||||
isOpened: false,
|
||||
contentPosX: 0,
|
||||
btnAreaWidth: 120,
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
onInit() {
|
||||
let that=this
|
||||
setTimeout(() => {
|
||||
this.$element('right').getBoundingClientRect({
|
||||
success(res) {
|
||||
that.btnAreaWidth=res.width
|
||||
// console.log(`res=${JSON.stringify(res)}`);
|
||||
}
|
||||
})
|
||||
}, 500);
|
||||
},
|
||||
|
||||
dealTouchStart(e) {
|
||||
this.movestartX = e.touches[0].clientX;
|
||||
console.info("dealTouchStart movestartX=" + e.touches[0].clientX);
|
||||
},
|
||||
|
||||
dealTouchMove(e) {
|
||||
let [deltaX, contentX] = this.calX(e.touches[0].clientX)
|
||||
// console.info(`dealTouchMove deltaX= ${deltaX},contentX= ${contentX}`);
|
||||
if (Math.abs(deltaX) < this.threshold) {
|
||||
return;
|
||||
}
|
||||
if (contentX > 0) {
|
||||
return
|
||||
}
|
||||
this.animate(contentX, contentX, true)
|
||||
},
|
||||
|
||||
dealTouchEnd(e) {
|
||||
let [deltaX, contentX] = this.calX(e.changedTouches[0].clientX)
|
||||
if (contentX > 0) {
|
||||
contentX = 0
|
||||
}
|
||||
this.isOpened = contentX < -this.btnAreaWidth ? true : false
|
||||
this.contentPosX = this.isOpened ? -this.btnAreaWidth : 0
|
||||
console.info(`dealTouchEnd dis=${deltaX}, contentX=${contentX}, isOpened=${this.isOpened},contentPosX=${this.contentPosX}`);
|
||||
this.animate(contentX, this.contentPosX)
|
||||
},
|
||||
|
||||
calX(clientX) {
|
||||
let deltaX = clientX - this.movestartX
|
||||
let contentX = this.contentPosX + deltaX
|
||||
return [deltaX, contentX]
|
||||
},
|
||||
|
||||
|
||||
animate(value1, value2, immediately = false) {
|
||||
// console.log(`animate from ${value1} to ${value2}, immediately=${immediately}`)
|
||||
let options = {
|
||||
duration: immediately ? 0 : 300,
|
||||
easing: 'linear',
|
||||
delay: 0,
|
||||
fill: 'forwards',
|
||||
iterations: 1
|
||||
}
|
||||
let frames = [
|
||||
{
|
||||
transform: {
|
||||
translateX: `${value1}px`,
|
||||
}
|
||||
},
|
||||
{
|
||||
transform: {
|
||||
translateX: `${value2}px`,
|
||||
}
|
||||
}];
|
||||
let $animation = this.$element('content').animate(frames, options);
|
||||
$animation.play();
|
||||
},
|
||||
}
|
||||
</script>
|
@ -3,11 +3,11 @@
|
||||
<!-- template里只能有一个根节点 -->
|
||||
<div class="wrapper">
|
||||
<div class="logo">
|
||||
<img src="/assets/images/index-logo.svg" />
|
||||
<image src="/assets/images/index-logo.svg" />
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<text class="btn-wx" @click="onWxSignBtnClick">Sign in with WeChat</text>
|
||||
<!-- class="btn-wx"
|
||||
<!-- class="btn-wx"
|
||||
value="Sign in with WeChat"
|
||||
onclick="onWxSignBtnClick"
|
||||
/> -->
|
||||
@ -16,54 +16,66 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import router from '@system.router'
|
||||
import router from '@system.router'
|
||||
|
||||
export default {
|
||||
// 页面级组件的数据模型,影响传入数据的覆盖机制:private内定义的属性不允许被覆盖
|
||||
private: {
|
||||
},
|
||||
const appInitC = new BroadcastChannel('init')
|
||||
appInitC.onmessage = ({ data }) => {
|
||||
console.log(`index: received app init message:${data}`);
|
||||
if (data === 1) {
|
||||
appInitC.close()
|
||||
router.replace({
|
||||
uri: 'pages/Home'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onWxSignBtnClick() {
|
||||
router.replace({
|
||||
uri: '/pages/Home',
|
||||
})
|
||||
},
|
||||
export default {
|
||||
// 页面级组件的数据模型,影响传入数据的覆盖机制:private内定义的属性不允许被覆盖
|
||||
private: {
|
||||
},
|
||||
|
||||
onInit() {
|
||||
},
|
||||
}
|
||||
async onWxSignBtnClick() {
|
||||
API.login()
|
||||
.then(token => {
|
||||
appInitC.postMessage(token)
|
||||
})
|
||||
},
|
||||
|
||||
onInit() {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.wrapper {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
.logo {
|
||||
.wrapper {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 60%;
|
||||
width: 50%;
|
||||
}
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
.btn-group {
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
/* margin: 0 auto; */
|
||||
|
||||
text {
|
||||
margin: 16px 0;
|
||||
padding: 24px;
|
||||
border-width: 3px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
.logo {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 60%;
|
||||
width: 50%;
|
||||
}
|
||||
.btn-wx {
|
||||
color: #296c05;
|
||||
border-color: #296c05;
|
||||
|
||||
.btn-group {
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
/* margin: 0 auto; */
|
||||
|
||||
text {
|
||||
margin: 16px 0;
|
||||
padding: 24px;
|
||||
border-width: 3px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
font-size: 32px;
|
||||
}
|
||||
.btn-wx {
|
||||
color: #296c05;
|
||||
border-color: #296c05;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
79
quickapp/src/pages/swipe/index.ux
Normal file
79
quickapp/src/pages/swipe/index.ux
Normal file
@ -0,0 +1,79 @@
|
||||
<import name="swipe_item" src="../component/swipeItem"></import>
|
||||
<template>
|
||||
<div>
|
||||
<swipe_item>
|
||||
<text slot="content" class="main">text</text>
|
||||
<div slot="right" class="right">
|
||||
<image src="/assets/images/trash.png"></image>
|
||||
</div>
|
||||
</swipe_item>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.main {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
background-color: blue;
|
||||
height: 100px;
|
||||
}
|
||||
.right {
|
||||
height: 60px;
|
||||
width: 100px;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import prompt from '@system.prompt'
|
||||
export default {
|
||||
private: {
|
||||
componentName: 'slide-view',
|
||||
slideButton1: [
|
||||
{
|
||||
id: "button1",
|
||||
buttonWidth: '200px',
|
||||
text: '删除',
|
||||
backgroundColor: "#cc0000",
|
||||
secondaryConfirm: {
|
||||
text: '二次确认'
|
||||
}
|
||||
}
|
||||
],
|
||||
slideButton2: [
|
||||
{
|
||||
id: "button2",
|
||||
buttonWidth: '200px',
|
||||
icon: '../../../common/logo.png',
|
||||
backgroundColor: "#cc0000",
|
||||
secondaryConfirm: {
|
||||
text: '二次确认'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
onInit() {
|
||||
this.$page.setTitleBar({ text: 'slide-view' })
|
||||
},
|
||||
slideViewOpen() {
|
||||
console.info(`### slide view is open ###`)
|
||||
},
|
||||
slideViewClose() {
|
||||
console.info(`### slide view is close ###`)
|
||||
},
|
||||
slideViewSlide({ offset }) {
|
||||
console.info(`### slide view is slide, offset is ${offset} ###`)
|
||||
},
|
||||
buttonClick(data) {
|
||||
const { id, isSecondaryConfirm } = data
|
||||
console.info(`### button:${id} is click, data is ${data} ###`)
|
||||
if (isSecondaryConfirm) {
|
||||
prompt.showToast({
|
||||
message: '第二次点击触发'
|
||||
})
|
||||
} else {
|
||||
prompt.showToast({
|
||||
message: '第一次点击触发'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user