
交友盲盒源码下载及搭建
网络约会业务是互联网的未来。互联网已经极大地改变了我们的互动方式,如今超过 85% 的人口正在使用约会网络应用程序与朋友保持联系或结识新朋友。现在,人们甚至在去酒吧与其他人会面之前首先使用互联网。使用互联网与某人约会的人数每年都在增加。约会业务已成为网络上第二大最赚钱的市场。 所有领先的约会业务每年都在增加越来越多的收入,而您可能是下一个!
交友盲盒演示:m.ymzan.top

交友盲盒是一个原生应用程序源代码,具有时尚的设计和完整功能以及额外的高级功能。即使您不是编码专家,也可以使用我们的应用程序源代码。获取应用程序源代码并开始构建,或者我们为您提供最物有所值的定制包。
交友盲盒源码是使用最新网络技术的最强大的现成约会网站生成器,包括创建成功的约会网络应用程序所需的所有约会功能
简单、快速和智能:交友盲盒源码的构建非常快速、安全,并集成了隐形智能垃圾邮件检测系统。最后,交友盲盒源码基于当今可用的最新 Web 技术。
非常有趣:我们的软件对您和您的访客来说非常有趣和简单!
约会服务和社区网站:社交约会 CMS 非常适合约会网站和社交社区门户。
多主题和无限定制:借助我们的 CMS 架构,在创纪录的时间内构建独特的社交/约会主题。
国际化系统:我们的社区约会软件可以被轻松翻译成任何语言。
借助集成到软件中的会员模块,让人们无需花费一美元就可以为您的网站做广告!
为数据库、模板文件、静态文件(HTML、CSS、JS)、字符串内容等提供强大的智能缓存系统。缓存系统还会压缩内容以节省服务器上的带宽并降低其成本。
针对寻求专业且高度可定制的软件的经验丰富的开发人员和公司进行了优化。
继续使用 100% 的“RSS 源”:所有内容模块都包含在 RSS 源输出中,以便您在任何不同的应用程序、站点、小部件等中获取和集成数据,甚至向合作伙伴、开发人员或用户。
完整的 API: 交友盲盒源码提供了一个 RESTful API(和一个检索数据类帮助程序),以便您可以创建 iOS(iPhone、iPad、Apple Watch)、Android 或任何其他类型的 Web 或电话应用程序您网站的用户数据。
你的数据是你的!在您想要的任何地方托管您的网络服务,控制您的数据,并且不依赖任何人!
完全控制数据,最终完全控制您的业务。
美丽的代码:非常彻底地评论了整个 PHP 代码中发生的事情,漂亮的缩进和可读性,即使对于非程序员也是如此。
交友盲盒源码的社交/约会功能
强大的反垃圾邮件系统(并检测重复的内容)。
SEO 友好(标题,内容,代码,...),站点地图模块,...
Schema.org 标记和微数据,您的社交约会网络应用程序将大大提高搜索引擎结果的排名,并启用强大的功能!
支持多种语言、国际化和本地化。
多语言 URL无论是哪种语言,所有 URL 都可以翻译,以提高您约会平台的 SEO。
动态用户字段管理
内置的基本统计和分析工具。
使用内置 RandomUser.me API 创建高质量配置文件的简单方法
使用管理面板的 IP 限制阻止访问/
管理员/用户/附属机构的两步验证选项。
智取审核工具
附近的人技术
相关配置文件功能(更容易匹配)
强大的反垃圾邮件系统(并检测重复的内容)。
内置会员系统,鼓励品牌影响者和大使推广您的约会服务。
会员和会员注册表格的国家限制
国际时间和日期格式
使用交友盲盒源码,任何人都可以在一天左右的时间内启动像其他社交约会网络应用程序,无需任何技术知识交友盲盒源码是最强大的现成约会网站生成器,使用最新的网络技术并包含您需要的所有约会功能创建一个类似或克隆的 Web 应用程序。如果您是开发人员/程序员,该软件的代码经过特别编码以便始终被理解,并包含每个操作的解释性注释,以防您想要进行一些修改。
我们提供三个高质量和专业的约会模板,高度可定制,并且 100% 兼容所有现代和流行的移动设备(以及桌面设备)。
与其他人不同,我们不会创建数百个约会模板。您可能已经看到提供 10、50 甚至数百个约会主题的其他竞争对手只是在撒谎。他们只是在快速测试一个模板是否适用于每个版本,而其他模板有很多错误,与每个设备/浏览器不兼容,错误并且不能与新功能正常工作。这就是为什么在 交友盲盒源码中,重要的是质量而不是数量!
与任何其他竞争对手不同,交友盲盒源码不仅是一个“约会软件提供商”,而且是一个真正的约会业务解决方案。
通过选择交友盲盒源码,您可以获得完整的源代码(没有加密!),让您(或为您工作的开发人员)有权进行任何修改和/或添加任何新功能。
与竞争对手不同,交友盲盒源码的构建首先考虑了安全性,它现在是当今市场上最安全的产品。交友盲盒源码也是开源的,非常适合想要构建严肃的社交约会网站/应用程序的开发人员。
交友盲盒源码是 100%基于模板的方法, 这意味着您可以轻松 自定义其设计或创建新模板。
与我们所有的竞争对手不同,在 交友盲盒源码,我们之前都参与过在线社交/约会应用程序 ,并且我们会不断了解领先约会网站使用的最新“技术和资料”。是的,我们真的很喜欢这个主题,我们绝对想让 交友盲盒源码成为行业中最好的!
交友盲盒源码使用 GetText 来翻译页面。如今,GetText 是翻译应用程序的最佳方式。比简单的 PHP 语言文件快得多,因为 GetText 文件针对高流量在线 Web 应用程序进行了编译和高度优化。
通过选择 交友盲盒源码,您可以获得 MIT 许可下的完整源代码(没有加密!),让您(或您的开发人员)有权对软件进行任何更改。
“交友盲盒源码”社交约会软件包括几个模块,可以分散用户的注意力,让他们一次又一次地返回您的网站,使其成为病毒式的和有趣的的!
社交友好,它还提供微信、QQ、微博等集成、聊天、爱情计算器、即时通讯工具、、聊天室……
借助强大的交互式内置通信工具,您的用户可以随时随地表达他们的意见、分享他们的想法并抓住他们难忘的时刻,并与世界各地的其他用户和朋友直接、即时地互动!
自托管
你的数据是你的!在您想要的任何地方托管您的网络服务,控制您的数据,并且不依赖任何人!为什么您的企业必须受制于他人?使用 交友盲盒源码,您可以选择您自己的服务器、您自己的数据和您的应用程序文件。通过选择 交友盲盒源码,您终于可以完全掌控您的业务了!
基于高度安全的框架;包括垃圾邮件保护系统
该软件基于“pCO8 Security pH7Framework”,它提供针对垃圾邮件、暴力攻击、重复内容、大量消息、大量评论/帖子的最高保护之一,并具有针对垃圾邮件的独特算法保护系统,有助于您与最不受欢迎的用户作斗争。
您还可以阻止整个国家/地区访问您的网站。
最后,它完全防止 SQL 注入、XSS、CSRF、会话固定、身份验证黑客、蛮力登录、反诈骗,甚至可以防止一些DDoS攻击!
网络约会业务是互联网的未来。互联网已经极大地改变了我们的互动方式,如今超过 85% 的人口正在使用约会网络应用程序与朋友保持联系或结识新朋友。现在,人们甚至在去酒吧与其他人会面之前首先使用互联网。使用互联网与某人约会的人数每年都在增加。约会业务已成为网络上第二大最赚钱的市场。 所有领先的约会业务每年都在增加越来越多的收入,而您可能是下一个!
交友盲盒演示:m.ymzan.top
交友盲盒是一个原生应用程序源代码,具有时尚的设计和完整功能以及额外的高级功能。即使您不是编码专家,也可以使用我们的应用程序源代码。获取应用程序源代码并开始构建,或者我们为您提供最物有所值的定制包。
交友盲盒源码是使用最新网络技术的最强大的现成约会网站生成器,包括创建成功的约会网络应用程序所需的所有约会功能
简单、快速和智能:交友盲盒源码的构建非常快速、安全,并集成了隐形智能垃圾邮件检测系统。最后,交友盲盒源码基于当今可用的最新 Web 技术。
非常有趣:我们的软件对您和您的访客来说非常有趣和简单!
约会服务和社区网站:社交约会 CMS 非常适合约会网站和社交社区门户。
多主题和无限定制:借助我们的 CMS 架构,在创纪录的时间内构建独特的社交/约会主题。
国际化系统:我们的社区约会软件可以被轻松翻译成任何语言。
借助集成到软件中的会员模块,让人们无需花费一美元就可以为您的网站做广告!
为数据库、模板文件、静态文件(HTML、CSS、JS)、字符串内容等提供强大的智能缓存系统。缓存系统还会压缩内容以节省服务器上的带宽并降低其成本。
针对寻求专业且高度可定制的软件的经验丰富的开发人员和公司进行了优化。
继续使用 100% 的“RSS 源”:所有内容模块都包含在 RSS 源输出中,以便您在任何不同的应用程序、站点、小部件等中获取和集成数据,甚至向合作伙伴、开发人员或用户。
完整的 API: 交友盲盒源码提供了一个 RESTful API(和一个检索数据类帮助程序),以便您可以创建 iOS(iPhone、iPad、Apple Watch)、Android 或任何其他类型的 Web 或电话应用程序您网站的用户数据。
你的数据是你的!在您想要的任何地方托管您的网络服务,控制您的数据,并且不依赖任何人!
完全控制数据,最终完全控制您的业务。
美丽的代码:非常彻底地评论了整个 PHP 代码中发生的事情,漂亮的缩进和可读性,即使对于非程序员也是如此。
交友盲盒源码的社交/约会功能
强大的反垃圾邮件系统(并检测重复的内容)。
SEO 友好(标题,内容,代码,...),站点地图模块,...
Schema.org 标记和微数据,您的社交约会网络应用程序将大大提高搜索引擎结果的排名,并启用强大的功能!
支持多种语言、国际化和本地化。
多语言 URL无论是哪种语言,所有 URL 都可以翻译,以提高您约会平台的 SEO。
动态用户字段管理
内置的基本统计和分析工具。
使用内置 RandomUser.me API 创建高质量配置文件的简单方法
使用管理面板的 IP 限制阻止访问/
管理员/用户/附属机构的两步验证选项。
智取审核工具
附近的人技术
相关配置文件功能(更容易匹配)
强大的反垃圾邮件系统(并检测重复的内容)。
内置会员系统,鼓励品牌影响者和大使推广您的约会服务。
会员和会员注册表格的国家限制
国际时间和日期格式
使用交友盲盒源码,任何人都可以在一天左右的时间内启动像其他社交约会网络应用程序,无需任何技术知识交友盲盒源码是最强大的现成约会网站生成器,使用最新的网络技术并包含您需要的所有约会功能创建一个类似或克隆的 Web 应用程序。如果您是开发人员/程序员,该软件的代码经过特别编码以便始终被理解,并包含每个操作的解释性注释,以防您想要进行一些修改。
我们提供三个高质量和专业的约会模板,高度可定制,并且 100% 兼容所有现代和流行的移动设备(以及桌面设备)。
与其他人不同,我们不会创建数百个约会模板。您可能已经看到提供 10、50 甚至数百个约会主题的其他竞争对手只是在撒谎。他们只是在快速测试一个模板是否适用于每个版本,而其他模板有很多错误,与每个设备/浏览器不兼容,错误并且不能与新功能正常工作。这就是为什么在 交友盲盒源码中,重要的是质量而不是数量!
与任何其他竞争对手不同,交友盲盒源码不仅是一个“约会软件提供商”,而且是一个真正的约会业务解决方案。
通过选择交友盲盒源码,您可以获得完整的源代码(没有加密!),让您(或为您工作的开发人员)有权进行任何修改和/或添加任何新功能。
与竞争对手不同,交友盲盒源码的构建首先考虑了安全性,它现在是当今市场上最安全的产品。交友盲盒源码也是开源的,非常适合想要构建严肃的社交约会网站/应用程序的开发人员。
交友盲盒源码是 100%基于模板的方法, 这意味着您可以轻松 自定义其设计或创建新模板。
与我们所有的竞争对手不同,在 交友盲盒源码,我们之前都参与过在线社交/约会应用程序 ,并且我们会不断了解领先约会网站使用的最新“技术和资料”。是的,我们真的很喜欢这个主题,我们绝对想让 交友盲盒源码成为行业中最好的!
交友盲盒源码使用 GetText 来翻译页面。如今,GetText 是翻译应用程序的最佳方式。比简单的 PHP 语言文件快得多,因为 GetText 文件针对高流量在线 Web 应用程序进行了编译和高度优化。
通过选择 交友盲盒源码,您可以获得 MIT 许可下的完整源代码(没有加密!),让您(或您的开发人员)有权对软件进行任何更改。
“交友盲盒源码”社交约会软件包括几个模块,可以分散用户的注意力,让他们一次又一次地返回您的网站,使其成为病毒式的和有趣的的!
社交友好,它还提供微信、QQ、微博等集成、聊天、爱情计算器、即时通讯工具、、聊天室……
借助强大的交互式内置通信工具,您的用户可以随时随地表达他们的意见、分享他们的想法并抓住他们难忘的时刻,并与世界各地的其他用户和朋友直接、即时地互动!
自托管
你的数据是你的!在您想要的任何地方托管您的网络服务,控制您的数据,并且不依赖任何人!为什么您的企业必须受制于他人?使用 交友盲盒源码,您可以选择您自己的服务器、您自己的数据和您的应用程序文件。通过选择 交友盲盒源码,您终于可以完全掌控您的业务了!
基于高度安全的框架;包括垃圾邮件保护系统
该软件基于“pCO8 Security pH7Framework”,它提供针对垃圾邮件、暴力攻击、重复内容、大量消息、大量评论/帖子的最高保护之一,并具有针对垃圾邮件的独特算法保护系统,有助于您与最不受欢迎的用户作斗争。
您还可以阻止整个国家/地区访问您的网站。
最后,它完全防止 SQL 注入、XSS、CSRF、会话固定、身份验证黑客、蛮力登录、反诈骗,甚至可以防止一些DDoS攻击! 收起阅读 »

easyinput 添加readonly
input 什么时候可以添加readonly属性,我看到19年就有人提这个需求了,现在还是没有添加
input 什么时候可以添加readonly属性,我看到19年就有人提这个需求了,现在还是没有添加

WebDAV client for uni-app
https://github.com/kytrun/webdav-client-uniapp
Fork 自 webdav-client,添加了 uni.request 作为 axios adaper,目前基本可用,没有测试全部功能。需要注意的是坚果云提供的 WebDAV 并非标准的 WebDAV,部分接口有问题可能在其他服务上表现正常。
下载 https://github.com/kytrun/webdav-client-uniapp/blob/master/dist/uniapp/webdav.js 文件在 uni-app 项目中以 ES module 导入使用。
坚果云 WebDAV 示例:
import {
AuthType,
createClient
} from "@/deps/webdav"
const client = createClient(
"https://dav.jianguoyun.com/dav/test/", {
authType: AuthType.Password,
username: `${username}`,
password: `${password}`
})
client.getFileContents("test.txt", {
format: "text"
})
.then(data => console.log(data))
.catch(e => console.log(e))
更多接口见项目文档。
https://github.com/kytrun/webdav-client-uniapp
Fork 自 webdav-client,添加了 uni.request 作为 axios adaper,目前基本可用,没有测试全部功能。需要注意的是坚果云提供的 WebDAV 并非标准的 WebDAV,部分接口有问题可能在其他服务上表现正常。
下载 https://github.com/kytrun/webdav-client-uniapp/blob/master/dist/uniapp/webdav.js 文件在 uni-app 项目中以 ES module 导入使用。
坚果云 WebDAV 示例:
import {
AuthType,
createClient
} from "@/deps/webdav"
const client = createClient(
"https://dav.jianguoyun.com/dav/test/", {
authType: AuthType.Password,
username: `${username}`,
password: `${password}`
})
client.getFileContents("test.txt", {
format: "text"
})
.then(data => console.log(data))
.catch(e => console.log(e))
更多接口见项目文档。
收起阅读 »
语音播报-前台后台离线推送语音播报、到账xx元、收款播报、自定义推送铃(ios)
语音播报-前台后台离线推送语音播报、到账xx元、收款播报、自定义推送铃(ios):https://ext.dcloud.net.cn/plugin?id=8452
语音播报-前台后台离线推送语音播报、到账xx元、收款播报、自定义推送铃(ios):https://ext.dcloud.net.cn/plugin?id=8452

DCloud平台用户信息修改,插件作者未更新
更新用户信息后,为什么发布的插件作者那里没有变,点击之后还提示找不到此用户
更新用户信息后,为什么发布的插件作者那里没有变,点击之后还提示找不到此用户

希望可以在js里面输入未导入的变量时可以自动导入
希望可以在js里面输入未导入的变量时可以自动导入,像webstorm一样,,不然第一次写的都只能去复制,这样可以省去更多的时间;
并且希望可以在scss文件里面也可以使用格式化功能,现在无法使用格式化功能,只能自己手动排版,非常麻烦!
希望可以在js里面输入未导入的变量时可以自动导入,像webstorm一样,,不然第一次写的都只能去复制,这样可以省去更多的时间;
并且希望可以在scss文件里面也可以使用格式化功能,现在无法使用格式化功能,只能自己手动排版,非常麻烦!

迫于新版HX诸多问题,放一个我现在一直在用的3.3.13版本
迫于新版HX诸多问题,看到有不少同学在找历史版本,在这放一个现在一直在用的3.3.13版本吧

图片在容器下自由缩放旋转拖动Demo
先实现如下效果,图片可自由缩放旋转删除移动。通过两个点控制。
实现效果Demo如下:
这是Demo代码,可直接复制到项目中运行看效果。
支持小程序、APP。
一开始考虑使用的movable-area+movable-view。但因为需要先禁用移动,当点击的是右下角旋转按钮时才允许移动,所以需要在touchstart里面disabled改为false,然后再touchend中再次修改为禁止移动。
但movable-view不支持在touchstart中修改disabled立刻生效,只能在下次点击时生效,所以使用view+css实现。
<template>
<view class="page-body">
<view class="move-area">
<view v-if="!isHide" class="move-box" style="transform-origin:center;"
@touchmove="itemMove" @touchstart="itemtouch" @touchend="itemend"
:style="{transform: 'translate(' + itemX + 'px, ' + itemY +'px) rotate('+tmpRotate+'deg) scale('+tmpScale+')'}">
<view class="opt-icon del-icon" :style="{transform: 'scale(' + (1 / tmpScale) + ')'}" @touchstart="startMode(2)"></view>
<view class="opt-icon edit-icon" :style="{transform: 'scale(' + (1 / tmpScale) + ')'}" @touchstart="startMode(1)"></view>
<view class="move-body" @touchstart="startMode(0)">这是内容</view>
</view>
</view>
</view>
</template>
<script>
const nearDg = 7; // 用于控制当近似垂直或水平时,视为垂直或水平的容差。
let lastX = 0, lastY = 0;
export default {
data() {
return {
itemX: 0,
itemY: 0,
realCenterX: 0,
realCenterY: 0,
halfWidth: 75, // px
halfHeight: 75, // px
realWidth: 0,
realHeight: 0,
offset: 12.5, // px
touchMode: 0, // 0移动 1缩放旋转 2删除
startX: 0,
startY: 0,
startAngle: 0,
startDist: 0,
tmpRotate: 0,
initRotate: 0,
tmpScale: 1,
initScale: 1,
isHide: false,
}
},
onLoad:function(){
this.itemX = 70;
this.itemY = 100;
},
mounted:function(){
let view = uni.createSelectorQuery().in(this).select(".move-box");
view.boundingClientRect(data => {
this.realWidth = data.width;
this.realHeight = data.height;
this.realCenterX = data.right - data.width / 2;
this.realCenterY = data.bottom - data.height / 2;
}).exec();
},
methods: {
itemMove: function(e){
let curX = e.touches[0].clientX;
let curY = e.touches[0].clientY;
if(this.touchMode === 0){
this.itemX += curX - lastX;
this.itemY += curY - lastY;
this.realCenterX += curX - lastX;
this.realCenterY += curY - lastY;
lastX = curX;
lastY = curY;
}
if(this.touchMode !== 1)return;
let angle = this.angle(this.realCenterX, this.realCenterY, curX, curY);
if(this.startAngle === 0){
this.startX = curX;
this.startY = curY;
this.startAngle = angle;
this.startDist = Math.hypot(this.startX - this.realCenterX, this.startY - this.realCenterY);
}
else{
let rotate = this.initRotate + Math.round(angle - this.startAngle);
let leftDg = Math.abs(rotate % 90);
if(leftDg < nearDg || 90 - leftDg < nearDg){
rotate = Math.round(rotate / 90) * 90;
}
this.tmpRotate = rotate;
let curDist = Math.hypot(curX - this.realCenterX, curY - this.realCenterY);
this.tmpScale = this.initScale * curDist / this.startDist;
}
},
itemtouch: function(e){
lastX = e.touches[0].clientX;
lastY = e.touches[0].clientY;
},
itemend: function(e){
this.startAngle = 0;
this.initRotate = this.tmpRotate;
this.initScale = this.tmpScale;
},
startMode: function(mode){
this.touchMode = mode;
if(this.touchMode === 2){
this.isHide = true;
}
},
angle: function(cx, cy, ex, ey){
var dy = ey - cy;
var dx = ex - cx;
var theta = Math.atan2(dy, dx); // range (-PI, PI]
theta *= 180 / Math.PI; // rads to degs, range (-180, 180]
if (theta < 0) theta = 360 + theta; // range [0, 360)
return theta;
}
}
}
</script>
<style lang="scss">
.page-body{
padding: 5px;
}
.move-area{
width: 365px;
height: 500px;
}
.move-box{
position: relative;
width: 175px;
height: 175px;
padding: 1px;
}
.opt-icon{
position: absolute;
width: 25px;
height: 25px;
border-radius: 50%;
}
.del-icon{
background-color: red;
left: 0;
top: 0;
}
.edit-icon{
background-color: green;
right: 0;
bottom: 0;
}
.move-body{
margin: 12.5px;
width: 150px;
height: 150px;
border: 2px solid green;
}
</style>
先实现如下效果,图片可自由缩放旋转删除移动。通过两个点控制。
实现效果Demo如下:
这是Demo代码,可直接复制到项目中运行看效果。
支持小程序、APP。
一开始考虑使用的movable-area+movable-view。但因为需要先禁用移动,当点击的是右下角旋转按钮时才允许移动,所以需要在touchstart里面disabled改为false,然后再touchend中再次修改为禁止移动。
但movable-view不支持在touchstart中修改disabled立刻生效,只能在下次点击时生效,所以使用view+css实现。
<template>
<view class="page-body">
<view class="move-area">
<view v-if="!isHide" class="move-box" style="transform-origin:center;"
@touchmove="itemMove" @touchstart="itemtouch" @touchend="itemend"
:style="{transform: 'translate(' + itemX + 'px, ' + itemY +'px) rotate('+tmpRotate+'deg) scale('+tmpScale+')'}">
<view class="opt-icon del-icon" :style="{transform: 'scale(' + (1 / tmpScale) + ')'}" @touchstart="startMode(2)"></view>
<view class="opt-icon edit-icon" :style="{transform: 'scale(' + (1 / tmpScale) + ')'}" @touchstart="startMode(1)"></view>
<view class="move-body" @touchstart="startMode(0)">这是内容</view>
</view>
</view>
</view>
</template>
<script>
const nearDg = 7; // 用于控制当近似垂直或水平时,视为垂直或水平的容差。
let lastX = 0, lastY = 0;
export default {
data() {
return {
itemX: 0,
itemY: 0,
realCenterX: 0,
realCenterY: 0,
halfWidth: 75, // px
halfHeight: 75, // px
realWidth: 0,
realHeight: 0,
offset: 12.5, // px
touchMode: 0, // 0移动 1缩放旋转 2删除
startX: 0,
startY: 0,
startAngle: 0,
startDist: 0,
tmpRotate: 0,
initRotate: 0,
tmpScale: 1,
initScale: 1,
isHide: false,
}
},
onLoad:function(){
this.itemX = 70;
this.itemY = 100;
},
mounted:function(){
let view = uni.createSelectorQuery().in(this).select(".move-box");
view.boundingClientRect(data => {
this.realWidth = data.width;
this.realHeight = data.height;
this.realCenterX = data.right - data.width / 2;
this.realCenterY = data.bottom - data.height / 2;
}).exec();
},
methods: {
itemMove: function(e){
let curX = e.touches[0].clientX;
let curY = e.touches[0].clientY;
if(this.touchMode === 0){
this.itemX += curX - lastX;
this.itemY += curY - lastY;
this.realCenterX += curX - lastX;
this.realCenterY += curY - lastY;
lastX = curX;
lastY = curY;
}
if(this.touchMode !== 1)return;
let angle = this.angle(this.realCenterX, this.realCenterY, curX, curY);
if(this.startAngle === 0){
this.startX = curX;
this.startY = curY;
this.startAngle = angle;
this.startDist = Math.hypot(this.startX - this.realCenterX, this.startY - this.realCenterY);
}
else{
let rotate = this.initRotate + Math.round(angle - this.startAngle);
let leftDg = Math.abs(rotate % 90);
if(leftDg < nearDg || 90 - leftDg < nearDg){
rotate = Math.round(rotate / 90) * 90;
}
this.tmpRotate = rotate;
let curDist = Math.hypot(curX - this.realCenterX, curY - this.realCenterY);
this.tmpScale = this.initScale * curDist / this.startDist;
}
},
itemtouch: function(e){
lastX = e.touches[0].clientX;
lastY = e.touches[0].clientY;
},
itemend: function(e){
this.startAngle = 0;
this.initRotate = this.tmpRotate;
this.initScale = this.tmpScale;
},
startMode: function(mode){
this.touchMode = mode;
if(this.touchMode === 2){
this.isHide = true;
}
},
angle: function(cx, cy, ex, ey){
var dy = ey - cy;
var dx = ex - cx;
var theta = Math.atan2(dy, dx); // range (-PI, PI]
theta *= 180 / Math.PI; // rads to degs, range (-180, 180]
if (theta < 0) theta = 360 + theta; // range [0, 360)
return theta;
}
}
}
</script>
<style lang="scss">
.page-body{
padding: 5px;
}
.move-area{
width: 365px;
height: 500px;
}
.move-box{
position: relative;
width: 175px;
height: 175px;
padding: 1px;
}
.opt-icon{
position: absolute;
width: 25px;
height: 25px;
border-radius: 50%;
}
.del-icon{
background-color: red;
left: 0;
top: 0;
}
.edit-icon{
background-color: green;
right: 0;
bottom: 0;
}
.move-body{
margin: 12.5px;
width: 150px;
height: 150px;
border: 2px solid green;
}
</style>
收起阅读 »

Native.js 实现 unaipp 离线推送
<template>
<view class="content">
<view class="text-area">
<button type="primary" size="mini" @tap="pushMsg()">推送</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onLoad() {
// #ifdef APP-PLUS
// 获取客户端标识信息
// var info = plus.push.getClientInfo();
// console.log( JSON.stringify( info ) );
// 添加监听从系统消息中心点击某条消息启动应用事件
plus.push.addEventListener('click', function(msg){
// 分析msg.payload处理业务逻辑
console.log( '点击通知栏: ',msg.payload, msg.content, msg.payload.url )
setTimeout(() => {
uni.navigateTo({
url: msg.payload.url
});
}, 1000);
}, false );
// #endif
},
methods: {
pushMsg(){
plus.nativeUI.toast('推送消息测试')
// createMessage
var options = {
cover:false,
// icon: '',
// title: '1111',
// subtitle: '1111',
};
plus.push.createMessage('你收到一条新消息', {
type: 'LocalMSG',
url: '../test/test'
}, options);
//设置角标
plus.runtime.setBadgeNumber(0);
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
<template>
<view class="content">
<view class="text-area">
<button type="primary" size="mini" @tap="pushMsg()">推送</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onLoad() {
// #ifdef APP-PLUS
// 获取客户端标识信息
// var info = plus.push.getClientInfo();
// console.log( JSON.stringify( info ) );
// 添加监听从系统消息中心点击某条消息启动应用事件
plus.push.addEventListener('click', function(msg){
// 分析msg.payload处理业务逻辑
console.log( '点击通知栏: ',msg.payload, msg.content, msg.payload.url )
setTimeout(() => {
uni.navigateTo({
url: msg.payload.url
});
}, 1000);
}, false );
// #endif
},
methods: {
pushMsg(){
plus.nativeUI.toast('推送消息测试')
// createMessage
var options = {
cover:false,
// icon: '',
// title: '1111',
// subtitle: '1111',
};
plus.push.createMessage('你收到一条新消息', {
type: 'LocalMSG',
url: '../test/test'
}, options);
//设置角标
plus.runtime.setBadgeNumber(0);
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
收起阅读 »

Native.js 实现 unaipp 截图
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<image :src="capture" ref="img"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<button @tap="captureWebview"> 截图 </button>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello word !',
capture: '',
}
},
onLoad() {
// #ifdef APP-PLUS
console.log('系统: ', plus.os.name)
// console.log('version:' + plus.runtime.versionCode);
// 监听设备网络状态变化事件
plus.globalEvent.addEventListener('netchange', function(){
console.log('网络')
});
// #endif
},
methods: {
// 截屏绘制
captureWebview() {
var _this = this
var ws=plus.webview.getTopWebview();
var bitmap = new plus.nativeObj.Bitmap('test');
// 将webview内容绘制到Bitmap对象中
ws.draw(bitmap,function(){
console.log('截屏绘制图片成功');
bitmap.save( "_doc/a.jpg",{},
function(e){
console.log('保存图片成功:'+JSON.stringify(e));
//保存到相册
plus.gallery.save(e.target,(e)=>{
plus.nativeUI.toast("保存成功")
})
},
function(e){
console.log('保存图片失败:'+JSON.stringify(e));
});
_this.capture = bitmap.toBase64Data()
// bitmap.save('_doc/b.png',
// { "overwrite": false, "format": "png", "quality": 50 },
// function(e){
// //保存到相册
// plus.gallery.save(e.target,(e)=>{
// plus.nativeUI.toast("保存成功")
// })
// }, function(error){
// plus.nativeUI.toast("保存失败")
// console.log("code:" + error.code + ";msg:" + error.message)
// })
//保存到相册后,回收Bitmap图片内存
bitmap.recycle();
},function(e){
console.log('截屏绘制图片失败:'+JSON.stringify(e));
});
},
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<image :src="capture" ref="img"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<button @tap="captureWebview"> 截图 </button>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello word !',
capture: '',
}
},
onLoad() {
// #ifdef APP-PLUS
console.log('系统: ', plus.os.name)
// console.log('version:' + plus.runtime.versionCode);
// 监听设备网络状态变化事件
plus.globalEvent.addEventListener('netchange', function(){
console.log('网络')
});
// #endif
},
methods: {
// 截屏绘制
captureWebview() {
var _this = this
var ws=plus.webview.getTopWebview();
var bitmap = new plus.nativeObj.Bitmap('test');
// 将webview内容绘制到Bitmap对象中
ws.draw(bitmap,function(){
console.log('截屏绘制图片成功');
bitmap.save( "_doc/a.jpg",{},
function(e){
console.log('保存图片成功:'+JSON.stringify(e));
//保存到相册
plus.gallery.save(e.target,(e)=>{
plus.nativeUI.toast("保存成功")
})
},
function(e){
console.log('保存图片失败:'+JSON.stringify(e));
});
_this.capture = bitmap.toBase64Data()
// bitmap.save('_doc/b.png',
// { "overwrite": false, "format": "png", "quality": 50 },
// function(e){
// //保存到相册
// plus.gallery.save(e.target,(e)=>{
// plus.nativeUI.toast("保存成功")
// })
// }, function(error){
// plus.nativeUI.toast("保存失败")
// console.log("code:" + error.code + ";msg:" + error.message)
// })
//保存到相册后,回收Bitmap图片内存
bitmap.recycle();
},function(e){
console.log('截屏绘制图片失败:'+JSON.stringify(e));
});
},
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
收起阅读 »

我写了一个基于Typescript跨多平台的nodejs框架
现在支持私有部署同时也支持serverless各个平台的nodejs框架多么?答案是否定的,在2022年越来越多的企业会选择serverless来部署自己的应用,因为它足够轻巧省去了运维的成本,编写一个API可能只需要几行代码,越来越多的平台也推出了自己的云数据库以及云消息队列,我们前端开发编写后端api不再是一个头疼的事情。所以serverless是未来,为此我写了一个框架,它会在web服务器中运行也可以在serverless环境运行,在serverless中我会优先支持unicloud,我将使用这款框架参加2022年的dcloud插件大赛。
简单聊聊这款框架,我为什么要创建一款nodejs框架?
为什么要造轮子
在sword团队中我们使用unicloud构建应用程序,采用了CQRS,我们所有的写操作都由unicloud的云函数完成,但是你会发现在unicloud社区优秀的框架有很多,它们提供了url处理以及逻辑的分发,还有一些特色的框架也提供了诸如上传,和unicloud的部分特性封装,在我看来,这样的框架没有真正解决开发者的问题,比如:
- 我想现在不想用unicloud,我想用传统服务器运行函数
- 我想和云平台解耦,我希望我的云函数的特性和功能实现和某一平台无关
- 我想使用ts开发
- 我想有IDE强力支持
- 我想使用一些开箱即用的方案,比如说hook,又比如HMR
- 我想使用ES开发nodejs程序,使用先进的技术对程序进行捆绑(treeshaking...)
- 如果要满足上面的特性,那么只有midway.js了,midway.js很酷,但是它并没有unicloud的faas插件,而且我希望框架能够让sword团队更好的构建程序,所以我们造一个轮子,来解决这些事情。
简单说说这个框架的技术栈
这款框架是我目前最得意的作品, 但是时间太仓促, 它的功能实现肯定不是最好的, 所以我需要各位的支持测试, 而且我也希望能拿到今年的插件大赛的名次; 去年拿到了三等奖也是我写的一款小程序, 今年带来的这个作品含金量非常高哈哈哈.
整个框架都是ts, 我使用了monorepo架构基于pnpm, 所有的源代码你都可以在packages中找到, 框架核心就是runtime那个文件夹. 整个框架最主要的2个部分就是cli + runtime, cli主要做多端的编译功能, 没错cli不仅做了打包还做了编译, 而且打包也是分环境的, 开发环境我是用的是swc (rust) 进行打包, 生产程序是使用esbuild (go), 所以极速是这个框架的特点, 不仅如此, runtime部分我实现了一个简易的异步依赖调度器使之不同平台, 都可以动态加载依赖, 所以server平台和unicloud平台互相不牵扯.
接下来, 我大概梳理一下我这个框架的特性, 希望你可以喜欢
- 完全拥抱TypeScript
- 支持跨平台: Server/阿里云/腾讯云/Cloudflare/AWS/Unicloud
- 基于文件系统的路由
- 开箱即用的开发套件
- TS运行时类型校验
- 生成API文档,兼容markdown以及openapi3.0
- 完全 Hook 的写法与设计
框架github地址: https://github.com/swordCodePractice/sword-framework
dcloud插件市场求支持求支持求支持: https://ext.dcloud.net.cn/plugin?id=8433
我们的中文文档: https://www.yuque.com/mlgrgm/lrf0ra
我们的官方网站: https://swordcodepractice.github.io/backend-framework-website/
现在支持私有部署同时也支持serverless各个平台的nodejs框架多么?答案是否定的,在2022年越来越多的企业会选择serverless来部署自己的应用,因为它足够轻巧省去了运维的成本,编写一个API可能只需要几行代码,越来越多的平台也推出了自己的云数据库以及云消息队列,我们前端开发编写后端api不再是一个头疼的事情。所以serverless是未来,为此我写了一个框架,它会在web服务器中运行也可以在serverless环境运行,在serverless中我会优先支持unicloud,我将使用这款框架参加2022年的dcloud插件大赛。
简单聊聊这款框架,我为什么要创建一款nodejs框架?
为什么要造轮子
在sword团队中我们使用unicloud构建应用程序,采用了CQRS,我们所有的写操作都由unicloud的云函数完成,但是你会发现在unicloud社区优秀的框架有很多,它们提供了url处理以及逻辑的分发,还有一些特色的框架也提供了诸如上传,和unicloud的部分特性封装,在我看来,这样的框架没有真正解决开发者的问题,比如:
- 我想现在不想用unicloud,我想用传统服务器运行函数
- 我想和云平台解耦,我希望我的云函数的特性和功能实现和某一平台无关
- 我想使用ts开发
- 我想有IDE强力支持
- 我想使用一些开箱即用的方案,比如说hook,又比如HMR
- 我想使用ES开发nodejs程序,使用先进的技术对程序进行捆绑(treeshaking...)
- 如果要满足上面的特性,那么只有midway.js了,midway.js很酷,但是它并没有unicloud的faas插件,而且我希望框架能够让sword团队更好的构建程序,所以我们造一个轮子,来解决这些事情。
简单说说这个框架的技术栈
这款框架是我目前最得意的作品, 但是时间太仓促, 它的功能实现肯定不是最好的, 所以我需要各位的支持测试, 而且我也希望能拿到今年的插件大赛的名次; 去年拿到了三等奖也是我写的一款小程序, 今年带来的这个作品含金量非常高哈哈哈.
整个框架都是ts, 我使用了monorepo架构基于pnpm, 所有的源代码你都可以在packages中找到, 框架核心就是runtime那个文件夹. 整个框架最主要的2个部分就是cli + runtime, cli主要做多端的编译功能, 没错cli不仅做了打包还做了编译, 而且打包也是分环境的, 开发环境我是用的是swc (rust) 进行打包, 生产程序是使用esbuild (go), 所以极速是这个框架的特点, 不仅如此, runtime部分我实现了一个简易的异步依赖调度器使之不同平台, 都可以动态加载依赖, 所以server平台和unicloud平台互相不牵扯.
接下来, 我大概梳理一下我这个框架的特性, 希望你可以喜欢
- 完全拥抱TypeScript
- 支持跨平台: Server/阿里云/腾讯云/Cloudflare/AWS/Unicloud
- 基于文件系统的路由
- 开箱即用的开发套件
- TS运行时类型校验
- 生成API文档,兼容markdown以及openapi3.0
- 完全 Hook 的写法与设计
框架github地址: https://github.com/swordCodePractice/sword-framework
dcloud插件市场求支持求支持求支持: https://ext.dcloud.net.cn/plugin?id=8433
我们的中文文档: https://www.yuque.com/mlgrgm/lrf0ra
我们的官方网站: https://swordcodepractice.github.io/backend-framework-website/

uni-app海外月活过亿,2022出海吧;uni-ad全面支持web和微信小程序;uni统计发布2.0版且全面开源
-
uni-app海外月活过亿,2022出海吧。详见:https://mp.weixin.qq.com/s/to1Zj9t684F6csFn7BJYTw
-
uni-ad新版发布,全面支持web和微信小程序
- 在App端聚合了全网所有主流广告源,包括腾讯优量汇、字节穿山甲、快手、百度、华为、360、Sigmob等十几家广告源以及自有广告客户,并通过优秀比价算法,提供了更高的广告出价
- uni-ad的微信小程序有更低的广告开通门槛,欢迎流量主体验。https://uniapp.dcloud.io/uni-ad.html
-
uni统计2.0版本发布,开源、私有部署、可自由定制。 https://uniapp.dcloud.net.cn/uni-stat-v2.html
-
uni-app海外月活过亿,2022出海吧。详见:https://mp.weixin.qq.com/s/to1Zj9t684F6csFn7BJYTw
-
uni-ad新版发布,全面支持web和微信小程序
- 在App端聚合了全网所有主流广告源,包括腾讯优量汇、字节穿山甲、快手、百度、华为、360、Sigmob等十几家广告源以及自有广告客户,并通过优秀比价算法,提供了更高的广告出价
- uni-ad的微信小程序有更低的广告开通门槛,欢迎流量主体验。https://uniapp.dcloud.io/uni-ad.html
-
uni统计2.0版本发布,开源、私有部署、可自由定制。 https://uniapp.dcloud.net.cn/uni-stat-v2.html