diff --git a/api/index/index.js b/api/index/index.js
index 4d2f84a..69257b0 100644
--- a/api/index/index.js
+++ b/api/index/index.js
@@ -32,4 +32,25 @@ export const selectCourseTitles = (data) => {
url: '/course/selectCourseTitles',
data
})
-}
\ No newline at end of file
+}
+
+// 抽奖
+export const selectDiscSpinning = (data) => {
+ return http.request({
+ url: '/discSpinning/selectDiscSpinning',
+ data
+ })
+}
+
+export const selectUserMoney = (data) => {
+ return http.request({
+ url: '/moneyDetails/selectUserMoney',
+ data
+ })
+}
+export const drawCount = (data) => {
+ return http.request({
+ url: '/discSpinning/drawCount',
+ data
+ })
+}
diff --git a/api/task/index.js b/api/task/index.js
new file mode 100644
index 0000000..562bab5
--- /dev/null
+++ b/api/task/index.js
@@ -0,0 +1,32 @@
+import http from '@/http/http.js'
+
+// 获取任务列表
+export const selectTaskCenter = (data) => {
+ return http.request({
+ url: '/taskCenter/selectTaskCenter',
+ data
+ })
+}
+// 获取签到
+export const getUserSignData = (data) => {
+ return http.request({
+ url: 'userSignRecord/getUserSignData',
+ data
+ })
+}
+// 任务-签到
+export const taskReceive = (data) => {
+ return http.request({
+ url: 'taskCenter/taskReceive',
+ data,
+ isreturm:true
+ })
+}
+
+// 任务列表
+export const selectDiscSpinning = (data) => {
+ return http.request({
+ url: 'discSpinning/selectDiscSpinning',
+ data,
+ })
+}
diff --git a/api/video/index.js b/api/video/index.js
new file mode 100644
index 0000000..5d5a696
--- /dev/null
+++ b/api/video/index.js
@@ -0,0 +1,9 @@
+import http from '@/http/http.js'
+
+//获取短剧视频详情
+export function getVideoDetail(data) {
+ return http.request({
+ url: 'course/courseSets?courseId='+data.courseId,
+ data
+ })
+}
\ No newline at end of file
diff --git a/commons/config.js b/commons/config.js
index 447803e..c55e9fe 100644
--- a/commons/config.js
+++ b/commons/config.js
@@ -17,7 +17,7 @@ export const AppConfig = {
local: 'http://192.168.1.41:8100'
}
-function returnShareUrl(){
+export function returnShareUrl(){
if(env==='test'){
return 'https://video-h5.hnsiyao.cn'
}
diff --git a/components/my-video-list/my-video-list.vue b/components/my-video-list/my-video-list.vue
index 96a79a3..445ebe9 100644
--- a/components/my-video-list/my-video-list.vue
+++ b/components/my-video-list/my-video-list.vue
@@ -1,20 +1,249 @@
-
+
+
+
+
+
+
+
+
+
+
+ {{item.courseDetailsName}}
+
+
+ {{item.courseDetailsName}}(共{{list.length}}集)选集 >
+
+
+
+
+
+
+ {{item.goodNum}}
+
+
+
+ 分享
+
+
+
+
+ {{isCollect?'已追':'追剧'}}
+
+
+
+
+
-
\ No newline at end of file
diff --git a/components/pop-ling-qu.vue b/components/pop-ling-qu.vue
new file mode 100644
index 0000000..e1b143c
--- /dev/null
+++ b/components/pop-ling-qu.vue
@@ -0,0 +1,163 @@
+
+
+
+
+ 恭喜您获得
+
+
+
+
+
+
+ {{result.name}}
+
+
+
+
+ {{result.number}}
+ 元
+
+
+ 现金红包
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/http/http.js b/http/http.js
index 79d3e2a..041d67f 100644
--- a/http/http.js
+++ b/http/http.js
@@ -14,7 +14,7 @@ function getHeader() {
}
// 通用处理逻辑
-function commonsProcess(showLoading, httpReqCallback) {
+function commonsProcess(showLoading, httpReqCallback,isreturm) {
// 判断是否请求完成(用作 是否loading )
// 包括: 'ing', 'ingLoading', 'finish'
let reqState = "ing";
@@ -41,11 +41,15 @@ function commonsProcess(showLoading, httpReqCallback) {
return httpReqCallback()
.then((httpData) => {
- reqFinishFunc(); // 请求完毕的动作
+
+ reqFinishFunc(); // 请求完毕的动作
// 从http响应数据中解构响应数据 [ 响应码、 bodyData ]
let { statusCode, data } = httpData;
// 避免混淆重新命名
let bodyData = data;
+ if(isreturm){
+ return Promise.resolve(bodyData.data || bodyData.page|| bodyData);
+ }
if (statusCode == 500) {
isShowErrorToast = true;
return Promise.reject(bodyData); // 跳转到catch函数
@@ -81,11 +85,12 @@ function commonsProcess(showLoading, httpReqCallback) {
code: bodyData.code,
});
}
+
// 构造请求成功的响应数据
return Promise.resolve(bodyData.data || bodyData.page|| bodyData);
})
.catch((res) => {
- console.log(res);
+
if (res.status == 404) {
infoBox.showErrorToast("接口404").then(() => {});
reject();
@@ -95,7 +100,7 @@ function commonsProcess(showLoading, httpReqCallback) {
if (res.code == 401) {
infoBox.showErrorToast(res.message || "请登录").then(() => {
uni.redirectTo({
- url: "/pages/login/index",
+ url: "/pages/login/login",
});
reject();
});
@@ -147,7 +152,8 @@ function request(args) {
params,
method = "GET",
showLoading = true,
- extParams = {}
+ extParams = {},
+ isreturm=false
} = args
if (params) {
let result = ''
@@ -170,7 +176,7 @@ function request(args) {
}, extParams)
)
- })
+ },isreturm)
}
// 处理/
function slash(baseUrl, url) {
diff --git a/pages.json b/pages.json
index fe6a09a..c8acf21 100644
--- a/pages.json
+++ b/pages.json
@@ -32,8 +32,7 @@
{
"path": "pages/task/index",
"style": {
- "navigationBarTitleText": "",
- "navigationStyle": "custom"
+ "navigationBarTitleText": "任务大厅"
}
}, {
"path": "pages/chasingDrama/index",
@@ -129,6 +128,29 @@
"style": {
"navigationBarTitleText": "搜索"
}
+ },
+ {
+ "path" : "pages/task/prizeList",
+ "style" :
+ {
+ "navigationBarTitleText" : "任务"
+
+ }
+ },
+ {
+ "path" : "pages/task/receiveMember",
+ "style" :
+ {
+ "navigationBarTitleText" : "",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path" : "pages/me/prizeDraw",
+ "style" :
+ {
+ "navigationBarTitleText" : "抽奖"
+ }
}
],
"globalStyle": {
diff --git a/pages/index/components/contentlist.vue b/pages/index/components/contentlist.vue
index 3f890a3..09a91b5 100644
--- a/pages/index/components/contentlist.vue
+++ b/pages/index/components/contentlist.vue
@@ -55,8 +55,8 @@
}
.liststyle:last-child {
- margin-right: auto;
- margin-left: 6rpx;
+ // margin-right: auto;
+ // margin-left: 6rpx;
}
}
\ No newline at end of file
diff --git a/pages/index/index.vue b/pages/index/index.vue
index 42d848e..13eed30 100644
--- a/pages/index/index.vue
+++ b/pages/index/index.vue
@@ -17,7 +17,7 @@
-
+
{{ item.title }}
@@ -25,25 +25,26 @@
-
+
最新
-
+
排行
-
+
最热
-
+
剧情
-
+
飙升
-
+
+
@@ -58,13 +59,12 @@
import {
reactive
} from 'vue';
-import { announcement, messageselectMessage,courseselectCourse } from '@/api/index/index.js'
+import { announcement, messageselectMessage, courseselectCourse } from '@/api/index/index.js'
import {
onLoad,
onReachBottom
} from '@dcloudio/uni-app'
import contentlist from './components/contentlist.vue'
-import http from '@/http/http.js'
let datas = reactive({
noticeList: [], //公告列表
@@ -90,22 +90,30 @@ onReachBottom(() => {
++datas.page
getrecomVideo()
})
-
+// 跳转公告链接
+function goMsg(url) {
+ // if (url.indexOf('/pages/') !== -1 || url.indexOf('/me/') !== -1) {
+ uni.navigateTo({
+ url: '/pages/me/prizeDraw'
+ });
+ // } else {
+ //#ifndef H5
+ // uni.navigateTo({
+ // url: '/pages/index/webView?url=' + url
+ // });
+ //#endif
+ //#ifdef H5
+ // window.location.href = url;
+ //#endif
+ // }
+}
// 获取弹窗信息
async function getPop() {
let res = await announcement()
- if (res.code == 0) {
- if (res.data && res.data.state == 1) {
- datas.ruleShow = true
- datas.rule_title = res.data.title
- datas.rule_content = res.data.content
- }
- } else {
- uni.showToast({
- title: res.msg,
- duration: 1000,
- icon: 'none'
- });
+ if (res.state == 1) {
+ datas.ruleShow = true
+ datas.rule_title = res.title
+ datas.rule_content = res.content
}
}
// 搜索跳转
@@ -117,15 +125,7 @@ function moreVideo() {
// 公告
async function getMsg() {
let res = await messageselectMessage()
- if (res.code == 0) {
- datas.noticeList = res.data.list
- } else {
- uni.showToast({
- title: res.msg,
- duration: 1000,
- icon: 'none'
- });
- }
+ datas.noticeList = res.list
}
//获取推荐视频
async function getrecomVideo(sort, active = 1) {
@@ -140,18 +140,10 @@ async function getrecomVideo(sort, active = 1) {
classifyId: ''
})
- if (res.code == 0) {
- if (datas.page == 1) {
- datas.list = res.data.list
- } else {
- datas.list = [...datas.list, ...res.data.list]
- }
+ if (datas.page == 1) {
+ datas.list = res.list
} else {
- uni.showToast({
- title: res.msg,
- duration: 1000,
- icon: 'none'
- });
+ datas.list = [...datas.list, ...res.list]
}
}
@@ -225,6 +217,10 @@ async function getrecomVideo(sort, active = 1) {
}
+.navTop-active {
+ color: #cb5d68;
+}
+
.navTop {
display: flex;
align-items: center;
diff --git a/pages/index/search/index.vue b/pages/index/search/index.vue
index 12816f4..312970a 100644
--- a/pages/index/search/index.vue
+++ b/pages/index/search/index.vue
@@ -2,47 +2,58 @@
-
+ @search="doSearch()">
-
+
-
-
+
+
{{ keyword }}
-
- 当前搜热已隐藏
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/me/almost-lottery copy/changelog.md b/pages/me/almost-lottery copy/changelog.md
new file mode 100644
index 0000000..3d6673c
--- /dev/null
+++ b/pages/me/almost-lottery copy/changelog.md
@@ -0,0 +1,249 @@
+## 1.9.7(2023-08-02)
+本次更新:
+- 调整 `draw-before` 为自定义函数,且该函数为必备函数,转盘能否启动,将根据该函数中调用 `callback` 时传递的 `Boolean` 进行判断
+## 1.9.6.2(2023-07-28)
+本次更新:
+- 更新示例项目
+## 1.9.6.1(2023-07-28)
+本次更新:
+- 修复参数文档排版问题
+## 1.9.6(2023-07-28)
+本次更新:
+- 新增`drawStartBefore`钩子,请看说明文档
+## 1.9.5(2023-07-12)
+本次更新:
+- 优化 `duration` 参数的变更需要刷新才能生效的开发体验
+- 新增 `duration` 和 `ringCount` 设置不合理时的 `console` 提醒
+## 1.9.4(2023-07-06)
+本次更新:
+- 修复某些情况文字无法换行的问题
+- 参数`strMaxLen`设置为`0`时不限制文字长度
+## 1.9.3(2023-06-12)
+本次更新:
+- 新增 `selfTime` 参数,查看文档说明
+- 示例项目分离 `uni-popup` 用例为独立页面进行展示
+## 1.9.2(2023-05-22)
+本次更新:
+- 新增 `renderDelay` 参数,请查看文档
+- 示例项目新增 `ui-popup` 组件的用例,使用 `uni-popup` 包裹转盘时,请前往 `uni-popup` 组件文档关注平台兼容性问题
+## 1.9.1(2023-03-07)
+本次更新:
+- 新增 `selfRotaty` 自转参数,视觉效果上存在细微瑕疵,欢迎PR
+## 1.8.33(2022-07-04)
+本次更新:
+- 统一奖品图片下载方式
+## 1.8.32(2022-06-20)
+本次更新:
+- 调整平台兼容性(因 HBX 存在 bug,导致平台兼容性的更新多次失败,近几次的更新都可以忽略)
+## 1.8.31(2022-06-20)
+本次更新:
+- 无意义的更新,请忽略
+## 1.8.30(2022-06-20)
+本次更新:
+- 调整平台兼容性
+## 1.8.29(2022-06-19)
+本次更新:
+- 调整平台兼容信息
+## 1.8.28(2022-06-19)
+本次更新:
+- 修复单个尺寸过大的 canvas 在 H5/APP-vue iOS/Safari 中存在可能无法绘制成功的问题
+## 1.8.27(2022-06-01)
+本次更新:
+- 优化示例项目
+## 1.8.26(2022-06-01)
+本次更新:
+- 修复奖品图片裁切为圆形时在安卓机器不显示的问题
+## 1.8.25(2022-05-31)
+本次更新:
+- 修复部分安卓下载图片得到.unknown格式文件的问题
+## 1.8.24(2022-05-09)
+本地缓存:
+- 优化示例项目
+## 1.8.23(2022-05-09)
+本地缓存:
+- 优化清除文件缓存的方法
+## 1.8.22(2022-05-09)
+本次更新:
+- 调整计算转盘绘制的方式
+## 1.8.21(2022-05-08)
+本次更新:
+- 调整示例项目中本地图片的引入方式
+## 1.8.20(2022-04-29)
+本次更新:
+- 修复转盘在某个临界点可以出现多次触发的问题
+## 1.8.19(2022-04-27)
+本次更新:
+- 奖品文字的绘制由先前的两行变成多行,根据设定的每行文字的长度分段绘制
+## 1.8.18(2022-04-25)
+本次更新:
+- 减少小程序平台的 delay
+## 1.8.17(2022-03-23)
+本次更新:
+- 新增配置项 `imgCircled` 奖品图片是否裁切为圆形,默认不裁切
+## 1.8.16(2022-03-04)
+本次更新:
+- 示例项目新增绘制时长的计算,方便开发时定位绘制慢的问题
+## 1.8.15(2022-03-02)
+本次更新:
+- 优化一处错误提示信息的展现方式
+## 1.8.14(2021-11-29)
+本次更新:
+- 示例项目中新增开放自定义权重最大值,没有自定义则取权重数组中的最大值
+- 更新文档
+## 1.8.13(2021-11-03)
+本次更新:
+- 注释 `1.8.12` 版本中调试时的代码
+## 1.8.12(2021-11-03)
+本次更新:
+- 修复一些老机型不支持 `flex` 导致布局错乱的问题
+## 1.8.11(2021-10-29)
+本次更新:
+- 优化示例项目中模拟接口访问的速度
+## 1.8.10(2021-10-19)
+本次更新:
+- 优化组件代码
+- 更新示例项目
+## 1.8.9(2021-09-28)
+本次更新:
+- 移除内置的 `奖品准备中...` 提示
+## 1.8.8(2021-09-27)
+本次更新:
+- 修复 `1.8.6` 引起的非微信小程序平台绘制异常的问题
+## 1.8.7(2021-09-23)
+本次更新:
+- 优化项目中使用到的图片大小
+## 1.8.6(2021-09-23)
+本次更新:
+- 修复小程序平台在绘制 `base64` 格式的图片时无法在真机模式下正常显示的问题
+## 1.8.5(2021-09-13)
+本次更新:
+- 修复一个已知问题
+## 1.8.4(2021-09-12)
+本次更新:
+- 调整 `strFontColor` 为 `strFontColors`,现在可以设置每个区块的文字颜色,详见文档说明
+## 1.8.3(2021-09-12)
+本次更新:
+- 修复因 `1.8.0` 改动引起的文字方向、无奖品图时绘制异常的问题
+- 新增 `imgDrawed` 是否绘制奖品图片的配置项 ,默认为 `true`
+## 1.8.2(2021-09-10)
+本次更新:
+**不兼容旧版本的更新**
+- 移除配置项 `strKey` 字段
+- 调整 `prizeList` 结构
+## 1.8.1(2021-09-06)
+本次更新:
+- 修复 `hbx3.1.22` 在小程序平台处理 `id-name` 存在解析错误的问题
+## 1.8.0(2021-09-06)
+本次更新:
+**该版本更新涉及破坏性的变更,请重新查看 `API - Props` 的部分**
+- `px` 全面调整为 `rpx` 单位,多个`Props` 的参数相应调整,请查看文档
+ - 新增 `pixelRatio` 参数,该参数为设计稿的设备像素比基准值,默认为 `2` 倍素
+## 1.7.18(2021-09-05)
+本次更新:
+- 修复一个已知问题
+## 1.7.17(2021-08-23)
+本次更新:
+- 更新示例项目
+## 1.7.16(2021-08-14)
+本次更新:
+- 更新示例项目
+## 1.7.15(2021-08-03)
+本次更新:
+- 新增文字竖向展示的功能,详见文档说明
+## 1.7.13(2021-08-02)
+本次更新:
+- 更新文档
+## 1.7.12(2021-07-30)
+本次更新:
+- 修复示例项目的已知问题
+- 现已提供Almost-Lottery抽奖转盘的uniCloud云端一体页面模板
+- 现已提供Almost-Lottery抽奖转盘云端一体页面配套的Admin配置中心
+## 1.7.11(2021-07-22)
+本次更新:
+- 修复部分安卓手机文字大小异常的问题
+- 字段 `strHeightMultiple` 更换为 `strLineHeight`
+## 1.7.10(2021-07-12)
+本次更新:
+- 修复奖品名称 `name` 为空字符串时无法成功绘制转盘的问题
+- 新增 `prizeNameDrawed` 是否绘制奖品名称的配置项,现在可以仅展示奖品图片了
+## 1.7.9(2021-07-09)
+本次更新:
+- 优化组件内部代码
+- 修复奖品图片已然是 `base64` 格式时导致转盘绘制失败的问题
+- 文档新增QQ群号,让沟通更便捷
+## 1.7.8(2021-07-08)
+本次更新:
+- 调整 `Canvas` 默认宽高为 `280`
+## 1.7.7(2021-07-08)
+本次更新:
+- 新增多个配置项,满足更多自定义需求
+- 优化多行文本情况下非中文字符的字节处理
+- 修复偶发的第一条数据文本不居中显示的问题
+## 1.7.6(2021-07-02)
+本次更新:
+- 调整 `imageWidth` 、 `imageHeight` 字段为 `imgWidth` 、 `imgHeight`
+- 更新示例项目
+## 1.7.5(2021-07-01)
+本次更新:
+- 新增配置项 `imgMarginStr` 奖品图片距离奖品文字的距离
+## 1.7.4(2021-06-28)
+本次更新:
+- 新增轮盘旋转或指针旋转配置项
+- 转盘内置的外环图片以及按钮图片统一调整为 `image` 展示
+- 更新相关文档说明
+## 1.7.3(2021-06-16)
+本次更新:
+- 优化错误提示
+- 优化示例项目
+- 优化文档说明
+## 1.7.2(2021-06-11)
+本次更新:
+- 新增 `canvasId` 参数配置项,多画板情况下需要配置不同的 `canvasId`
+- 优化多画板情况下的缓存功能
+- 优化示例项目
+- 修改文档说明
+## 1.7.1(2021-06-10)
+本次更新:
+- 优化示例项目中的注释
+## 1.7.0(2021-06-04)
+本次更新:
+- 修复 `1.6.1` 引起的多行奖品文字行高异常的问题
+- 新增配置转盘外环和抽奖按钮图片的功能,详见文档说明
+- 更新示例项目,新增抽奖次数等业务有关的逻辑供参考
+## 1.6.1(2021-05-28)
+本次更新:
+- 修复小程序平台画板模糊的问题
+## 1.6.0(2021-05-28)
+本次更新:
+- 新增奖品区块是否开启描边的配置项,默认不开启
+- 调整画板缓存为默认不开启
+- 优化代码
+- 优化文档说明
+- 更新示例项目并修改部分注释
+## 1.5.13(2021-05-22)
+本次更新:
+- 优化文档说明
+- 更新示例项目
+## 1.5.12(2021-05-22)
+本次更新:
+- 新增配置项 `strokeColor` 奖品区块边框颜色
+- 更新文档说明
+## 1.5.11(2021-05-19)
+本次更新:
+- 新增`strMarginOutside`参数,用于设置奖品文字距离边缘的距离
+- 修复奖品文字在某些情况下不是居中显示的问题
+## 1.5.10(2021-05-19)
+本次更新:
+- 修复示例项目中权重值相同时的取值逻辑
+## 1.5.9(2021-05-14)
+本次更新:
+- 调整代码,优化小程序端的展示
+## 1.5.8(2021-05-12)
+本次更新:
+- 文档增加预警提示:不再维护非 `uni_modules` 模式下的版本
+## 1.5.7(2021-05-12)
+本次更新:
+- 修复小程序平台奖品名称不清晰的问题
+## 1.5.6(2021-03-18)
+本次更新:
+- 适配 uni_modules 插件模式
diff --git a/pages/me/almost-lottery copy/components/almost-lottery/almost-lottery.vue b/pages/me/almost-lottery copy/components/almost-lottery/almost-lottery.vue
new file mode 100644
index 0000000..faf7f2e
--- /dev/null
+++ b/pages/me/almost-lottery copy/components/almost-lottery/almost-lottery.vue
@@ -0,0 +1,1087 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ measureText }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/me/almost-lottery copy/package.json b/pages/me/almost-lottery copy/package.json
new file mode 100644
index 0000000..5a58e96
--- /dev/null
+++ b/pages/me/almost-lottery copy/package.json
@@ -0,0 +1,85 @@
+{
+ "id": "almost-lottery",
+ "displayName": "Almost-Lottery抽奖转盘",
+ "version": "1.9.7",
+ "description": "【荣获2021插件大赛三等奖】提供奇数、缓存等众多配置项,更有抽奖概率、抽奖次数、付费抽奖等功能内置于示例项目中,完美支持APP、各平台小程序、H5、PC,同时提供 uniCloud 云端版本",
+ "keywords": [
+ "转盘",
+ "抽奖",
+ "转盘抽奖",
+ "大转盘",
+ "大转盘抽奖"
+],
+ "repository": "https://github.com/ialmost/almost-components_uniapp",
+ "engines": {
+ "HBuilderX": "^3.7.11"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "n"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y",
+ "钉钉": "y",
+ "快手": "y",
+ "飞书": "y",
+ "京东": "y"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "n"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/pages/me/almost-lottery copy/readme.md b/pages/me/almost-lottery copy/readme.md
new file mode 100644
index 0000000..cd74ad3
--- /dev/null
+++ b/pages/me/almost-lottery copy/readme.md
@@ -0,0 +1,174 @@
+# almost-lottery
+*使用 Canvas 绘制的抽奖转盘,提供奇数、缓存等众多配置项,更有抽奖概率、抽奖次数、付费抽奖等功能内置于示例项目中*
+
+
+>
+>
+> 如果用着还行,请支持一下
+> - 前往 [GitHub](https://github.com/ialmost/almost-components_uniapp) 给个 Star
+> - 前往 [UniApp](https://ext.dcloud.net.cn/plugin?id=1030) 给个五星
+> - 使用中遇到问题时,可以添加 **QQ群 20441313**
+>
+>
+
+
+## 基于 uniCloud 开发的云端 Almost-Lottery 抽奖转盘,欢迎尝试体验
+- [Almost-Lottery抽奖转盘的云端一体页面](https://ext.dcloud.net.cn/plugin?id=5763)
+- [Almost-Lottery抽奖转盘的配置中心](https://ext.dcloud.net.cn/plugin?id=5762)
+
+
+## 高能预警
+- 本插件仅支持 `uni_modules` 模式,强烈推荐使用该模式,**非 `uni_modules` 模式不再维护**
+- 在使用本插件之前,强烈建议使用 `HBuilderX` 导入示例项目验证可用性并参照修改
+
+## 功能概要
+- [x] 可配置奖品文字 **支持横向/竖向展示**
+- [x] 可配置每个奖品区块的背景颜色
+- [x] 可配置每个奖品区块的奖品文字颜色
+- [x] 可配置奖品区块是否开启描边以及边框的颜色,默认不开启
+- [x] 可配置转盘外环和抽奖按钮图
+- [x] 可配置每个奖品区块的奖品图片,**当图片是网络地址时,小程序端需要配置白名单,H5端需要允许跨域,奖品文字为竖向时不支持展示奖品图片**
+- [x] 奖品列表支持奇数,**奇数时需尽量能被 `360` 除尽**
+- [x] 可配置内圈与外圈的间距
+- [x] 可配置轮盘旋转或指针旋转
+- [x] 可配置画板是否缓存,默认不开启
+- [x] 更多配置请查看API说明
+
+## 示例项目附加功能
+- [x] 中奖概率,**强烈推荐中奖概率应由后端控制**
+- [x] 抽奖次数
+- [x] 付费抽奖
+
+
+## 注意事项
+
+- 编译到小程序端时,请务必勾选ES6转ES5
+
+- `@reset-index="prizeIndex = -1"` 必须默认写入到 `template` 中,不可删除
+
+- 每个奖品区块的奖品图片尺寸不宜过大,图片越大,绘制的过程越慢,尽量将图片尺寸控制在 `100*100` 以内,且图片大小控制在 `40KB` 以内
+
+- 关于中奖概率的配置,请下载示例项目,参照 `pages/index/index.vue` 中的代码进行配置
+
+- 组件本身不涉及任何业务逻辑,与业务相关的代码建议都放在 `pages/index/index.vue` 中
+
+
+## 代码演示
+#### 基础用法
+```
+// template
+// @reset-index="prizeIndex = -1" 必须默认写入到 template 中,不可删除
+
+
+// script
+import AlmostLottery from '@/uni_modules/almost-lottery/components/almost-lottery/almost-lottery.vue'
+export default {
+ components: {
+ AlmostLottery
+ },
+ data () {
+ return {
+ // 以下是奖品配置数据
+ // 奖品数据
+ prizeList: [],
+ // 中奖下标
+ prizeIndex: -1
+ }
+ },
+ methods: {
+ // 本次抽奖开始之前
+ handleDrawStart (callback) {
+ // 这里需要处理你抽奖之前的逻辑
+ // 请查看示例项目中的代码
+ // 必须调用 callback 并传递一个布尔值,布尔值为 true 时,转盘才会开始旋转
+ let flag = true
+
+ callback(flag)
+ },
+ // 本次抽奖开始
+ handleDrawStart () {
+ // 这里需要处理你的抽奖逻辑,并得出中奖物品的 prizeIndex
+ // 请查看示例项目中的代码
+ },
+ // 本次抽奖结束
+ handleDrawEnd () {
+ // 完成抽奖后,这里处理你拿到结果后的逻辑
+ // 请查看示例项目中的代码
+ },
+ // 抽奖转盘绘制完成
+ handleDrawFinish (res) {
+ // 抽奖转盘准备就绪后,这里处理你的逻辑
+ // 请查看示例项目中的代码
+ // console.log('抽奖转盘绘制完成', res)
+ }
+ }
+}
+```
+
+## API
+#### Props
+参数 | 说明 | 类型 | 默认值
+:---|:---|:---|:---
+pixelRatio | 移动端设计稿的像素比基准值,**涉及到 `rpx` 的适配问题** | *`Number`* | `2`
+canvasId | Canvas的标识,**多画板情况下需要配置不同的标识** | *`String`* | `'almostLottery'`
+renderDelay | 转盘的渲染延时,**转盘被包裹在 uni-popup 组件内且开启了动画,请设置成最少 300** | *`Number`* | `0`
+lotterySize | 抽奖转盘的整体尺寸,单位 `rpx` | *`Number`* | `600`
+actionSize | 抽奖按钮的尺寸,单位 `rpx` | *`Number`* | `200`
+canvasMarginOutside | Canvas边缘距离转盘边缘的距离,单位`rpx` | *`Number`* | `90`
+prizeIndex | 获奖奖品在奖品列表中的序号,**每次抽奖结束后会自动重置为 `-1`** | *`Number`* | `-1`
+prizeList | 奖品列表,支持奇数(尽量能被 `360` 除尽),**为奇数时需要重设 `colors` 参数** | *`Array`* | -
+lotteryBg | 转盘外环图片 | `String` | `默认内置的本地图片`
+actionBg | 抽奖按钮图片 | `String` | `默认内置的本地图片`
+colors | 奖品区块对应的背景颜色,默认 2 个颜色相互交替,**也可以对每个区块设置不同颜色** | *`Array`* | `['#FFFFFF', '#FFBF05']`
+prizeNameDrawed | 是否绘制奖品名称 | *`Boolean`* | `true`
+stroked | 是否开启奖品区块描边 | *`Boolean`* | `false`
+strDirection | 奖品名称展示方向,可选值 `'horizontal'` => 横向 `'vertical'` => 竖向 | *`String`* | `'horizontal'`
+strokeColor | 奖品区块边框颜色 | *`String`* | `'#FFBF05'`
+rotateType | 旋转的类型,可选值 `'roulette'` => 轮盘旋转 `'pointer'` => 指针旋转 | *`String`* | `'roulette'`
+selfRotaty | 是否开启自转,开启后`duration`和`ringCount`参数不生效 | *`Boolean`* | `false`
+selfTime | 开启自转时,最少转多少毫秒 | *`Number`* | `1000`
+duration | 转盘旋转的动画时长,单位:秒 | *`Number`* | `8`
+ringCount | 旋转的圈数 | *`Number`* | `8`
+pointerPosition | 点击抽奖按钮指针的位置,可选值 `'edge'` => 指向边界 `'middle'` => 指向中间 | *`String`* | `'edge'`
+strFontColors | 奖品文字颜色,默认 2 个颜色相互交替,**也可以对每个区块的文字设置不同颜色,或仅设置一个颜色** | *`Array`* | `['#FFBF05', '#FFFFFF']`
+strFontSize | 奖品名称的字号,单位 `rpx` | *`Number`* | `24`
+strLineHeight | 奖品名称多行情况下的行高 | *`Number`* | `1.2`
+strMaxLen | 奖品名称长度限制,为`0`时不限制,**文字竖向时不生效** | *`Number`* | `12`
+strLineLen | 奖品名称在多行情况下第一行文字的长度,**文字竖向时不生效** | *`Number`* | `6`
+strMarginOutside | 奖品文字相对轮盘边缘的距离,单位 `rpx` | *`Number`* | `strFontSize 的一半`
+imgMarginStr | 奖品图片相对奖品文字的距离,单位 `rpx` | *`Number`* | `60`
+imgWidth | 奖品图片的宽度,单位 `rpx` | *`Number`* | `50`
+imgHeight | 奖品图片的高度,单位 `rpx` | *`Number`* | `50`
+imgDrawed | 是否绘制奖品图片,默认绘制 | *`Boolean`* | `true`
+imgCircled | 奖品图片是否裁切为圆形,默认不裁切 | *`Boolean`* | `false`
+successMsg | 转盘绘制成功的提示 | *`String`* | `'奖品准备就绪,快来参与抽奖吧'`
+failMsg | 转盘绘制失败的提示 | *`String`* | `'奖品仍在准备中,请稍后再来...'`
+canvasCached | 是否开启缓存,避免在数据不变的情况下重复绘制,建议在生产环境中开启 | *`Boolean`* | `false`
+
+#### Events
+事件名 | 说明 | 回调参数
+:---|:---|:---|:---
+@reset-index | 每次抽奖结束后重置获奖的序号为 `-1`,**该事件必须默认写入到 `template` 中,不可删除** | -
+@draw-before | 转盘旋转之前触发,**该事件必须默认写入到 `template` 中,不可删除** | `callback(Boolean)`
+@draw-start | 转盘旋转开始时触发 | -
+@draw-end | 转盘旋转结束时触发 | -
+@finish | Canvas转盘绘制完成时触发 | `{ ok: 绘制是否成功, data: 转盘的图片, msg: 绘制结果的提示 }`
+
+#### prizeList 数据结构
+*请按如下数据字段对你的奖品列表数据结构进行调整*
+键名 | 说明 | 类型
+:---|:---|:---
+prizeId | 奖品对应 `ID` | *`Number`*
+prizeName | 奖品名称 | *`String`*
+prizeStock | 奖品库存 | *`Number`*
+prizeWeight | 奖品权重 | *`Number`*
+prizeImage | 奖品图片地址,网络图片仅支持`http`和`https`协议 | *`String`*
\ No newline at end of file
diff --git a/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__action.png b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__action.png
new file mode 100644
index 0000000..2e221a4
Binary files /dev/null and b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__action.png differ
diff --git a/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__action2x.png b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__action2x.png
new file mode 100644
index 0000000..10d497f
Binary files /dev/null and b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__action2x.png differ
diff --git a/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__action3x.png b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__action3x.png
new file mode 100644
index 0000000..5e3b8d3
Binary files /dev/null and b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__action3x.png differ
diff --git a/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__bg.png b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__bg.png
new file mode 100644
index 0000000..be39367
Binary files /dev/null and b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__bg.png differ
diff --git a/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__bg2x.png b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__bg2x.png
new file mode 100644
index 0000000..3fe4efd
Binary files /dev/null and b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__bg2x.png differ
diff --git a/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__bg3x.png b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__bg3x.png
new file mode 100644
index 0000000..bcd70e1
Binary files /dev/null and b/pages/me/almost-lottery copy/static/almost-lottery/almost-lottery__bg3x.png differ
diff --git a/pages/me/almost-lottery copy/utils/almost-utils.js b/pages/me/almost-lottery copy/utils/almost-utils.js
new file mode 100644
index 0000000..cd41164
--- /dev/null
+++ b/pages/me/almost-lottery copy/utils/almost-utils.js
@@ -0,0 +1,298 @@
+/**
+ * 存储 localStorage 数据
+ * @param {String} name - 缓存数据的标识
+ * @param {any} content - 缓存的数据内容
+ */
+export const setStore = (name, content) => {
+ if (!name) return
+ if (typeof content !== 'string') {
+ content = JSON.stringify(content)
+ }
+ uni.setStorageSync(name, content)
+}
+
+/**
+ * 获取 localStorage 数据
+ * @param {String} name - 缓存数据的标识
+ */
+export const getStore = (name) => {
+ if (!name) return
+ return uni.getStorageSync(name)
+}
+
+/**
+ * 清除 localStorage 数据
+ * @param {String} name - 缓存数据的标识
+ */
+export const clearStore = (name) => {
+ if (name) {
+ uni.removeStorageSync(name)
+ } else {
+ console.log('清理本地全部缓存')
+ uni.clearStorageSync()
+ }
+}
+
+/**
+ * 绘制圆形
+ * @param {String} ctx - 图片网络地址
+ * @param {String} img - 图片地址
+ * @param {String} x - x 轴偏移量
+ * @param {String} y - y 轴偏移量
+ * @param {String} w - 宽
+ * @param {String} h - 高
+*/
+export const circleImg = (ctx, img, x, y, w, h) => {
+ let r = Math.floor(w/2)
+ let cx = x + r
+ let cy = y + r
+
+ ctx.save()
+ ctx.beginPath()
+ ctx.arc(cx, cy, r, 0, Math.PI * 2)
+ ctx.fill()
+ ctx.clip()
+ ctx.drawImage(img, x, y, w, h)
+ ctx.restore()
+}
+
+/**
+ * 计算文本的长度
+ * @param {String} text - 文本内容
+ */
+export const clacTextLen = (text) => {
+ if (!text) return { byteLen: 0, realLen: 0 }
+ text += ''
+ let clacLen = 0
+ for (let i = 0; i < text.length; i++) {
+ if ((text.charCodeAt(i) < 0) || (text.charCodeAt(i) > 255)) {
+ clacLen += 2
+ } else {
+ clacLen += 1
+ }
+ }
+ // console.log(`当前文本 ${text} 的长度为 ${clacLen / 2}`)
+ return {
+ byteLen: clacLen,
+ realLen: clacLen / 2
+ }
+}
+
+/**
+ * 下载文件,并返回临时路径
+ * @return {String} 临时路径
+ * @param {String} fileUrl - 网络地址
+*/
+export const downloadFile = (fileUrl) => {
+ return new Promise((resolve) => {
+ uni.downloadFile({
+ url: fileUrl,
+ success: (res) => {
+ resolve({
+ ok: true,
+ data: res.errMsg,
+ tempFilePath: res.tempFilePath
+ })
+ },
+ fail: (err) => {
+ resolve({
+ ok: false,
+ data: err.errMsg,
+ msg: '图片下载失败'
+ })
+ }
+ })
+ })
+}
+
+/**
+ * 清理应用已缓存的文件
+*/
+export const clearCacheFile = () => {
+ // #ifndef H5
+ uni.getSavedFileList({
+ success: (res) => {
+ let fileList = res.fileList
+ if (fileList.length) {
+ for (let i = 0; i < fileList.length; i++) {
+ uni.removeSavedFile({
+ filePath: fileList[i].filePath,
+ complete: () => {
+ console.log('清除缓存已完成')
+ }
+ })
+ }
+ }
+ },
+ fail: (err) => {
+ console.log('getSavedFileList Fail')
+ }
+ })
+ // #endif
+}
+
+
+
+// 图像转换工具,可用于图像和base64的转换
+// https://ext.dcloud.net.cn/plugin?id=123
+const getLocalFilePath = (path) => {
+ if (
+ path.indexOf('_www') === 0 ||
+ path.indexOf('_doc') === 0 ||
+ path.indexOf('_documents') === 0 ||
+ path.indexOf('_downloads') === 0
+ ) return path
+
+ if (path.indexOf('/storage/emulated/0/') === 0) return path
+
+ if (path.indexOf('/storage/sdcard0/') === 0) return path
+
+ if (path.indexOf('/var/mobile/') === 0) return path
+
+ if (path.indexOf('file://') === 0) return path
+
+ if (path.indexOf('/') === 0) {
+ // ios 无法获取本地路径
+ let localFilePath = plus.os.name === 'iOS' ? path : plus.io.convertLocalFileSystemURL(path)
+ if (localFilePath !== path) {
+ return localFilePath
+ } else {
+ path = path.substring(1)
+ }
+ }
+
+ return '_www/' + path
+}
+
+export const pathToBase64 = (path) => {
+ return new Promise((resolve, reject) => {
+ if (typeof window === 'object' && 'document' in window) {
+ if (typeof FileReader === 'function') {
+ let xhr = new XMLHttpRequest()
+ xhr.open('GET', path, true)
+ xhr.responseType = 'blob'
+ xhr.onload = function() {
+ if (this.status === 200) {
+ let fileReader = new FileReader()
+ fileReader.onload = function(e) {
+ resolve(e.target.result)
+ }
+ fileReader.onerror = reject
+ fileReader.readAsDataURL(this.response)
+ }
+ }
+ xhr.onerror = reject
+ xhr.send()
+ return
+ }
+ let canvas = document.createElement('canvas')
+ let c2x = canvas.getContext('2d')
+ let img = new Image
+ img.onload = function() {
+ canvas.width = img.width
+ canvas.height = img.height
+ c2x.drawImage(img, 0, 0)
+ resolve(canvas.toDataURL())
+ canvas.height = canvas.width = 0
+ }
+ img.onerror = reject
+ img.src = path
+ return
+ }
+
+ if (typeof plus === 'object') {
+ let tempPath = getLocalFilePath(path)
+ plus.io.resolveLocalFileSystemURL(tempPath, (entry) => {
+ entry.file((file) => {
+ let fileReader = new plus.io.FileReader()
+ fileReader.onload = function(data) {
+ resolve(data.target.result)
+ }
+ fileReader.onerror = function(error) {
+ console.log(error)
+ reject(error)
+ }
+ fileReader.readAsDataURL(file)
+ }, (error) => {
+ reject(error)
+ })
+ }, (error) => {
+ reject(error)
+ })
+ return
+ }
+
+ if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
+ wx.getFileSystemManager().readFile({
+ filePath: path,
+ encoding: 'base64',
+ success: (res) => {
+ resolve('data:image/png;base64,' + res.data)
+ },
+ fail: (error) => {
+ reject(error)
+ }
+ })
+ return
+ }
+ reject(new Error('not support'))
+ })
+}
+
+export const base64ToPath = (base64) => {
+ return new Promise((resolve, reject) => {
+ if (typeof window === 'object' && 'document' in window) {
+ base64 = base64.split(',')
+ let type = base64[0].match(/:(.*?);/)[1]
+ let str = atob(base64[1])
+ let n = str.length
+ let array = new Uint8Array(n)
+ while (n--) {
+ array[n] = str.charCodeAt(n)
+ }
+ return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], {
+ type: type
+ })))
+ }
+ let extName = base64.match(/data\:\S+\/(\S+);/)
+ if (extName) {
+ extName = extName[1]
+ } else {
+ reject(new Error('base64 error'))
+ }
+ let fileName = Date.now() + '.' + extName
+ if (typeof plus === 'object') {
+ let bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+ bitmap.loadBase64Data(base64, () => {
+ let filePath = '_doc/uniapp_temp/' + fileName
+ bitmap.save(filePath, {}, () => {
+ bitmap.clear()
+ resolve(filePath)
+ }, (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ }, (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ return
+ }
+ if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
+ let filePath = wx.env.USER_DATA_PATH + '/' + fileName
+ wx.getFileSystemManager().writeFile({
+ filePath: filePath,
+ data: base64.replace(/^data:\S+\/\S+;base64,/, ''),
+ encoding: 'base64',
+ success: () => {
+ resolve(filePath)
+ },
+ fail: (error) => {
+ reject(error)
+ }
+ })
+ return
+ }
+ reject(new Error('not support'))
+ })
+}
diff --git a/pages/me/prizeDraw.vue b/pages/me/prizeDraw.vue
new file mode 100644
index 0000000..61e1a84
--- /dev/null
+++ b/pages/me/prizeDraw.vue
@@ -0,0 +1,764 @@
+
+
+
+
+
+
+
+
+
+ 红包
+ {{ totalMoney }}
+
+
+
+
+ 我的奖品
+
+
+
+
+
+
+
+
+
+
+
+ 剩余免费抽奖 {{ freeNum }} 次
+
+
+
+
+
+
+
+
+ 活动规则
+
+
+
+
+ 1
+
+ 抽奖细则:
+ 每日前{{ freeNumDay }}次付款均可获得抽奖机会
+
+
+
+ 2
+
+ 奖励说明:红包奖励将自动发放到红包余额,已绑定支付宝账号将会自动发起提现。其余奖品则需联系客服领取。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/task/index.vue b/pages/task/index.vue
index b15bdca..93bc129 100644
--- a/pages/task/index.vue
+++ b/pages/task/index.vue
@@ -1,11 +1,415 @@
- ios
- anzhuo
+
+
+
+
+
+
+
+ 新人好礼送不停
+
+
+
+
+
+
+ 已连续签到 {{ datas.signDays }} 天
+
+
+
+ {{ item.status == 1 ? '已签到' : '待签到' }}
+
+ {{ item.signDay.substr(5, 8) }}
+
+
+
+
+
+
+
+
+
+
+ {{
+ item.title
+ }}
+
+ {{ item.rewardDetail }}
+
+ {{ item.detail }}
+
+
+
+ {{ item.type == 1 ? item.buttonTitle : item.number ? `${item.discNumber}/${item.number}` : (
+ item.discNumber <= 0 ? item.buttonTitle : `剩余${item.discNumber}次`) }}
+
+ {{ item.type == 1 ? item.buttonTitle : item.number ? `${item.discNumber}/${item.number}`
+ : (item.discNumber <= 0 ? item.buttonTitle : `剩余${item.discNumber}次`) }}
+ {{ item.buttonUnderContent }}
+
+
+
+
+
+
+
+
-
diff --git a/pages/task/prizeList.vue b/pages/task/prizeList.vue
new file mode 100644
index 0000000..9725da1
--- /dev/null
+++ b/pages/task/prizeList.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/task/receiveMember.vue b/pages/task/receiveMember.vue
new file mode 100644
index 0000000..1ab9fb4
--- /dev/null
+++ b/pages/task/receiveMember.vue
@@ -0,0 +1,193 @@
+
+
+
+
+
+ 每月打卡免费领
+
+
+
+ 打卡奖励
+ 每月免费领
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/video/detail.nvue b/pages/video/detail.nvue
index cdd2158..2b79431 100644
--- a/pages/video/detail.nvue
+++ b/pages/video/detail.nvue
@@ -1,22 +1,56 @@
-
+
diff --git a/uni_modules/almost-lottery/package.json b/uni_modules/almost-lottery/package.json
new file mode 100644
index 0000000..5a58e96
--- /dev/null
+++ b/uni_modules/almost-lottery/package.json
@@ -0,0 +1,85 @@
+{
+ "id": "almost-lottery",
+ "displayName": "Almost-Lottery抽奖转盘",
+ "version": "1.9.7",
+ "description": "【荣获2021插件大赛三等奖】提供奇数、缓存等众多配置项,更有抽奖概率、抽奖次数、付费抽奖等功能内置于示例项目中,完美支持APP、各平台小程序、H5、PC,同时提供 uniCloud 云端版本",
+ "keywords": [
+ "转盘",
+ "抽奖",
+ "转盘抽奖",
+ "大转盘",
+ "大转盘抽奖"
+],
+ "repository": "https://github.com/ialmost/almost-components_uniapp",
+ "engines": {
+ "HBuilderX": "^3.7.11"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "n"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y",
+ "钉钉": "y",
+ "快手": "y",
+ "飞书": "y",
+ "京东": "y"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "n"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/almost-lottery/readme.md b/uni_modules/almost-lottery/readme.md
new file mode 100644
index 0000000..cd74ad3
--- /dev/null
+++ b/uni_modules/almost-lottery/readme.md
@@ -0,0 +1,174 @@
+# almost-lottery
+*使用 Canvas 绘制的抽奖转盘,提供奇数、缓存等众多配置项,更有抽奖概率、抽奖次数、付费抽奖等功能内置于示例项目中*
+
+
+>
+>
+> 如果用着还行,请支持一下
+> - 前往 [GitHub](https://github.com/ialmost/almost-components_uniapp) 给个 Star
+> - 前往 [UniApp](https://ext.dcloud.net.cn/plugin?id=1030) 给个五星
+> - 使用中遇到问题时,可以添加 **QQ群 20441313**
+>
+>
+
+
+## 基于 uniCloud 开发的云端 Almost-Lottery 抽奖转盘,欢迎尝试体验
+- [Almost-Lottery抽奖转盘的云端一体页面](https://ext.dcloud.net.cn/plugin?id=5763)
+- [Almost-Lottery抽奖转盘的配置中心](https://ext.dcloud.net.cn/plugin?id=5762)
+
+
+## 高能预警
+- 本插件仅支持 `uni_modules` 模式,强烈推荐使用该模式,**非 `uni_modules` 模式不再维护**
+- 在使用本插件之前,强烈建议使用 `HBuilderX` 导入示例项目验证可用性并参照修改
+
+## 功能概要
+- [x] 可配置奖品文字 **支持横向/竖向展示**
+- [x] 可配置每个奖品区块的背景颜色
+- [x] 可配置每个奖品区块的奖品文字颜色
+- [x] 可配置奖品区块是否开启描边以及边框的颜色,默认不开启
+- [x] 可配置转盘外环和抽奖按钮图
+- [x] 可配置每个奖品区块的奖品图片,**当图片是网络地址时,小程序端需要配置白名单,H5端需要允许跨域,奖品文字为竖向时不支持展示奖品图片**
+- [x] 奖品列表支持奇数,**奇数时需尽量能被 `360` 除尽**
+- [x] 可配置内圈与外圈的间距
+- [x] 可配置轮盘旋转或指针旋转
+- [x] 可配置画板是否缓存,默认不开启
+- [x] 更多配置请查看API说明
+
+## 示例项目附加功能
+- [x] 中奖概率,**强烈推荐中奖概率应由后端控制**
+- [x] 抽奖次数
+- [x] 付费抽奖
+
+
+## 注意事项
+
+- 编译到小程序端时,请务必勾选ES6转ES5
+
+- `@reset-index="prizeIndex = -1"` 必须默认写入到 `template` 中,不可删除
+
+- 每个奖品区块的奖品图片尺寸不宜过大,图片越大,绘制的过程越慢,尽量将图片尺寸控制在 `100*100` 以内,且图片大小控制在 `40KB` 以内
+
+- 关于中奖概率的配置,请下载示例项目,参照 `pages/index/index.vue` 中的代码进行配置
+
+- 组件本身不涉及任何业务逻辑,与业务相关的代码建议都放在 `pages/index/index.vue` 中
+
+
+## 代码演示
+#### 基础用法
+```
+// template
+// @reset-index="prizeIndex = -1" 必须默认写入到 template 中,不可删除
+
+
+// script
+import AlmostLottery from '@/uni_modules/almost-lottery/components/almost-lottery/almost-lottery.vue'
+export default {
+ components: {
+ AlmostLottery
+ },
+ data () {
+ return {
+ // 以下是奖品配置数据
+ // 奖品数据
+ prizeList: [],
+ // 中奖下标
+ prizeIndex: -1
+ }
+ },
+ methods: {
+ // 本次抽奖开始之前
+ handleDrawStart (callback) {
+ // 这里需要处理你抽奖之前的逻辑
+ // 请查看示例项目中的代码
+ // 必须调用 callback 并传递一个布尔值,布尔值为 true 时,转盘才会开始旋转
+ let flag = true
+
+ callback(flag)
+ },
+ // 本次抽奖开始
+ handleDrawStart () {
+ // 这里需要处理你的抽奖逻辑,并得出中奖物品的 prizeIndex
+ // 请查看示例项目中的代码
+ },
+ // 本次抽奖结束
+ handleDrawEnd () {
+ // 完成抽奖后,这里处理你拿到结果后的逻辑
+ // 请查看示例项目中的代码
+ },
+ // 抽奖转盘绘制完成
+ handleDrawFinish (res) {
+ // 抽奖转盘准备就绪后,这里处理你的逻辑
+ // 请查看示例项目中的代码
+ // console.log('抽奖转盘绘制完成', res)
+ }
+ }
+}
+```
+
+## API
+#### Props
+参数 | 说明 | 类型 | 默认值
+:---|:---|:---|:---
+pixelRatio | 移动端设计稿的像素比基准值,**涉及到 `rpx` 的适配问题** | *`Number`* | `2`
+canvasId | Canvas的标识,**多画板情况下需要配置不同的标识** | *`String`* | `'almostLottery'`
+renderDelay | 转盘的渲染延时,**转盘被包裹在 uni-popup 组件内且开启了动画,请设置成最少 300** | *`Number`* | `0`
+lotterySize | 抽奖转盘的整体尺寸,单位 `rpx` | *`Number`* | `600`
+actionSize | 抽奖按钮的尺寸,单位 `rpx` | *`Number`* | `200`
+canvasMarginOutside | Canvas边缘距离转盘边缘的距离,单位`rpx` | *`Number`* | `90`
+prizeIndex | 获奖奖品在奖品列表中的序号,**每次抽奖结束后会自动重置为 `-1`** | *`Number`* | `-1`
+prizeList | 奖品列表,支持奇数(尽量能被 `360` 除尽),**为奇数时需要重设 `colors` 参数** | *`Array`* | -
+lotteryBg | 转盘外环图片 | `String` | `默认内置的本地图片`
+actionBg | 抽奖按钮图片 | `String` | `默认内置的本地图片`
+colors | 奖品区块对应的背景颜色,默认 2 个颜色相互交替,**也可以对每个区块设置不同颜色** | *`Array`* | `['#FFFFFF', '#FFBF05']`
+prizeNameDrawed | 是否绘制奖品名称 | *`Boolean`* | `true`
+stroked | 是否开启奖品区块描边 | *`Boolean`* | `false`
+strDirection | 奖品名称展示方向,可选值 `'horizontal'` => 横向 `'vertical'` => 竖向 | *`String`* | `'horizontal'`
+strokeColor | 奖品区块边框颜色 | *`String`* | `'#FFBF05'`
+rotateType | 旋转的类型,可选值 `'roulette'` => 轮盘旋转 `'pointer'` => 指针旋转 | *`String`* | `'roulette'`
+selfRotaty | 是否开启自转,开启后`duration`和`ringCount`参数不生效 | *`Boolean`* | `false`
+selfTime | 开启自转时,最少转多少毫秒 | *`Number`* | `1000`
+duration | 转盘旋转的动画时长,单位:秒 | *`Number`* | `8`
+ringCount | 旋转的圈数 | *`Number`* | `8`
+pointerPosition | 点击抽奖按钮指针的位置,可选值 `'edge'` => 指向边界 `'middle'` => 指向中间 | *`String`* | `'edge'`
+strFontColors | 奖品文字颜色,默认 2 个颜色相互交替,**也可以对每个区块的文字设置不同颜色,或仅设置一个颜色** | *`Array`* | `['#FFBF05', '#FFFFFF']`
+strFontSize | 奖品名称的字号,单位 `rpx` | *`Number`* | `24`
+strLineHeight | 奖品名称多行情况下的行高 | *`Number`* | `1.2`
+strMaxLen | 奖品名称长度限制,为`0`时不限制,**文字竖向时不生效** | *`Number`* | `12`
+strLineLen | 奖品名称在多行情况下第一行文字的长度,**文字竖向时不生效** | *`Number`* | `6`
+strMarginOutside | 奖品文字相对轮盘边缘的距离,单位 `rpx` | *`Number`* | `strFontSize 的一半`
+imgMarginStr | 奖品图片相对奖品文字的距离,单位 `rpx` | *`Number`* | `60`
+imgWidth | 奖品图片的宽度,单位 `rpx` | *`Number`* | `50`
+imgHeight | 奖品图片的高度,单位 `rpx` | *`Number`* | `50`
+imgDrawed | 是否绘制奖品图片,默认绘制 | *`Boolean`* | `true`
+imgCircled | 奖品图片是否裁切为圆形,默认不裁切 | *`Boolean`* | `false`
+successMsg | 转盘绘制成功的提示 | *`String`* | `'奖品准备就绪,快来参与抽奖吧'`
+failMsg | 转盘绘制失败的提示 | *`String`* | `'奖品仍在准备中,请稍后再来...'`
+canvasCached | 是否开启缓存,避免在数据不变的情况下重复绘制,建议在生产环境中开启 | *`Boolean`* | `false`
+
+#### Events
+事件名 | 说明 | 回调参数
+:---|:---|:---|:---
+@reset-index | 每次抽奖结束后重置获奖的序号为 `-1`,**该事件必须默认写入到 `template` 中,不可删除** | -
+@draw-before | 转盘旋转之前触发,**该事件必须默认写入到 `template` 中,不可删除** | `callback(Boolean)`
+@draw-start | 转盘旋转开始时触发 | -
+@draw-end | 转盘旋转结束时触发 | -
+@finish | Canvas转盘绘制完成时触发 | `{ ok: 绘制是否成功, data: 转盘的图片, msg: 绘制结果的提示 }`
+
+#### prizeList 数据结构
+*请按如下数据字段对你的奖品列表数据结构进行调整*
+键名 | 说明 | 类型
+:---|:---|:---
+prizeId | 奖品对应 `ID` | *`Number`*
+prizeName | 奖品名称 | *`String`*
+prizeStock | 奖品库存 | *`Number`*
+prizeWeight | 奖品权重 | *`Number`*
+prizeImage | 奖品图片地址,网络图片仅支持`http`和`https`协议 | *`String`*
\ No newline at end of file
diff --git a/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__action.png b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__action.png
new file mode 100644
index 0000000..2e221a4
Binary files /dev/null and b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__action.png differ
diff --git a/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__action2x.png b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__action2x.png
new file mode 100644
index 0000000..10d497f
Binary files /dev/null and b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__action2x.png differ
diff --git a/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__action3x.png b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__action3x.png
new file mode 100644
index 0000000..5e3b8d3
Binary files /dev/null and b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__action3x.png differ
diff --git a/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__bg.png b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__bg.png
new file mode 100644
index 0000000..be39367
Binary files /dev/null and b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__bg.png differ
diff --git a/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__bg2x.png b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__bg2x.png
new file mode 100644
index 0000000..3fe4efd
Binary files /dev/null and b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__bg2x.png differ
diff --git a/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__bg3x.png b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__bg3x.png
new file mode 100644
index 0000000..bcd70e1
Binary files /dev/null and b/uni_modules/almost-lottery/static/almost-lottery/almost-lottery__bg3x.png differ
diff --git a/uni_modules/almost-lottery/utils/almost-utils.js b/uni_modules/almost-lottery/utils/almost-utils.js
new file mode 100644
index 0000000..cd41164
--- /dev/null
+++ b/uni_modules/almost-lottery/utils/almost-utils.js
@@ -0,0 +1,298 @@
+/**
+ * 存储 localStorage 数据
+ * @param {String} name - 缓存数据的标识
+ * @param {any} content - 缓存的数据内容
+ */
+export const setStore = (name, content) => {
+ if (!name) return
+ if (typeof content !== 'string') {
+ content = JSON.stringify(content)
+ }
+ uni.setStorageSync(name, content)
+}
+
+/**
+ * 获取 localStorage 数据
+ * @param {String} name - 缓存数据的标识
+ */
+export const getStore = (name) => {
+ if (!name) return
+ return uni.getStorageSync(name)
+}
+
+/**
+ * 清除 localStorage 数据
+ * @param {String} name - 缓存数据的标识
+ */
+export const clearStore = (name) => {
+ if (name) {
+ uni.removeStorageSync(name)
+ } else {
+ console.log('清理本地全部缓存')
+ uni.clearStorageSync()
+ }
+}
+
+/**
+ * 绘制圆形
+ * @param {String} ctx - 图片网络地址
+ * @param {String} img - 图片地址
+ * @param {String} x - x 轴偏移量
+ * @param {String} y - y 轴偏移量
+ * @param {String} w - 宽
+ * @param {String} h - 高
+*/
+export const circleImg = (ctx, img, x, y, w, h) => {
+ let r = Math.floor(w/2)
+ let cx = x + r
+ let cy = y + r
+
+ ctx.save()
+ ctx.beginPath()
+ ctx.arc(cx, cy, r, 0, Math.PI * 2)
+ ctx.fill()
+ ctx.clip()
+ ctx.drawImage(img, x, y, w, h)
+ ctx.restore()
+}
+
+/**
+ * 计算文本的长度
+ * @param {String} text - 文本内容
+ */
+export const clacTextLen = (text) => {
+ if (!text) return { byteLen: 0, realLen: 0 }
+ text += ''
+ let clacLen = 0
+ for (let i = 0; i < text.length; i++) {
+ if ((text.charCodeAt(i) < 0) || (text.charCodeAt(i) > 255)) {
+ clacLen += 2
+ } else {
+ clacLen += 1
+ }
+ }
+ // console.log(`当前文本 ${text} 的长度为 ${clacLen / 2}`)
+ return {
+ byteLen: clacLen,
+ realLen: clacLen / 2
+ }
+}
+
+/**
+ * 下载文件,并返回临时路径
+ * @return {String} 临时路径
+ * @param {String} fileUrl - 网络地址
+*/
+export const downloadFile = (fileUrl) => {
+ return new Promise((resolve) => {
+ uni.downloadFile({
+ url: fileUrl,
+ success: (res) => {
+ resolve({
+ ok: true,
+ data: res.errMsg,
+ tempFilePath: res.tempFilePath
+ })
+ },
+ fail: (err) => {
+ resolve({
+ ok: false,
+ data: err.errMsg,
+ msg: '图片下载失败'
+ })
+ }
+ })
+ })
+}
+
+/**
+ * 清理应用已缓存的文件
+*/
+export const clearCacheFile = () => {
+ // #ifndef H5
+ uni.getSavedFileList({
+ success: (res) => {
+ let fileList = res.fileList
+ if (fileList.length) {
+ for (let i = 0; i < fileList.length; i++) {
+ uni.removeSavedFile({
+ filePath: fileList[i].filePath,
+ complete: () => {
+ console.log('清除缓存已完成')
+ }
+ })
+ }
+ }
+ },
+ fail: (err) => {
+ console.log('getSavedFileList Fail')
+ }
+ })
+ // #endif
+}
+
+
+
+// 图像转换工具,可用于图像和base64的转换
+// https://ext.dcloud.net.cn/plugin?id=123
+const getLocalFilePath = (path) => {
+ if (
+ path.indexOf('_www') === 0 ||
+ path.indexOf('_doc') === 0 ||
+ path.indexOf('_documents') === 0 ||
+ path.indexOf('_downloads') === 0
+ ) return path
+
+ if (path.indexOf('/storage/emulated/0/') === 0) return path
+
+ if (path.indexOf('/storage/sdcard0/') === 0) return path
+
+ if (path.indexOf('/var/mobile/') === 0) return path
+
+ if (path.indexOf('file://') === 0) return path
+
+ if (path.indexOf('/') === 0) {
+ // ios 无法获取本地路径
+ let localFilePath = plus.os.name === 'iOS' ? path : plus.io.convertLocalFileSystemURL(path)
+ if (localFilePath !== path) {
+ return localFilePath
+ } else {
+ path = path.substring(1)
+ }
+ }
+
+ return '_www/' + path
+}
+
+export const pathToBase64 = (path) => {
+ return new Promise((resolve, reject) => {
+ if (typeof window === 'object' && 'document' in window) {
+ if (typeof FileReader === 'function') {
+ let xhr = new XMLHttpRequest()
+ xhr.open('GET', path, true)
+ xhr.responseType = 'blob'
+ xhr.onload = function() {
+ if (this.status === 200) {
+ let fileReader = new FileReader()
+ fileReader.onload = function(e) {
+ resolve(e.target.result)
+ }
+ fileReader.onerror = reject
+ fileReader.readAsDataURL(this.response)
+ }
+ }
+ xhr.onerror = reject
+ xhr.send()
+ return
+ }
+ let canvas = document.createElement('canvas')
+ let c2x = canvas.getContext('2d')
+ let img = new Image
+ img.onload = function() {
+ canvas.width = img.width
+ canvas.height = img.height
+ c2x.drawImage(img, 0, 0)
+ resolve(canvas.toDataURL())
+ canvas.height = canvas.width = 0
+ }
+ img.onerror = reject
+ img.src = path
+ return
+ }
+
+ if (typeof plus === 'object') {
+ let tempPath = getLocalFilePath(path)
+ plus.io.resolveLocalFileSystemURL(tempPath, (entry) => {
+ entry.file((file) => {
+ let fileReader = new plus.io.FileReader()
+ fileReader.onload = function(data) {
+ resolve(data.target.result)
+ }
+ fileReader.onerror = function(error) {
+ console.log(error)
+ reject(error)
+ }
+ fileReader.readAsDataURL(file)
+ }, (error) => {
+ reject(error)
+ })
+ }, (error) => {
+ reject(error)
+ })
+ return
+ }
+
+ if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
+ wx.getFileSystemManager().readFile({
+ filePath: path,
+ encoding: 'base64',
+ success: (res) => {
+ resolve('data:image/png;base64,' + res.data)
+ },
+ fail: (error) => {
+ reject(error)
+ }
+ })
+ return
+ }
+ reject(new Error('not support'))
+ })
+}
+
+export const base64ToPath = (base64) => {
+ return new Promise((resolve, reject) => {
+ if (typeof window === 'object' && 'document' in window) {
+ base64 = base64.split(',')
+ let type = base64[0].match(/:(.*?);/)[1]
+ let str = atob(base64[1])
+ let n = str.length
+ let array = new Uint8Array(n)
+ while (n--) {
+ array[n] = str.charCodeAt(n)
+ }
+ return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], {
+ type: type
+ })))
+ }
+ let extName = base64.match(/data\:\S+\/(\S+);/)
+ if (extName) {
+ extName = extName[1]
+ } else {
+ reject(new Error('base64 error'))
+ }
+ let fileName = Date.now() + '.' + extName
+ if (typeof plus === 'object') {
+ let bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+ bitmap.loadBase64Data(base64, () => {
+ let filePath = '_doc/uniapp_temp/' + fileName
+ bitmap.save(filePath, {}, () => {
+ bitmap.clear()
+ resolve(filePath)
+ }, (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ }, (error) => {
+ bitmap.clear()
+ reject(error)
+ })
+ return
+ }
+ if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
+ let filePath = wx.env.USER_DATA_PATH + '/' + fileName
+ wx.getFileSystemManager().writeFile({
+ filePath: filePath,
+ data: base64.replace(/^data:\S+\/\S+;base64,/, ''),
+ encoding: 'base64',
+ success: () => {
+ resolve(filePath)
+ },
+ fail: (error) => {
+ reject(error)
+ }
+ })
+ return
+ }
+ reject(new Error('not support'))
+ })
+}