第一次提交

main
D 3 years ago
commit e1f6e93503

4
.gitignore vendored

@ -0,0 +1,4 @@
.hbuilderx
unpackage
dist
node_modules

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 哦NO
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

@ -0,0 +1,78 @@
{
"name": "uni-preset-vue",
"version": "0.0.0",
"scripts": {
"dev:app": "uni -p app",
"dev:app-android": "uni -p app-android",
"dev:app-ios": "uni -p app-ios",
"dev:custom": "uni -p",
"dev:h5": "uni",
"dev:h5:ssr": "uni --ssr",
"dev:mp-alipay": "uni -p mp-alipay",
"dev:mp-baidu": "uni -p mp-baidu",
"dev:mp-jd": "uni -p mp-jd",
"dev:mp-kuaishou": "uni -p mp-kuaishou",
"dev:mp-lark": "uni -p mp-lark",
"dev:mp-qq": "uni -p mp-qq",
"dev:mp-toutiao": "uni -p mp-toutiao",
"dev:mp-weixin": "uni -p mp-weixin",
"dev:quickapp-webview": "uni -p quickapp-webview",
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
"build:app": "uni build -p app",
"build:app-android": "uni build -p app-android",
"build:app-ios": "uni build -p app-ios",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "uni build -p mp-alipay",
"build:mp-baidu": "uni build -p mp-baidu",
"build:mp-jd": "uni build -p mp-jd",
"build:mp-kuaishou": "uni build -p mp-kuaishou",
"build:mp-lark": "uni build -p mp-lark",
"build:mp-qq": "uni build -p mp-qq",
"build:mp-toutiao": "uni build -p mp-toutiao",
"build:mp-weixin": "uni build -p mp-weixin",
"build:quickapp-webview": "uni build -p quickapp-webview",
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
"type-check": "vue-tsc --noEmit"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-3080720230703001",
"@dcloudio/uni-app-plus": "3.0.0-3080720230703001",
"@dcloudio/uni-components": "3.0.0-3080720230703001",
"@dcloudio/uni-h5": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-alipay": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-baidu": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-jd": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-lark": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-qq": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-toutiao": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-weixin": "3.0.0-3080720230703001",
"@dcloudio/uni-quickapp-webview": "3.0.0-3080720230703001",
"@qiun/wx-ucharts": "2.5.0-20230101",
"@ttou/uview-typings": "^2.0.5",
"clipboard": "^2.0.11",
"dayjs": "^1.11.9",
"uview-plus": "^3.1.36",
"vue": "^3.2.45",
"vue-i18n": "^9.1.9",
"vuex": "^4.1.0"
},
"devDependencies": {
"@dcloudio/types": "^3.3.2",
"@dcloudio/uni-automator": "3.0.0-3080720230703001",
"@dcloudio/uni-cli-shared": "3.0.0-3080720230703001",
"@dcloudio/uni-stacktracey": "3.0.0-3080720230703001",
"@dcloudio/vite-plugin-uni": "3.0.0-3080720230703001",
"@vue/tsconfig": "^0.1.3",
"less": "^4.2.0",
"sass": "^1.64.2",
"sass-loader": "10",
"typescript": "^4.9.4",
"vite": "4.0.4",
"vue-tsc": "^1.0.24"
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,18 @@
<script>
export default {
onLaunch: function () {
console.log('App Launch')
},
onShow: function () {
console.log('App Show')
},
onHide: function () {
console.log('App Hide')
}
}
</script>
<style lang="scss">
@import "uview-plus/index.scss";
@import '@/static/scss/index.scss';
</style>

@ -0,0 +1,59 @@
import request from '@/utils/request'
// 登录方法
export function login(username, password, code, uuid) {
const data = {
username,
password,
code,
uuid
}
return request({
url: '/login',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
// 注册方法
export function register(data) {
return request({
url: '/register',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
// 获取用户详细信息
export function getInfo() {
return request({
url: '/getInfo',
method: 'get'
})
}
// 退出方法
export function logout() {
return request({
url: '/logout',
method: 'post'
})
}
// 获取验证码
export function getCodeImg() {
return request({
url: '/captchaImage',
headers: {
isToken: false
},
method: 'get',
timeout: 20000
})
}

@ -0,0 +1,41 @@
import upload from '@/utils/upload'
import request from '@/utils/request'
// 用户密码重置
export function updateUserPwd(oldPassword, newPassword) {
const data = {
oldPassword,
newPassword
}
return request({
url: '/system/user/profile/updatePwd',
method: 'put',
params: data
})
}
// 查询用户个人信息
export function getUserProfile() {
return request({
url: '/system/user/profile',
method: 'get'
})
}
// 修改用户个人信息
export function updateUserProfile(data) {
return request({
url: '/system/user/profile',
method: 'put',
data: data
})
}
// 用户头像上传
export function uploadAvatar(data) {
return upload({
url: '/system/user/profile/avatar',
name: data.name,
filePath: data.filePath
})
}

@ -0,0 +1,320 @@
## 2.5.0-202301012023-01-01
- 秋云图表组件 修改条件编译顺序确保uniapp的cli方式的项目依赖不完整时可以正常显示
- 秋云图表组件 恢复props属性directory的使用以修复vue3项目中开启echarts后echarts目录识别错误的bug
- uCharts.js 修复区域图、混合图只有一个数据时图表显示不正确的bug
- uCharts.js 修复折线图、区域图中时间轴类别图表tooltip指示点显示不正确的bug
- uCharts.js 修复x轴使用labelCount时并且boundaryGap = 'justify' 并且关闭Y轴显示的时候最后一个坐标值不显示的bug
- uCharts.js 修复折线图只有一组数据时 ios16 渲染颜色不正确的bug
- uCharts.js 修复玫瑰图半径显示不正确的bug
- uCharts.js 柱状图、山峰图增加正负图功能y轴网格如果需要显示0轴则由 min max 及 splitNumber 确定后续版本优化自动显示0轴
- uCharts.js 柱状图column增加 opts.extra.column.labelPosition数据标签位置有效值为 outside外部, insideTop内顶部, center内中间, bottom内底部
- uCharts.js 雷达图radar增加 opts.extra.radar.labelShow否显示各项标识文案是默认true
- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.boxPadding提示窗边框填充距离默认3px
- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.fontSize提示窗字体大小配置默认13px
- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.lineHeight提示窗文字行高默认20px
- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.legendShow是否显示左侧图例默认true
- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.legendShape图例形状图例标识样式有效值为 auto自动跟随图例, diamond◆, circle●, triangle▲, square■, rect▬, line-
- uCharts.js 标记线markLine增加 opts.extra.markLine.labelFontSize字体大小配置默认13px
- uCharts.js 标记线markLine增加 opts.extra.markLine.labelPadding标签边框内填充距离默认6px
- uCharts.js 折线图line增加 opts.extra.line.linearType渐变色类型可选值 none关闭渐变色custom 自定义渐变色。使用自定义渐变色时请赋值serie.linearColor作为颜色值
- uCharts.js 折线图line增加 serie.linearColor渐变色数组格式为2维数组[起始位置,颜色值],例如[[0,'#0EE2F8'],[0.3,'#2BDCA8'],[0.6,'#1890FF'],[1,'#9A60B4']]
- uCharts.js 折线图line增加 opts.extra.line.onShadow是否开启折线阴影开启后请赋值serie.setShadow阴影设置
- uCharts.js 折线图line增加 serie.setShadow阴影配置格式为4位数组[offsetX,offsetY,blur,color]
- uCharts.js 折线图line增加 opts.extra.line.animation动画效果方向可选值为vertical 垂直动画效果horizontal 水平动画效果
- uCharts.js X轴xAxis增加 opts.xAxis.lineHeightX轴字体行高默认20px
- uCharts.js X轴xAxis增加 opts.xAxis.marginTopX轴文字距离轴线的距离默认0px
- uCharts.js X轴xAxis增加 opts.xAxis.title当前X轴标题
- uCharts.js X轴xAxis增加 opts.xAxis.titleFontSize标题字体大小默认13px
- uCharts.js X轴xAxis增加 opts.xAxis.titleOffsetY标题纵向偏移距离负数为向上偏移正数向下偏移
- uCharts.js X轴xAxis增加 opts.xAxis.titleOffsetX标题横向偏移距离负数为向左偏移正数向右偏移
- uCharts.js X轴xAxis增加 opts.xAxis.titleFontColor标题字体颜色默认#666666
## 报错TypeError: Cannot read properties of undefined (reading 'length')
- 如果是uni-modules版本组件请先登录HBuilderX账号
- 在HBuilderX中的manifest.json点击重新获取uniapp的appid或者删除appid重新粘贴重新运行
- 如果是cli项目请使用码云上的非uniCloud版本组件
- 或者添加uniCloud的依赖
- 或者使用原生uCharts
## 2.4.5-202211302022-11-30
- uCharts.js 优化tooltip当文字很多变为左侧显示时如果画布仍显显示不下提示框错位置变为以左侧0位置起画
- uCharts.js 折线图修复特殊情况下只有单点数据并改变线宽后点变为圆形的bug
- uCharts.js 修复Y轴disabled启用后无效并报错的bug
- uCharts.js 修复仪表盘起始结束角度特殊情况下显示不正确的bug
- uCharts.js 雷达图新增参数 opts.extra.radar.radius , 自定义雷达图半径
- uCharts.js 折线图、区域图增加tooltip指示点opts.extra.line.activeType/opts.extra.area.activeType可选值"none"不启用激活指示点,"hollow"空心点模式,"solid"实心点模式
## 2.4.4-202211022022-11-02
- 秋云图表组件 修复使用echarts时reload、reshow无法调用重新渲染的bug[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/40)
- 秋云图表组件 修复使用echarts时初始化时宽高不正确的bug[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/42)
- 秋云图表组件 修复uniapp的h5使用history模式时无法加载echarts的bug
- 秋云图表组件 小程序端@complete、@scrollLeft、@scrollRight、@getTouchStart、@getTouchMove、@getTouchEnd事件增加opts参数传出方便一些特殊需求的交互获取数据。
- uCharts.js 修复calTooltipYAxisData方法内formatter格式化方法未与y轴方法同步的问题[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/43)
- uCharts.js 地图新增参数opts.series[i].fillOpacity以透明度方式来设置颜色过度效果[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/38)
- uCharts.js 地图新增参数opts.extra.map.active是否启用点击激活变色
- uCharts.js 地图新增参数opts.extra.map.activeTextColor是否启用点击激活变色
- uCharts.js 地图新增渲染完成事件renderComplete
- uCharts.js 漏斗图修复当部分数据相同时tooltip提示窗点击错误的bug
- uCharts.js 漏斗图新增参数series.data[i].centerText 居中标签文案
- uCharts.js 漏斗图新增参数series.data[i].centerTextSize 居中标签文案字体大小默认opts.fontSize
- uCharts.js 漏斗图新增参数series.data[i].centerTextColor 居中标签文案字体颜色,默认#FFFFFF
- uCharts.js 漏斗图新增参数opts.extra.funnel.minSize 最小值的最小宽度默认0
- uCharts.js 进度条新增参数opts.extra.arcbar.direction动画方向可选值为cw顺时针、ccw逆时针
- uCharts.js 混合图新增参数opts.extra.mix.line.width折线的宽度默认2
- uCharts.js 修复tooltip开启horizentalLine水平横线标注时图表显示错位的bug
- uCharts.js 优化tooltip当文字很多变为左侧显示时如果画布仍显显示不下提示框错位置变为以左侧0位置起画
- uCharts.js 修复开启滚动条后X轴文字超出绘图区域后的隐藏逻辑
- uCharts.js 柱状图、条状图修复堆叠模式不能通过{value,color}赋值单个柱子颜色的问题
- uCharts.js 气泡图修复不识别series.textSize和series.textColor的bug
## 报错TypeError: Cannot read properties of undefined (reading 'length')
1. 如果是uni-modules版本组件请先登录HBuilderX账号
2. 在HBuilderX中的manifest.json点击重新获取uniapp的appid或者删除appid重新粘贴重新运行
3. 如果是cli项目请使用码云上的非uniCloud版本组件
4. 或者添加uniCloud的依赖
5. 或者使用原生uCharts
## 2.4.3-202205052022-05-05
- 秋云图表组件 修复开启canvas2d后将series赋值为空数组显示加载图标时再次赋值后画布闪动的bug
- 秋云图表组件 修复升级hbx最新版后ECharts的highlight方法报错的bug
- uCharts.js 雷达图新增参数opts.extra.radar.gridEval数据点位网格抽希默认1
- uCharts.js 雷达图新增参数opts.extra.radar.axisLabel 是否显示刻度点值默认false
- uCharts.js 雷达图新增参数opts.extra.radar.axisLabelTofix刻度点值小数位数默认0
- uCharts.js 雷达图新增参数opts.extra.radar.labelPointShow是否显示末端刻度圆点默认false
- uCharts.js 雷达图新增参数opts.extra.radar.labelPointRadius刻度圆点的半径默认3
- uCharts.js 雷达图新增参数opts.extra.radar.labelPointColor刻度圆点的颜色默认#cccccc
- uCharts.js 雷达图新增参数opts.extra.radar.linearType渐变色类型可选值"none"关闭渐变,"custom"开启渐变
- uCharts.js 雷达图新增参数opts.extra.radar.customColor自定义渐变颜色数组类型对应series的数组长度以匹配不同series颜色的不同配色方案例如["#FA7D8D", "#EB88E2"]
- uCharts.js 雷达图优化支持series.textColor、series.textSize属性
- uCharts.js 柱状图中温度计式图标优化支持全圆角类型修复边框有缝隙的bug详见官网【演示】中的温度计图表
- uCharts.js 柱状图新增参数opts.extra.column.activeWidth当前点击柱状图的背景宽度默认一个单元格单位
- uCharts.js 混合图增加opts.extra.mix.area.gradient 区域图是否开启渐变色
- uCharts.js 混合图增加opts.extra.mix.area.opacity 区域图透明度默认0.2
- uCharts.js 饼图、圆环图、玫瑰图、漏斗图增加opts.series[0].data[i].labelText自定义标签文字避免formatter格式化的繁琐详见官网【演示】中的饼图
- uCharts.js 饼图、圆环图、玫瑰图、漏斗图增加opts.series[0].data[i].labelShow自定义是否显示某一个指示标签避免因饼图类别太多导致标签重复或者居多导致图形变形的问题详见官网【演示】中的饼图
- uCharts.js 增加opts.series[i].legendText/opts.series[0].data[i].legendText与series.name同级自定义图例显示文字的方法
- uCharts.js 优化X轴、Y轴formatter格式化方法增加形参统一为fromatter:function(value,index,opts){}
- uCharts.js 修复横屏模式下无法使用双指缩放方法的bug
- uCharts.js 修复当只有一条数据或者多条数据值相等的时候Y轴自动计算的最大值错误的bug
- 【官网模板】增加外部自定义图例与图表交互的例子,[点击跳转](https://www.ucharts.cn/v2/#/layout/info?id=2)
## 注意非unimodules 版本如因更新 hbx 至 3.4.7 导致报错如下,请到码云更新非 unimodules 版本组件,[点击跳转](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6)
> Error in callback for immediate watcher "uchartsOpts": "SyntaxError: Unexpected token u in JSON at position 0"
## 2.4.2-202204212022-04-21
- 秋云图表组件 修复HBX升级3.4.6.20220420版本后echarts报错的问题
## 2.4.2-202204202022-04-20
## 重要此版本uCharts新增了很多功能修复了诸多已知问题
- 秋云图表组件 新增onzoom开启双指缩放功能仅uCharts前提需要直角坐标系类图表类型并且ontouch为true、opts.enableScroll为true详见实例项目K线图
- 秋云图表组件 新增optsWatch是否监听opts变化关闭optsWatch后动态修改opts不会触发图表重绘
- 秋云图表组件 修复开启canvas2d功能后动态更新数据后画布闪动的bug
- 秋云图表组件 去除directory属性改为自动获取echarts.min.js路径升级不受影响
- 秋云图表组件 增加getImage()方法及@getImage事件通过ref调用getImage()方法获,触发@getImage事件获取当前画布的base64图片文件流。
- 秋云图表组件 支付宝、字节跳动、飞书、快手小程序支持开启canvas2d同层渲染设置。
- 秋云图表组件 新增加【非uniCloud】版本组件避免有些不需要uniCloud的使用组件发布至小程序需要提交隐私声明问题请到码云[【非uniCloud版本】](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6)或npm[【非uniCloud版本】](https://www.npmjs.com/package/@qiun/uni-ucharts)下载使用。
- uCharts.js 新增dobuleZoom双指缩放功能
- uCharts.js 新增山峰图type="mount"数据格式为饼图类格式不需要传入categories具体详见新版官网在线演示
- uCharts.js 修复折线图当数据中存在null时tooltip报错的bug
- uCharts.js 修复饼图类当画布比较小时自动计算的半径是负数报错的bug
- uCharts.js 统一各图表类型的series.formatter格式化方法的形参为(val, index, series, opts),方便格式化时有更多参数可用
- uCharts.js 标记线功能增加labelText自定义显示文字增加labelAlign标签显示位置左侧或右侧增加标签显示位置微调labelOffsetX、labelOffsetY
- uCharts.js 修复条状图当数值很小时开启圆角后样式错误的bug
- uCharts.js 修复X轴开启disabled后X轴仍占用空间的bug
- uCharts.js 修复X轴开启滚动条并且开启rotateLabel后X轴文字与滚动条重叠的bug
- uCharts.js 增加X轴rotateAngle文字旋转自定义角度取值范围(-90至90)
- uCharts.js 修复地图文字标签层级显示不正确的bug
- uCharts.js 修复饼图、圆环图、玫瑰图当数据全部为0的时候不显示数据标签的bug
- uCharts.js 修复当opts.padding上边距为0时Y轴顶部刻度标签位置不正确的bug
## 另外我们还开发了各大原生小程序组件已发布至码云和npm
[https://gitee.com/uCharts/uCharts](https://gitee.com/uCharts/uCharts)
[https://www.npmjs.com/~qiun](https://www.npmjs.com/~qiun)
## 对于原生uCharts文档我们已上线新版官方网站详情点击下面链接进入官网
[https://www.uCharts.cn/v2/](https://www.ucharts.cn/v2/)
## 2.3.7-202201222022-01-22
## 重要使用vue3编译请使用cli模式并升级至最新依赖HbuilderX编译需要使用3.3.8以上版本
- uCharts.js 修复uni-app平台组件模式使用vue3编译到小程序报错的bug。
## 2.3.7-202201182022-01-18
## 注意使用vue3的前提是需要3.3.8.20220114-alpha版本的HBuilder
## 2.3.67-202201182022-01-18
- 秋云图表组件 组件初步支持vue3全端编译会有些问题具体详见下面修改
1. 小程序端运行时在uni_modules文件夹的qiun-data-charts.js中搜索 new uni_modules_qiunDataCharts_js_sdk_uCharts_uCharts.uCharts将.uCharts去掉。
2. 小程序端发行时在uni_modules文件夹的qiun-data-charts.js中搜索 new e.uCharts将.uCharts去掉变为 new e。
3. 如果觉得上述步骤比较麻烦如果您的项目只编译到小程序端可以修改u-charts.js最后一行导出方式将 export default uCharts;变更为 export default { uCharts: uCharts }; 这样变更后H5和App端的renderjs会有问题请开发者自行选择。此问题非组件问题请等待DC官方修复Vue3的小程序端
## 2.3.6-202201112022-01-11
- 秋云图表组件 修改组件 props 属性中的 background 默认值为 rgba(0,0,0,0)
## 2.3.6-202112012021-12-01
- uCharts.js 修复bar条状图开启圆角模式时值很小时圆角渲染错误的bug
## 2.3.5-202110142021-10-15
- uCharts.js 增加vue3的编译支持仅原生uChartsqiun-data-charts组件后续会支持请关注更新
## 2.3.4-202110122021-10-12
- 秋云图表组件 修复 mac os x 系统 mouseover 事件丢失的 bug
## 2.3.3-202107062021-07-06
- uCharts.js 增加雷达图开启数据点值opts.dataLabel的显示
## 2.3.2-202106272021-06-27
- 秋云图表组件 修复tooltipCustom个别情况下传值不正确报错TypeError: Cannot read property 'name' of undefined的bug
## 2.3.1-202106162021-06-16
- uCharts.js 修复圆角柱状图使用4角圆角时当数值过大时不正确的bug
## 2.3.0-202106122021-06-12
- uCharts.js 【重要】uCharts增加nvue兼容可在nvue项目中使用gcanvas组件渲染uCharts[详见码云uCharts-demo-nvue](https://gitee.com/uCharts/uCharts)
- 秋云图表组件 增加tapLegend属性是否开启图例点击交互事件
- 秋云图表组件 getIndex事件中增加返回uCharts实例中的opts参数以便在页面中调用参数
- 示例项目 pages/other/other.vue增加app端自定义tooltip的方法详见showOptsTooltip方法
## 2.2.1-202106032021-06-03
- uCharts.js 修复饼图、圆环图、玫瑰图当起始角度不为0时tooltip位置不准确的bug
- uCharts.js 增加温度计式柱状图开启顶部半圆形的配置
## 2.2.0-202105292021-05-29
- uCharts.js 增加条状图type="bar"
- 示例项目 pages/ucharts/ucharts.vue增加条状图的demo
## 2.1.7-202105242021-05-24
- uCharts.js 修复大数据量模式下曲线图不平滑的bug
## 2.1.6-202105232021-05-23
- 秋云图表组件 修复小程序端开启滚动条更新数据后滚动条位置不符合预期的bug
## 2.1.5-20210517022021-05-17
- uCharts.js 修复自定义Y轴min和max值为0时不能正确显示的bug
## 2.1.5-202105172021-05-17
- uCharts.js 修复Y轴自定义min和max时未按指定的最大值最小值显示坐标轴刻度的bug
## 2.1.4-202105162021-05-16
- 秋云图表组件 优化onWindowResize防抖方法
- 秋云图表组件 修复APP端uCharts更新数据时清空series显示loading图标后再显示图表图表抖动的bug
- uCharts.js 修复开启canvas2d后x轴、y轴、series自定义字体大小未按比例缩放的bug
- 示例项目 修复format-e.vue拼写错误导致app端使用uCharts渲染图表
## 2.1.3-202105132021-05-13
- 秋云图表组件 修改uCharts变更chartData数据为updateData方法支持带滚动条的数据动态打点
- 秋云图表组件 增加onWindowResize防抖方法 fix by ど誓言,如尘般染指流年づ
- 秋云图表组件 H5或者APP变更chartData数据显示loading图表时原数据闪现的bug
- 秋云图表组件 props增加errorReload禁用错误点击重新加载的方法
- uCharts.js 增加tooltip显示categoryx轴对应点位标题的功能opts.extra.tooltip.showCategory默认为false
- uCharts.js 修复mix混合图只有柱状图时tooltip的分割线显示位置不正确的bug
- uCharts.js 修复开启滚动条图表在拖动中动态打点滚动条位置不正确的bug
- uCharts.js 修复饼图类数据格式为echarts数据格式series为空数组报错的bug
- 示例项目 修改uCharts.js更新到v2.1.2版本后,@getIndex方法获取索引值变更为e.currentIndex.index
- 示例项目 pages/updata/updata.vue增加滚动条拖动更新数据动态打点的demo
- 示例项目 pages/other/other.vue增加errorReload禁用错误点击重新加载的demo
## 2.1.2-202105092021-05-09
秋云图表组件 修复APP端初始化时就传入chartData或lacaldata不显示图表的bug
## 2.1.1-202105092021-05-09
- 秋云图表组件 变更ECharts的eopts配置在renderjs内执行支持在config-echarts.js配置文件内写function配置。
- 秋云图表组件 修复APP端报错Prop being mutated: "onmouse"错误的bug。
- 秋云图表组件 修复APP端报错Error: Not FoundPage[6][-1,27] at view.umd.min.js:1的bug。
## 2.1.0-202105072021-05-07
- 秋云图表组件 修复初始化时就有数据或者数据更新的时候loading加载动画闪动的bug
- uCharts.js 修复x轴format方法categories为字符串类型时返回NaN的bug
- uCharts.js 修复series.textColor、legend.fontColor未执行全局默认颜色的bug
## 2.1.0-202105062021-05-06
- 秋云图表组件 修复极个别情况下报错item.properties undefined的bug
- 秋云图表组件 修复极个别情况下关闭加载动画reshow不起作用无法显示图表的bug
- 示例项目 pages/ucharts/ucharts.vue 增加时间轴折线图type="tline"、时间轴区域图type="tarea"、散点图type="scatter"、气泡图demotype="bubble"、倒三角形漏斗图opts.extra.funnel.type="triangle"、金字塔形漏斗图opts.extra.funnel.type="pyramid"
- 示例项目 pages/format-u/format-u.vue 增加X轴format格式化示例
- uCharts.js 升级至v2.1.0版本
- uCharts.js 修复 玫瑰图面积模式点击tooltip位置不正确的bug
- uCharts.js 修复 玫瑰图点击图例只剩一个类别显示空白的bug
- uCharts.js 修复 饼图类图点击图例其他图表tooltip位置某些情况下不准的bug
- uCharts.js 修复 x轴为矢量轴时间轴情况下点击tooltip位置不正确的bug
- uCharts.js 修复 词云图获取点击索引偶尔不准的bug
- uCharts.js 增加 直角坐标系图表X轴format格式化方法原生uCharts.js用法请使用formatter
- uCharts.js 增加 漏斗图扩展配置倒三角形opts.extra.funnel.type="triangle"金字塔形opts.extra.funnel.type="pyramid"
- uCharts.js 增加 散点图opts.type="scatter"、气泡图opts.type="bubble"
- 后期计划 完善散点图、气泡图增加markPoints标记点增加横向条状图。
## 2.0.0-202105022021-05-02
- uCharts.js 修复词云图获取点击索引不正确的bug
## 2.0.0-202105012021-05-01
- 秋云图表组件 修复QQ小程序、百度小程序在关闭动画效果情况下v-for循环使用图表显示不正确的bug
## 2.0.0-202104262021-04-26
- 秋云图表组件 修复QQ小程序不支持canvas2d的bug
- 秋云图表组件 修复钉钉小程序某些情况点击坐标计算错误的bug
- uCharts.js 增加 extra.column.categoryGap 参数柱状图类每个category点位X轴点柱子组之间的间距
- uCharts.js 增加 yAxis.data[i].titleOffsetY 参数,标题纵向偏移距离,负数为向上偏移,正数向下偏移
- uCharts.js 增加 yAxis.data[i].titleOffsetX 参数,标题横向偏移距离,负数为向左偏移,正数向右偏移
- uCharts.js 增加 extra.gauge.labelOffset 参数仪表盘标签文字径向便宜距离默认13px
## 2.0.0-20210422-22021-04-22
秋云图表组件 修复 formatterAssign 未判断 args[key] == null 的情况导致栈溢出的 bug
## 2.0.0-202104222021-04-22
- 秋云图表组件 修复H5、APP、支付宝小程序、微信小程序canvas2d模式下横屏模式的bug
## 2.0.0-202104212021-04-21
- uCharts.js 修复多行图例的情况下图例在上方或者下方时图例float为左侧或者右侧时第二行及以后的图例对齐方式不正确的bug
## 2.0.0-202104202021-04-20
- 秋云图表组件 修复微信小程序开启canvas2d模式后windows版微信小程序不支持canvas2d模式的bug
- 秋云图表组件 修改非uni_modules版本为v2.0版本qiun-data-charts组件
## 2.0.0-202104192021-04-19
## v1.0版本已停更建议转uni_modules版本组件方式调用点击右侧绿色【使用HBuilderX导入插件】即可使用示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件请重启HBuilderX如仍不好用请重启电脑
## 如果是cli项目请尝试清理node_modules重新install还不行就删除项目再重新install。
## 此问题已于DCloud官方确认HBuilderX下个版本会修复。
## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
## <font color=#FF0000> 新手请先完整阅读帮助文档及常见问题3遍右侧蓝色按钮示例项目请看2遍 </font>
## [DEMO演示及在线生成工具v2.0文档https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- uCharts.js 修复混合图中柱状图单独设置颜色不生效的bug
- uCharts.js 修复多Y轴单独设置fontSize时开启canvas2d后未对应放大字体的bug
## 2.0.0-202104182021-04-18
- 秋云图表组件 增加directory配置修复H5端history模式下如果发布到二级目录无法正确加载echarts.min.js的bug
## 2.0.0-202104162021-04-16
## v1.0版本已停更建议转uni_modules版本组件方式调用点击右侧绿色【使用HBuilderX导入插件】即可使用示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件请重启HBuilderX如仍不好用请重启电脑
## 如果是cli项目请尝试清理node_modules重新install还不行就删除项目再重新install。
## 此问题已于DCloud官方确认HBuilderX下个版本会修复。
## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
## <font color=#FF0000> 新手请先完整阅读帮助文档及常见问题3遍右侧蓝色按钮示例项目请看2遍 </font>
## [DEMO演示及在线生成工具v2.0文档https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- 秋云图表组件 修复APP端某些情况下报错`Not Found Page`的bugfix by 高级bug开发技术员
- 示例项目 修复APP端v-for循环某些情况下报错`Not Found Page`的bugfix by 高级bug开发技术员
- uCharts.js 修复非直角坐标系tooltip提示窗右侧超出未变换方向显示的bug
## 2.0.0-202104152021-04-15
- 秋云图表组件 修复H5端发布到二级目录下echarts无法加载的bug
- 秋云图表组件 修复某些情况下echarts.off('finished')移除监听事件报错的bug
## 2.0.0-202104142021-04-14
## v1.0版本已停更建议转uni_modules版本组件方式调用点击右侧绿色【使用HBuilderX导入插件】即可使用示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件请重启HBuilderX如仍不好用请重启电脑
## 如果是cli项目请尝试清理node_modules重新install还不行就删除项目再重新install。
## 此问题已于DCloud官方确认HBuilderX下个版本会修复。
## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
## <font color=#FF0000> 新手请先完整阅读帮助文档及常见问题3遍右侧蓝色按钮示例项目请看2遍 </font>
## [DEMO演示及在线生成工具v2.0文档https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- 秋云图表组件 修复H5端在cli项目下ECharts引用地址错误的bug
- 示例项目 增加ECharts的formatter用法的示例(详见示例项目format-e.vue)
- uCharts.js 增加圆环图中心背景色的配置extra.ring.centerColor
- uCharts.js 修复微信小程序安卓端柱状图开启透明色后显示不正确的bug
## 2.0.0-202104132021-04-13
- 秋云图表组件 修复百度小程序多个图表真机未能正确获取根元素dom尺寸的bug
- 秋云图表组件 修复百度小程序横屏模式方向不正确的bug
- 秋云图表组件 修改ontouch时@getTouchStart@getTouchMove@getTouchEnd的触发条件
- uCharts.js 修复饼图类数据格式series属性不生效的bug
- uCharts.js 增加时序区域图 详见示例项目中ucharts.vue
## 2.0.0-20210412-22021-04-12
## v1.0版本已停更建议转uni_modules版本组件方式调用点击右侧绿色【使用HBuilderX导入插件】即可使用示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件请重启HBuilderX。如仍不好用请重启电脑此问题已于DCloud官方确认HBuilderX下个版本会修复。
## [DEMO演示及在线生成工具v2.0文档https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- 秋云图表组件 修复uCharts在APP端横屏模式下不能正确渲染的bug
- 示例项目 增加ECharts柱状图渐变色、圆角柱状图、横向柱状图条状图的示例
## 2.0.0-202104122021-04-12
- 秋云图表组件 修复created中判断echarts导致APP端无法识别改回mounted中判断echarts初始化
- uCharts.js 修复2d模式下series.textOffset未乘像素比的bug
## 2.0.0-202104112021-04-11
## v1.0版本已停更建议转uni_modules版本组件方式调用点击右侧绿色【使用HBuilderX导入插件】即可使用示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
## 初次使用如果提示未注册<qiun-data-charts>组件请重启HBuilderX并清空小程序开发者工具缓存。
## [DEMO演示及在线生成工具v2.0文档https://demo.ucharts.cn](https://demo.ucharts.cn)
## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- uCharts.js 折线图区域图增加connectNulls断点续连的功能详见示例项目中ucharts.vue
- 秋云图表组件 变更初始化方法为created变更type2d默认值为true优化2d模式下组件初始化后dom获取不到的bug
- 秋云图表组件 修复左右布局时右侧图表点击坐标错误的bug修复tooltip柱状图自定义颜色显示object的bug
## 2.0.0-202104102021-04-10
- 修复左右布局时右侧图表点击坐标错误的bug修复柱状图自定义颜色tooltip显示object的bug
- 增加标记线及柱状图自定义颜色的demo
## 2.0.0-202104092021-04-08
## v1.0版本已停更建议转uni_modules版本组件方式调用点击右侧【使用HBuilderX导入插件】即可体验DEMO演示及在线生成工具v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn)
## 图表组件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
- uCharts.js 修复钉钉小程序百度小程序measureText不准确的bug修复2d模式下饼图类activeRadius为按比例放大的bug
- 修复组件在支付宝小程序端点击位置不准确的bug
## 2.0.0-202104082021-04-07
- 修复组件在支付宝小程序端不能显示的bug目前支付宝小程不能点击交互后续修复
- uCharts.js 修复高分屏下柱状图类,圆弧进度条 自定义宽度不能按比例放大的bug
## 2.0.0-202104072021-04-06
## v1.0版本已停更建议转uni_modules版本组件方式调用点击右侧【使用HBuilderX导入插件】即可体验DEMO演示及在线生成工具v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn)
## 增加 通过tofix和unit快速格式化y轴的demo add by `howcode`
## 增加 图表组件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651)
## 2.0.0-202104062021-04-05
# 秋云图表组件+uCharts v2.0版本同步上线使用方法详见https://demo.ucharts.cn帮助页
## 2.0.02021-04-05
# 秋云图表组件+uCharts v2.0版本同步上线使用方法详见https://demo.ucharts.cn帮助页

File diff suppressed because one or more lines are too long

@ -0,0 +1,162 @@
<template>
<view class="container loading1">
<view class="shape shape1"></view>
<view class="shape shape2"></view>
<view class="shape shape3"></view>
<view class="shape shape4"></view>
</view>
</template>
<script>
export default {
name: 'loading1',
data() {
return {
};
}
}
</script>
<style scoped="true">
.container {
width: 30px;
height: 30px;
position: relative;
}
.container.loading1 {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.container .shape {
position: absolute;
width: 10px;
height: 10px;
border-radius: 1px;
}
.container .shape.shape1 {
left: 0;
background-color: #1890FF;
}
.container .shape.shape2 {
right: 0;
background-color: #91CB74;
}
.container .shape.shape3 {
bottom: 0;
background-color: #FAC858;
}
.container .shape.shape4 {
bottom: 0;
right: 0;
background-color: #EE6666;
}
.loading1 .shape1 {
-webkit-animation: animation1shape1 0.5s ease 0s infinite alternate;
animation: animation1shape1 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation1shape1 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(16px, 16px);
transform: translate(16px, 16px);
}
}
@keyframes animation1shape1 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(16px, 16px);
transform: translate(16px, 16px);
}
}
.loading1 .shape2 {
-webkit-animation: animation1shape2 0.5s ease 0s infinite alternate;
animation: animation1shape2 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation1shape2 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-16px, 16px);
transform: translate(-16px, 16px);
}
}
@keyframes animation1shape2 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-16px, 16px);
transform: translate(-16px, 16px);
}
}
.loading1 .shape3 {
-webkit-animation: animation1shape3 0.5s ease 0s infinite alternate;
animation: animation1shape3 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation1shape3 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(16px, -16px);
transform: translate(16px, -16px);
}
}
@keyframes animation1shape3 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(16px, -16px);
transform: translate(16px, -16px);
}
}
.loading1 .shape4 {
-webkit-animation: animation1shape4 0.5s ease 0s infinite alternate;
animation: animation1shape4 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation1shape4 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-16px, -16px);
transform: translate(-16px, -16px);
}
}
@keyframes animation1shape4 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-16px, -16px);
transform: translate(-16px, -16px);
}
}
</style>

@ -0,0 +1,170 @@
<template>
<view class="container loading2">
<view class="shape shape1"></view>
<view class="shape shape2"></view>
<view class="shape shape3"></view>
<view class="shape shape4"></view>
</view>
</template>
<script>
export default {
name: 'loading2',
data() {
return {
};
}
}
</script>
<style scoped="true">
.container {
width: 30px;
height: 30px;
position: relative;
}
.container.loading2 {
-webkit-transform: rotate(10deg);
transform: rotate(10deg);
}
.container.loading2 .shape {
border-radius: 5px;
}
.container.loading2{
-webkit-animation: rotation 1s infinite;
animation: rotation 1s infinite;
}
.container .shape {
position: absolute;
width: 10px;
height: 10px;
border-radius: 1px;
}
.container .shape.shape1 {
left: 0;
background-color: #1890FF;
}
.container .shape.shape2 {
right: 0;
background-color: #91CB74;
}
.container .shape.shape3 {
bottom: 0;
background-color: #FAC858;
}
.container .shape.shape4 {
bottom: 0;
right: 0;
background-color: #EE6666;
}
.loading2 .shape1 {
-webkit-animation: animation2shape1 0.5s ease 0s infinite alternate;
animation: animation2shape1 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation2shape1 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(20px, 20px);
transform: translate(20px, 20px);
}
}
@keyframes animation2shape1 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(20px, 20px);
transform: translate(20px, 20px);
}
}
.loading2 .shape2 {
-webkit-animation: animation2shape2 0.5s ease 0s infinite alternate;
animation: animation2shape2 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation2shape2 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-20px, 20px);
transform: translate(-20px, 20px);
}
}
@keyframes animation2shape2 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-20px, 20px);
transform: translate(-20px, 20px);
}
}
.loading2 .shape3 {
-webkit-animation: animation2shape3 0.5s ease 0s infinite alternate;
animation: animation2shape3 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation2shape3 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(20px, -20px);
transform: translate(20px, -20px);
}
}
@keyframes animation2shape3 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(20px, -20px);
transform: translate(20px, -20px);
}
}
.loading2 .shape4 {
-webkit-animation: animation2shape4 0.5s ease 0s infinite alternate;
animation: animation2shape4 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation2shape4 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-20px, -20px);
transform: translate(-20px, -20px);
}
}
@keyframes animation2shape4 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-20px, -20px);
transform: translate(-20px, -20px);
}
}
</style>

@ -0,0 +1,173 @@
<template>
<view class="container loading3">
<view class="shape shape1"></view>
<view class="shape shape2"></view>
<view class="shape shape3"></view>
<view class="shape shape4"></view>
</view>
</template>
<script>
export default {
name: 'loading3',
data() {
return {
};
}
}
</script>
<style scoped="true">
.container {
width: 30px;
height: 30px;
position: relative;
}
.container.loading3 {
-webkit-animation: rotation 1s infinite;
animation: rotation 1s infinite;
}
.container.loading3 .shape1 {
border-top-left-radius: 10px;
}
.container.loading3 .shape2 {
border-top-right-radius: 10px;
}
.container.loading3 .shape3 {
border-bottom-left-radius: 10px;
}
.container.loading3 .shape4 {
border-bottom-right-radius: 10px;
}
.container .shape {
position: absolute;
width: 10px;
height: 10px;
border-radius: 1px;
}
.container .shape.shape1 {
left: 0;
background-color: #1890FF;
}
.container .shape.shape2 {
right: 0;
background-color: #91CB74;
}
.container .shape.shape3 {
bottom: 0;
background-color: #FAC858;
}
.container .shape.shape4 {
bottom: 0;
right: 0;
background-color: #EE6666;
}
.loading3 .shape1 {
-webkit-animation: animation3shape1 0.5s ease 0s infinite alternate;
animation: animation3shape1 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation3shape1 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(5px, 5px);
transform: translate(5px, 5px);
}
}
@keyframes animation3shape1 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(5px, 5px);
transform: translate(5px, 5px);
}
}
.loading3 .shape2 {
-webkit-animation: animation3shape2 0.5s ease 0s infinite alternate;
animation: animation3shape2 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation3shape2 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-5px, 5px);
transform: translate(-5px, 5px);
}
}
@keyframes animation3shape2 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-5px, 5px);
transform: translate(-5px, 5px);
}
}
.loading3 .shape3 {
-webkit-animation: animation3shape3 0.5s ease 0s infinite alternate;
animation: animation3shape3 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation3shape3 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(5px, -5px);
transform: translate(5px, -5px);
}
}
@keyframes animation3shape3 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(5px, -5px);
transform: translate(5px, -5px);
}
}
.loading3 .shape4 {
-webkit-animation: animation3shape4 0.5s ease 0s infinite alternate;
animation: animation3shape4 0.5s ease 0s infinite alternate;
}
@-webkit-keyframes animation3shape4 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-5px, -5px);
transform: translate(-5px, -5px);
}
}
@keyframes animation3shape4 {
from {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
to {
-webkit-transform: translate(-5px, -5px);
transform: translate(-5px, -5px);
}
}
</style>

@ -0,0 +1,222 @@
<template>
<view class="container loading5">
<view class="shape shape1"></view>
<view class="shape shape2"></view>
<view class="shape shape3"></view>
<view class="shape shape4"></view>
</view>
</template>
<script>
export default {
name: 'loading5',
data() {
return {
};
}
}
</script>
<style scoped="true">
.container {
width: 30px;
height: 30px;
position: relative;
}
.container.loading5 .shape {
width: 15px;
height: 15px;
}
.container .shape {
position: absolute;
width: 10px;
height: 10px;
border-radius: 1px;
}
.container .shape.shape1 {
left: 0;
background-color: #1890FF;
}
.container .shape.shape2 {
right: 0;
background-color: #91CB74;
}
.container .shape.shape3 {
bottom: 0;
background-color: #FAC858;
}
.container .shape.shape4 {
bottom: 0;
right: 0;
background-color: #EE6666;
}
.loading5 .shape1 {
animation: animation5shape1 2s ease 0s infinite reverse;
}
@-webkit-keyframes animation5shape1 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(0, 15px);
transform: translate(0, 15px);
}
50% {
-webkit-transform: translate(15px, 15px);
transform: translate(15px, 15px);
}
75% {
-webkit-transform: translate(15px, 0);
transform: translate(15px, 0);
}
}
@keyframes animation5shape1 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(0, 15px);
transform: translate(0, 15px);
}
50% {
-webkit-transform: translate(15px, 15px);
transform: translate(15px, 15px);
}
75% {
-webkit-transform: translate(15px, 0);
transform: translate(15px, 0);
}
}
.loading5 .shape2 {
animation: animation5shape2 2s ease 0s infinite reverse;
}
@-webkit-keyframes animation5shape2 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(-15px, 0);
transform: translate(-15px, 0);
}
50% {
-webkit-transform: translate(-15px, 15px);
transform: translate(-15px, 15px);
}
75% {
-webkit-transform: translate(0, 15px);
transform: translate(0, 15px);
}
}
@keyframes animation5shape2 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(-15px, 0);
transform: translate(-15px, 0);
}
50% {
-webkit-transform: translate(-15px, 15px);
transform: translate(-15px, 15px);
}
75% {
-webkit-transform: translate(0, 15px);
transform: translate(0, 15px);
}
}
.loading5 .shape3 {
animation: animation5shape3 2s ease 0s infinite reverse;
}
@-webkit-keyframes animation5shape3 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(15px, 0);
transform: translate(15px, 0);
}
50% {
-webkit-transform: translate(15px, -15px);
transform: translate(15px, -15px);
}
75% {
-webkit-transform: translate(0, -15px);
transform: translate(0, -15px);
}
}
@keyframes animation5shape3 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(15px, 0);
transform: translate(15px, 0);
}
50% {
-webkit-transform: translate(15px, -15px);
transform: translate(15px, -15px);
}
75% {
-webkit-transform: translate(0, -15px);
transform: translate(0, -15px);
}
}
.loading5 .shape4 {
animation: animation5shape4 2s ease 0s infinite reverse;
}
@-webkit-keyframes animation5shape4 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(0, -15px);
transform: translate(0, -15px);
}
50% {
-webkit-transform: translate(-15px, -15px);
transform: translate(-15px, -15px);
}
75% {
-webkit-transform: translate(-15px, 0);
transform: translate(-15px, 0);
}
}
@keyframes animation5shape4 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(0, -15px);
transform: translate(0, -15px);
}
50% {
-webkit-transform: translate(-15px, -15px);
transform: translate(-15px, -15px);
}
75% {
-webkit-transform: translate(-15px, 0);
transform: translate(-15px, 0);
}
}
</style>

@ -0,0 +1,229 @@
<template>
<view class="container loading6">
<view class="shape shape1"></view>
<view class="shape shape2"></view>
<view class="shape shape3"></view>
<view class="shape shape4"></view>
</view>
</template>
<script>
export default {
name: 'loading6',
data() {
return {
};
}
}
</script>
<style scoped="true">
.container {
width: 30px;
height: 30px;
position: relative;
}
.container.loading6 {
-webkit-animation: rotation 1s infinite;
animation: rotation 1s infinite;
}
.container.loading6 .shape {
width: 12px;
height: 12px;
border-radius: 2px;
}
.container .shape {
position: absolute;
width: 10px;
height: 10px;
border-radius: 1px;
}
.container .shape.shape1 {
left: 0;
background-color: #1890FF;
}
.container .shape.shape2 {
right: 0;
background-color: #91CB74;
}
.container .shape.shape3 {
bottom: 0;
background-color: #FAC858;
}
.container .shape.shape4 {
bottom: 0;
right: 0;
background-color: #EE6666;
}
.loading6 .shape1 {
-webkit-animation: animation6shape1 2s linear 0s infinite normal;
animation: animation6shape1 2s linear 0s infinite normal;
}
@-webkit-keyframes animation6shape1 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(0, 18px);
transform: translate(0, 18px);
}
50% {
-webkit-transform: translate(18px, 18px);
transform: translate(18px, 18px);
}
75% {
-webkit-transform: translate(18px, 0);
transform: translate(18px, 0);
}
}
@keyframes animation6shape1 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(0, 18px);
transform: translate(0, 18px);
}
50% {
-webkit-transform: translate(18px, 18px);
transform: translate(18px, 18px);
}
75% {
-webkit-transform: translate(18px, 0);
transform: translate(18px, 0);
}
}
.loading6 .shape2 {
-webkit-animation: animation6shape2 2s linear 0s infinite normal;
animation: animation6shape2 2s linear 0s infinite normal;
}
@-webkit-keyframes animation6shape2 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(-18px, 0);
transform: translate(-18px, 0);
}
50% {
-webkit-transform: translate(-18px, 18px);
transform: translate(-18px, 18px);
}
75% {
-webkit-transform: translate(0, 18px);
transform: translate(0, 18px);
}
}
@keyframes animation6shape2 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(-18px, 0);
transform: translate(-18px, 0);
}
50% {
-webkit-transform: translate(-18px, 18px);
transform: translate(-18px, 18px);
}
75% {
-webkit-transform: translate(0, 18px);
transform: translate(0, 18px);
}
}
.loading6 .shape3 {
-webkit-animation: animation6shape3 2s linear 0s infinite normal;
animation: animation6shape3 2s linear 0s infinite normal;
}
@-webkit-keyframes animation6shape3 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(18px, 0);
transform: translate(18px, 0);
}
50% {
-webkit-transform: translate(18px, -18px);
transform: translate(18px, -18px);
}
75% {
-webkit-transform: translate(0, -18px);
transform: translate(0, -18px);
}
}
@keyframes animation6shape3 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(18px, 0);
transform: translate(18px, 0);
}
50% {
-webkit-transform: translate(18px, -18px);
transform: translate(18px, -18px);
}
75% {
-webkit-transform: translate(0, -18px);
transform: translate(0, -18px);
}
}
.loading6 .shape4 {
-webkit-animation: animation6shape4 2s linear 0s infinite normal;
animation: animation6shape4 2s linear 0s infinite normal;
}
@-webkit-keyframes animation6shape4 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(0, -18px);
transform: translate(0, -18px);
}
50% {
-webkit-transform: translate(-18px, -18px);
transform: translate(-18px, -18px);
}
75% {
-webkit-transform: translate(-18px, 0);
transform: translate(-18px, 0);
}
}
@keyframes animation6shape4 {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
25% {
-webkit-transform: translate(0, -18px);
transform: translate(0, -18px);
}
50% {
-webkit-transform: translate(-18px, -18px);
transform: translate(-18px, -18px);
}
75% {
-webkit-transform: translate(-18px, 0);
transform: translate(-18px, 0);
}
}
</style>

@ -0,0 +1,36 @@
<template>
<view>
<Loading1 v-if="loadingType==1"/>
<Loading2 v-if="loadingType==2"/>
<Loading3 v-if="loadingType==3"/>
<Loading4 v-if="loadingType==4"/>
<Loading5 v-if="loadingType==5"/>
</view>
</template>
<script>
import Loading1 from "./loading1.vue";
import Loading2 from "./loading2.vue";
import Loading3 from "./loading3.vue";
import Loading4 from "./loading4.vue";
import Loading5 from "./loading5.vue";
export default {
components:{Loading1,Loading2,Loading3,Loading4,Loading5},
name: 'qiun-loading',
props: {
loadingType: {
type: Number,
default: 2
},
},
data() {
return {
};
},
}
</script>
<style>
</style>

@ -0,0 +1,422 @@
/*
* uCharts®
* 高性能跨平台图表库支持H5APP小程序微信/支付宝/百度/头条/QQ/360VueTaro等支持canvas的框架平台
* Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved.
* Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
* 复制使用请保留本段注释感谢支持开源
*
* uCharts®官方网站
* https://www.uCharts.cn
*
* 开源地址:
* https://gitee.com/uCharts/uCharts
*
* uni-app插件市场地址
* http://ext.dcloud.net.cn/plugin?id=271
*
*/
// 通用配置项
// 主题颜色配置如每个图表类型需要不同主题请在对应图表类型上更改color属性
const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
const cfe = {
//demotype为自定义图表类型
"type": ["pie", "ring", "rose", "funnel", "line", "column", "area", "radar", "gauge","candle","demotype"],
//增加自定义图表类型如果需要categories请在这里加入您的图表类型例如最后的"demotype"
"categories": ["line", "column", "area", "radar", "gauge", "candle","demotype"],
//instance为实例变量承载属性option为eopts承载属性不要删除
"instance": {},
"option": {},
//下面是自定义format配置因除H5端外的其他端无法通过props传递函数只能通过此属性对应下标的方式来替换
"formatter":{
"tooltipDemo1":function(res){
let result = ''
for (let i in res) {
if (i == 0) {
result += res[i].axisValueLabel + '年销售额'
}
let value = '--'
if (res[i].data !== null) {
value = res[i].data
}
// #ifdef H5
result += '\n' + res[i].seriesName + '' + value + ' 万元'
// #endif
// #ifdef APP-PLUS
result += '<br/>' + res[i].marker + res[i].seriesName + '' + value + ' 万元'
// #endif
}
return result;
},
legendFormat:function(name){
return "自定义图例+"+name;
},
yAxisFormatDemo:function (value, index) {
return value + '元';
},
seriesFormatDemo:function(res){
return res.name + '年' + res.value + '元';
}
},
//这里演示了自定义您的图表类型的option可以随意命名之后在组件上 type="demotype" 后组件会调用这个花括号里的option如果组件上还存在eopts参数会将demotype与eopts中option合并后渲染图表。
"demotype":{
"color": color,
//在这里填写echarts的option即可
},
//下面是自定义配置,请添加项目所需的通用配置
"column": {
"color": color,
"title": {
"text": ''
},
"tooltip": {
"trigger": 'axis'
},
"grid": {
"top": 30,
"bottom": 50,
"right": 15,
"left": 40
},
"legend": {
"bottom": 'left',
},
"toolbox": {
"show": false,
},
"xAxis": {
"type": 'category',
"axisLabel": {
"color": '#666666'
},
"axisLine": {
"lineStyle": {
"color": '#CCCCCC'
}
},
"boundaryGap": true,
"data": []
},
"yAxis": {
"type": 'value',
"axisTick": {
"show": false,
},
"axisLabel": {
"color": '#666666'
},
"axisLine": {
"lineStyle": {
"color": '#CCCCCC'
}
},
},
"seriesTemplate": {
"name": '',
"type": 'bar',
"data": [],
"barwidth": 20,
"label": {
"show": true,
"color": "#666666",
"position": 'top',
},
},
},
"line": {
"color": color,
"title": {
"text": ''
},
"tooltip": {
"trigger": 'axis'
},
"grid": {
"top": 30,
"bottom": 50,
"right": 15,
"left": 40
},
"legend": {
"bottom": 'left',
},
"toolbox": {
"show": false,
},
"xAxis": {
"type": 'category',
"axisLabel": {
"color": '#666666'
},
"axisLine": {
"lineStyle": {
"color": '#CCCCCC'
}
},
"boundaryGap": true,
"data": []
},
"yAxis": {
"type": 'value',
"axisTick": {
"show": false,
},
"axisLabel": {
"color": '#666666'
},
"axisLine": {
"lineStyle": {
"color": '#CCCCCC'
}
},
},
"seriesTemplate": {
"name": '',
"type": 'line',
"data": [],
"barwidth": 20,
"label": {
"show": true,
"color": "#666666",
"position": 'top',
},
},
},
"area": {
"color": color,
"title": {
"text": ''
},
"tooltip": {
"trigger": 'axis'
},
"grid": {
"top": 30,
"bottom": 50,
"right": 15,
"left": 40
},
"legend": {
"bottom": 'left',
},
"toolbox": {
"show": false,
},
"xAxis": {
"type": 'category',
"axisLabel": {
"color": '#666666'
},
"axisLine": {
"lineStyle": {
"color": '#CCCCCC'
}
},
"boundaryGap": true,
"data": []
},
"yAxis": {
"type": 'value',
"axisTick": {
"show": false,
},
"axisLabel": {
"color": '#666666'
},
"axisLine": {
"lineStyle": {
"color": '#CCCCCC'
}
},
},
"seriesTemplate": {
"name": '',
"type": 'line',
"data": [],
"areaStyle": {},
"label": {
"show": true,
"color": "#666666",
"position": 'top',
},
},
},
"pie": {
"color": color,
"title": {
"text": ''
},
"tooltip": {
"trigger": 'item'
},
"grid": {
"top": 40,
"bottom": 30,
"right": 15,
"left": 15
},
"legend": {
"bottom": 'left',
},
"seriesTemplate": {
"name": '',
"type": 'pie',
"data": [],
"radius": '50%',
"label": {
"show": true,
"color": "#666666",
"position": 'top',
},
},
},
"ring": {
"color": color,
"title": {
"text": ''
},
"tooltip": {
"trigger": 'item'
},
"grid": {
"top": 40,
"bottom": 30,
"right": 15,
"left": 15
},
"legend": {
"bottom": 'left',
},
"seriesTemplate": {
"name": '',
"type": 'pie',
"data": [],
"radius": ['40%', '70%'],
"avoidLabelOverlap": false,
"label": {
"show": true,
"color": "#666666",
"position": 'top',
},
"labelLine": {
"show": true
},
},
},
"rose": {
"color": color,
"title": {
"text": ''
},
"tooltip": {
"trigger": 'item'
},
"legend": {
"top": 'bottom'
},
"seriesTemplate": {
"name": '',
"type": 'pie',
"data": [],
"radius": "55%",
"center": ['50%', '50%'],
"roseType": 'area',
},
},
"funnel": {
"color": color,
"title": {
"text": ''
},
"tooltip": {
"trigger": 'item',
"formatter": "{b} : {c}%"
},
"legend": {
"top": 'bottom'
},
"seriesTemplate": {
"name": '',
"type": 'funnel',
"left": '10%',
"top": 60,
"bottom": 60,
"width": '80%',
"min": 0,
"max": 100,
"minSize": '0%',
"maxSize": '100%',
"sort": 'descending',
"gap": 2,
"label": {
"show": true,
"position": 'inside'
},
"labelLine": {
"length": 10,
"lineStyle": {
"width": 1,
"type": 'solid'
}
},
"itemStyle": {
"bordercolor": '#fff',
"borderwidth": 1
},
"emphasis": {
"label": {
"fontSize": 20
}
},
"data": [],
},
},
"gauge": {
"color": color,
"tooltip": {
"formatter": '{a} <br/>{b} : {c}%'
},
"seriesTemplate": {
"name": '业务指标',
"type": 'gauge',
"detail": {"formatter": '{value}%'},
"data": [{"value": 50, "name": '完成率'}]
},
},
"candle": {
"xAxis": {
"data": []
},
"yAxis": {},
"color": color,
"title": {
"text": ''
},
"dataZoom": [{
"type": 'inside',
"xAxisIndex": [0, 1],
"start": 10,
"end": 100
},
{
"show": true,
"xAxisIndex": [0, 1],
"type": 'slider',
"bottom": 10,
"start": 10,
"end": 100
}
],
"seriesTemplate": {
"name": '',
"type": 'k',
"data": [],
},
}
}
export default cfe;

@ -0,0 +1,606 @@
/*
* uCharts®
* 高性能跨平台图表库支持H5APP小程序微信/支付宝/百度/头条/QQ/360VueTaro等支持canvas的框架平台
* Copyright (c) 2021 QIUN®秋云 https://www.ucharts.cn All rights reserved.
* Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
* 复制使用请保留本段注释感谢支持开源
*
* uCharts®官方网站
* https://www.uCharts.cn
*
* 开源地址:
* https://gitee.com/uCharts/uCharts
*
* uni-app插件市场地址
* http://ext.dcloud.net.cn/plugin?id=271
*
*/
// 主题颜色配置如每个图表类型需要不同主题请在对应图表类型上更改color属性
const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
//事件转换函数主要用作格式化x轴为时间轴根据需求自行修改
const formatDateTime = (timeStamp, returnType)=>{
var date = new Date();
date.setTime(timeStamp * 1000);
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h = date.getHours();
h = h < 10 ? ('0' + h) : h;
var minute = date.getMinutes();
var second = date.getSeconds();
minute = minute < 10 ? ('0' + minute) : minute;
second = second < 10 ? ('0' + second) : second;
if(returnType == 'full'){return y + '-' + m + '-' + d + ' '+ h +':' + minute + ':' + second;}
if(returnType == 'y-m-d'){return y + '-' + m + '-' + d;}
if(returnType == 'h:m'){return h +':' + minute;}
if(returnType == 'h:m:s'){return h +':' + minute +':' + second;}
return [y, m, d, h, minute, second];
}
const cfu = {
//demotype为自定义图表类型一般不需要自定义图表类型只需要改根节点上对应的类型即可
"type":["pie","ring","rose","word","funnel","map","arcbar","line","column","mount","bar","area","radar","gauge","candle","mix","tline","tarea","scatter","bubble","demotype"],
"range":["饼状图","圆环图","玫瑰图","词云图","漏斗图","地图","圆弧进度条","折线图","柱状图","山峰图","条状图","区域图","雷达图","仪表盘","K线图","混合图","时间轴折线","时间轴区域","散点图","气泡图","自定义类型"],
//增加自定义图表类型如果需要categories请在这里加入您的图表类型例如最后的"demotype"
//自定义类型时需要注意"tline","tarea","scatter","bubble"等时间轴矢量x轴类图表没有categories不需要加入categories
"categories":["line","column","mount","bar","area","radar","gauge","candle","mix","demotype"],
//instance为实例变量承载属性不要删除
"instance":{},
//option为opts及eopts承载属性不要删除
"option":{},
//下面是自定义format配置因除H5端外的其他端无法通过props传递函数只能通过此属性对应下标的方式来替换
"formatter":{
"yAxisDemo1":function(val, index, opts){return val+'元'},
"yAxisDemo2":function(val, index, opts){return val.toFixed(2)},
"xAxisDemo1":function(val, index, opts){return val+'年';},
"xAxisDemo2":function(val, index, opts){return formatDateTime(val,'h:m')},
"seriesDemo1":function(val, index, series, opts){return val+'元'},
"tooltipDemo1":function(item, category, index, opts){
if(index==0){
return '随便用'+item.data+'年'
}else{
return '其他我没改'+item.data+'天'
}
},
"pieDemo":function(val, index, series, opts){
if(index !== undefined){
return series[index].name+''+series[index].data+'元'
}
},
},
//这里演示了自定义您的图表类型的option可以随意命名之后在组件上 type="demotype" 后组件会调用这个花括号里的option如果组件上还存在opts参数会将demotype与opts中option合并后渲染图表。
"demotype":{
//我这里把曲线图当做了自定义图表类型,您可以根据需要随意指定类型或配置
"type": "line",
"color": color,
"padding": [15,10,0,15],
"xAxis": {
"disableGrid": true,
},
"yAxis": {
"gridType": "dash",
"dashLength": 2,
},
"legend": {
},
"extra": {
"line": {
"type": "curve",
"width": 2
},
}
},
//下面是自定义配置,请添加项目所需的通用配置
"pie":{
"type": "pie",
"color": color,
"padding": [5,5,5,5],
"extra": {
"pie": {
"activeOpacity": 0.5,
"activeRadius": 10,
"offsetAngle": 0,
"labelWidth": 15,
"border": true,
"borderWidth": 3,
"borderColor": "#FFFFFF"
},
}
},
"ring":{
"type": "ring",
"color": color,
"padding": [5,5,5,5],
"rotate": false,
"dataLabel": true,
"legend": {
"show": true,
"position": "right",
"lineHeight": 25,
},
"title": {
"name": "收益率",
"fontSize": 15,
"color": "#666666"
},
"subtitle": {
"name": "70%",
"fontSize": 25,
"color": "#7cb5ec"
},
"extra": {
"ring": {
"ringWidth":30,
"activeOpacity": 0.5,
"activeRadius": 10,
"offsetAngle": 0,
"labelWidth": 15,
"border": true,
"borderWidth": 3,
"borderColor": "#FFFFFF"
},
},
},
"rose":{
"type": "rose",
"color": color,
"padding": [5,5,5,5],
"legend": {
"show": true,
"position": "left",
"lineHeight": 25,
},
"extra": {
"rose": {
"type": "area",
"minRadius": 50,
"activeOpacity": 0.5,
"activeRadius": 10,
"offsetAngle": 0,
"labelWidth": 15,
"border": false,
"borderWidth": 2,
"borderColor": "#FFFFFF"
},
}
},
"word":{
"type": "word",
"color": color,
"extra": {
"word": {
"type": "normal",
"autoColors": false
}
}
},
"funnel":{
"type": "funnel",
"color": color,
"padding": [15,15,0,15],
"extra": {
"funnel": {
"activeOpacity": 0.3,
"activeWidth": 10,
"border": true,
"borderWidth": 2,
"borderColor": "#FFFFFF",
"fillOpacity": 1,
"labelAlign": "right"
},
}
},
"map":{
"type": "map",
"color": color,
"padding": [0,0,0,0],
"dataLabel": true,
"extra": {
"map": {
"border": true,
"borderWidth": 1,
"borderColor": "#666666",
"fillOpacity": 0.6,
"activeBorderColor": "#F04864",
"activeFillColor": "#FACC14",
"activeFillOpacity": 1
},
}
},
"arcbar":{
"type": "arcbar",
"color": color,
"title": {
"name": "百分比",
"fontSize": 25,
"color": "#00FF00"
},
"subtitle": {
"name": "默认标题",
"fontSize": 15,
"color": "#666666"
},
"extra": {
"arcbar": {
"type": "default",
"width": 12,
"backgroundColor": "#E9E9E9",
"startAngle": 0.75,
"endAngle": 0.25,
"gap": 2
}
}
},
"line":{
"type": "line",
"color": color,
"padding": [15,10,0,15],
"xAxis": {
"disableGrid": true,
},
"yAxis": {
"gridType": "dash",
"dashLength": 2,
},
"legend": {
},
"extra": {
"line": {
"type": "straight",
"width": 2,
"activeType": "hollow"
},
}
},
"tline":{
"type": "line",
"color": color,
"padding": [15,10,0,15],
"xAxis": {
"disableGrid": false,
"boundaryGap":"justify",
},
"yAxis": {
"gridType": "dash",
"dashLength": 2,
"data":[
{
"min":0,
"max":80
}
]
},
"legend": {
},
"extra": {
"line": {
"type": "curve",
"width": 2,
"activeType": "hollow"
},
}
},
"tarea":{
"type": "area",
"color": color,
"padding": [15,10,0,15],
"xAxis": {
"disableGrid": true,
"boundaryGap":"justify",
},
"yAxis": {
"gridType": "dash",
"dashLength": 2,
"data":[
{
"min":0,
"max":80
}
]
},
"legend": {
},
"extra": {
"area": {
"type": "curve",
"opacity": 0.2,
"addLine": true,
"width": 2,
"gradient": true,
"activeType": "hollow"
},
}
},
"column":{
"type": "column",
"color": color,
"padding": [15,15,0,5],
"xAxis": {
"disableGrid": true,
},
"yAxis": {
"data":[{"min":0}]
},
"legend": {
},
"extra": {
"column": {
"type": "group",
"width": 30,
"activeBgColor": "#000000",
"activeBgOpacity": 0.08
},
}
},
"mount":{
"type": "mount",
"color": color,
"padding": [15,15,0,5],
"xAxis": {
"disableGrid": true,
},
"yAxis": {
"data":[{"min":0}]
},
"legend": {
},
"extra": {
"mount": {
"type": "mount",
"widthRatio": 1.5,
},
}
},
"bar":{
"type": "bar",
"color": color,
"padding": [15,30,0,5],
"xAxis": {
"boundaryGap":"justify",
"disableGrid":false,
"min":0,
"axisLine":false
},
"yAxis": {
},
"legend": {
},
"extra": {
"bar": {
"type": "group",
"width": 30,
"meterBorde": 1,
"meterFillColor": "#FFFFFF",
"activeBgColor": "#000000",
"activeBgOpacity": 0.08
},
}
},
"area":{
"type": "area",
"color": color,
"padding": [15,15,0,15],
"xAxis": {
"disableGrid": true,
},
"yAxis": {
"gridType": "dash",
"dashLength": 2,
},
"legend": {
},
"extra": {
"area": {
"type": "straight",
"opacity": 0.2,
"addLine": true,
"width": 2,
"gradient": false,
"activeType": "hollow"
},
}
},
"radar":{
"type": "radar",
"color": color,
"padding": [5,5,5,5],
"dataLabel": false,
"legend": {
"show": true,
"position": "right",
"lineHeight": 25,
},
"extra": {
"radar": {
"gridType": "radar",
"gridColor": "#CCCCCC",
"gridCount": 3,
"opacity": 0.2,
"max": 200,
"labelShow": true
},
}
},
"gauge":{
"type": "gauge",
"color": color,
"title": {
"name": "66Km/H",
"fontSize": 25,
"color": "#2fc25b",
"offsetY": 50
},
"subtitle": {
"name": "实时速度",
"fontSize": 15,
"color": "#1890ff",
"offsetY": -50
},
"extra": {
"gauge": {
"type": "default",
"width": 30,
"labelColor": "#666666",
"startAngle": 0.75,
"endAngle": 0.25,
"startNumber": 0,
"endNumber": 100,
"labelFormat": "",
"splitLine": {
"fixRadius": 0,
"splitNumber": 10,
"width": 30,
"color": "#FFFFFF",
"childNumber": 5,
"childWidth": 12
},
"pointer": {
"width": 24,
"color": "auto"
}
}
}
},
"candle":{
"type": "candle",
"color": color,
"padding": [15,15,0,15],
"enableScroll": true,
"enableMarkLine": true,
"dataLabel": false,
"xAxis": {
"labelCount": 4,
"itemCount": 40,
"disableGrid": true,
"gridColor": "#CCCCCC",
"gridType": "solid",
"dashLength": 4,
"scrollShow": true,
"scrollAlign": "left",
"scrollColor": "#A6A6A6",
"scrollBackgroundColor": "#EFEBEF"
},
"yAxis": {
},
"legend": {
},
"extra": {
"candle": {
"color": {
"upLine": "#f04864",
"upFill": "#f04864",
"downLine": "#2fc25b",
"downFill": "#2fc25b"
},
"average": {
"show": true,
"name": ["MA5","MA10","MA30"],
"day": [5,10,20],
"color": ["#1890ff","#2fc25b","#facc14"]
}
},
"markLine": {
"type": "dash",
"dashLength": 5,
"data": [
{
"value": 2150,
"lineColor": "#f04864",
"showLabel": true
},
{
"value": 2350,
"lineColor": "#f04864",
"showLabel": true
}
]
}
}
},
"mix":{
"type": "mix",
"color": color,
"padding": [15,15,0,15],
"xAxis": {
"disableGrid": true,
},
"yAxis": {
"disabled": false,
"disableGrid": false,
"splitNumber": 5,
"gridType": "dash",
"dashLength": 4,
"gridColor": "#CCCCCC",
"padding": 10,
"showTitle": true,
"data": []
},
"legend": {
},
"extra": {
"mix": {
"column": {
"width": 20
}
},
}
},
"scatter":{
"type": "scatter",
"color":color,
"padding":[15,15,0,15],
"dataLabel":false,
"xAxis": {
"disableGrid": false,
"gridType":"dash",
"splitNumber":5,
"boundaryGap":"justify",
"min":0
},
"yAxis": {
"disableGrid": false,
"gridType":"dash",
},
"legend": {
},
"extra": {
"scatter": {
},
}
},
"bubble":{
"type": "bubble",
"color":color,
"padding":[15,15,0,15],
"xAxis": {
"disableGrid": false,
"gridType":"dash",
"splitNumber":5,
"boundaryGap":"justify",
"min":0,
"max":250
},
"yAxis": {
"disableGrid": false,
"gridType":"dash",
"data":[{
"min":0,
"max":150
}]
},
"legend": {
},
"extra": {
"bubble": {
"border":2,
"opacity": 0.5,
},
}
}
}
export default cfu;

@ -0,0 +1,5 @@
# uCharts JSSDK说明
1、如不使用uCharts组件可直接引用u-charts.js打包编译后会`自动压缩`,压缩后体积约为`120kb`。
2、如果120kb的体积仍需压缩请手到uCharts官网通过在线定制选择您需要的图表。
3、config-ucharts.js为uCharts组件的用户配置文件升级前请`自行备份config-ucharts.js`文件,以免被强制覆盖。
4、config-echarts.js为ECharts组件的用户配置文件升级前请`自行备份config-echarts.js`文件,以免被强制覆盖。

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,80 @@
{
"id": "qiun-data-charts",
"displayName": "秋云 ucharts echarts 高性能跨全端图表组件",
"version": "2.5.0-20230101",
"description": "uCharts 新增正负柱状图支持H5及APP用 ucharts echarts 渲染图表uniapp可视化首选组件",
"keywords": [
"ucharts",
"echarts",
"f2",
"图表",
"可视化"
],
"repository": "https://gitee.com/uCharts/uCharts",
"engines": {
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": "474119"
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/~qiun",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"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"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

@ -0,0 +1,84 @@
![logo](https://img-blog.csdnimg.cn/4a276226973841468c1be356f8d9438b.png)
[![star](https://gitee.com/uCharts/uCharts/badge/star.svg?theme=gvp)](https://gitee.com/uCharts/uCharts/stargazers)
[![fork](https://gitee.com/uCharts/uCharts/badge/fork.svg?theme=gvp)](https://gitee.com/uCharts/uCharts/members)
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![npm package](https://img.shields.io/npm/v/@qiun/ucharts.svg?style=flat-square)](https://www.npmjs.com/~qiun)
## uCharts简介
`uCharts`是一款基于`canvas API`开发的适用于所有前端应用的图表库,开发者编写一套代码,可运行到 Web、iOS、Android基于 uni-app / taro )、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等更多支持 canvas API 的平台。
## 官方网站
## [https://www.ucharts.cn](https://www.ucharts.cn)
## 快速体验
一套代码编到多个平台依次扫描二维码亲自体验uCharts图表跨平台效果其他平台请自行编译。
![](https://www.ucharts.cn/images/web/guide/qrcode20220224.png)
![](https://img-blog.csdnimg.cn/7d0115593ff24ac39a224fb7c6ed72a4.png)
## 致开发者
感谢各位开发者`五年`来对秋云及uCharts的支持uCharts的进步离不开各位开发者的鼓励与贡献。为更好的帮助各位开发者使用图表工具我们推出了新版官网增加了在线定制、问答社区、在线配置等一些增值服务为确保您能更好的应用图表组件建议您先`仔细阅读官网指南`以及`常见问题`,而不是下载下来`直接使用`。如仍然不能解决,请到`官网社区`或开通会员后加入`专属VIP会员群`提问将会很快得到回答。
## 视频教程
## [uCharts新手入门教程](https://www.bilibili.com/video/BV1qA411Q7se/?share_source=copy_web&vd_source=42a1242f9aaade6427736af69eb2e1d9)
## 社群支持
uCharts官方拥有5个2000人的QQ群及专属VIP会员群支持庞大的用户量证明我们一直在努力请各位放心使用uCharts的开源图表组件的开发团队付出了大量的时间与精力经过四来的考验不会有比较明显的bug请各位放心使用。如果您有更好的想法可以在`码云提交Pull Requests`以帮助更多开发者完成需求再次感谢各位对uCharts的鼓励与支持
#### 官方交流群
- 交流群1371774600已满
- 交流群2619841586已满
- 交流群3955340127已满
- 交流群4641669795已满
- 交流群5236294809只能扫码加入
![](https://www.ucharts.cn/images/web/qq5.jpg)
- 口令`uniapp`
#### 专属VIP会员群
- 开通会员后详见【账号详情】页面中顶部的滚动通知
- 口令`您的用户ID`
## 版权信息
uCharts始终坚持开源遵循 [Apache Licence 2.0](https://www.apache.org/licenses/LICENSE-2.0.html) 开源协议意味着您无需支付任何费用即可将uCharts应用到您的产品中。
注意这并不意味着您可以将uCharts应用到非法的领域比如涉及赌博暴力等方面。如因此产生纠纷或法律问题uCharts相关方及秋云科技不承担任何责任。
## 合作伙伴
[![DIY官网](https://www.ucharts.cn/images/web/guide/links/diy-gw.png)](https://www.diygw.com/)
[![HasChat](https://www.ucharts.cn/images/web/guide/links/haschat.png)](https://gitee.com/howcode/has-chat)
[![uViewUI](https://www.ucharts.cn/images/web/guide/links/uView.png)](https://www.uviewui.com/)
[![图鸟UI](https://www.ucharts.cn/images/web/guide/links/tuniao.png)](https://ext.dcloud.net.cn/plugin?id=7088)
[![thorui](https://www.ucharts.cn/images/web/guide/links/thorui.png)](https://ext.dcloud.net.cn/publisher?id=202)
[![FirstUI](https://www.ucharts.cn/images/web/guide/links/first.png)](https://www.firstui.cn/)
[![nProUI](https://www.ucharts.cn/images/web/guide/links/nPro.png)](https://ext.dcloud.net.cn/plugin?id=5169)
[![GraceUI](https://www.ucharts.cn/images/web/guide/links/grace.png)](https://www.graceui.com/)
## 更新记录
详见官网指南中说明,[点击此处查看](https://www.ucharts.cn/v2/#/guide/index?id=100)
## 相关链接
- [uCharts官网](https://www.ucharts.cn)
- [DCloud插件市场地址](https://ext.dcloud.net.cn/plugin?id=271)
- [uCharts码云开源托管地址](https://gitee.com/uCharts/uCharts) [![star](https://gitee.com/uCharts/uCharts/badge/star.svg?theme=gvp)](https://gitee.com/uCharts/uCharts/stargazers)
- [uCharts npm开源地址](https://www.ucharts.cn)
- [ECharts官网](https://echarts.apache.org/zh/index.html)
- [ECharts配置手册](https://echarts.apache.org/zh/option.html)
- [图表组件在项目中的应用 ReportPlus数据报表](https://www.ucharts.cn/v2/#/layout/info?id=1)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,167 @@
<template>
<view class="uni-section">
<view class="uni-section-header" @click="onClick">
<view class="uni-section-header__decoration" v-if="type" :class="type" />
<slot v-else name="decoration"></slot>
<view class="uni-section-header__content">
<text :style="{'font-size':titleFontSize,'color':titleColor}" class="uni-section__content-title" :class="{'distraction':!subTitle}">{{ title }}</text>
<text v-if="subTitle" :style="{'font-size':subTitleFontSize,'color':subTitleColor}" class="uni-section-header__content-sub">{{ subTitle }}</text>
</view>
<view class="uni-section-header__slot-right">
<slot name="right"></slot>
</view>
</view>
<view class="uni-section-content" :style="{padding: _padding}">
<slot />
</view>
</view>
</template>
<script>
/**
* Section 标题栏
* @description 标题栏
* @property {String} type = [line|circle|square] 标题装饰类型
* @value line 竖线
* @value circle 圆形
* @value square 正方形
* @property {String} title 主标题
* @property {String} titleFontSize 主标题字体大小
* @property {String} titleColor 主标题字体颜色
* @property {String} subTitle 副标题
* @property {String} subTitleFontSize 副标题字体大小
* @property {String} subTitleColor 副标题字体颜色
* @property {String} padding 默认插槽 padding
*/
export default {
name: 'UniSection',
emits:['click'],
props: {
type: {
type: String,
default: ''
},
title: {
type: String,
required: true,
default: ''
},
titleFontSize: {
type: String,
default: '14px'
},
titleColor:{
type: String,
default: '#333'
},
subTitle: {
type: String,
default: ''
},
subTitleFontSize: {
type: String,
default: '12px'
},
subTitleColor: {
type: String,
default: '#999'
},
padding: {
type: [Boolean, String],
default: false
}
},
computed:{
_padding(){
if(typeof this.padding === 'string'){
return this.padding
}
return this.padding?'10px':''
}
},
watch: {
title(newVal) {
if (uni.report && newVal !== '') {
uni.report('title', newVal)
}
}
},
methods: {
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" >
$uni-primary: #2979ff !default;
.uni-section {
background-color: #fff;
.uni-section-header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 12px 10px;
font-weight: normal;
&__decoration{
margin-right: 6px;
background-color: $uni-primary;
&.line {
width: 4px;
height: 12px;
border-radius: 10px;
}
&.circle {
width: 8px;
height: 8px;
border-top-right-radius: 50px;
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
border-bottom-right-radius: 50px;
}
&.square {
width: 8px;
height: 8px;
}
}
&__content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
flex: 1;
color: #333;
.distraction {
flex-direction: row;
align-items: center;
}
&-sub {
margin-top: 2px;
}
}
&__slot-right{
font-size: 14px;
}
}
.uni-section-content{
font-size: 14px;
}
}
</style>

@ -0,0 +1,29 @@
// 应用全局配置
const config = {
baseUrl: 'https://vue.ruoyi.vip/prod-api',
//cloud后台网关地址
// baseUrl: 'http://192.168.10.3:8080',
// 应用信息
appInfo: {
// 应用名称
name: "ruoyi-app-vue3",
// 应用版本
version: "1.1.0",
// 应用logo
logo: "/static/logo.png",
// 官方网站
site_url: "http://ruoyi.vip",
// 政策协议
agreements: [{
title: "隐私政策",
url: "https://ruoyi.vip/protocol.html"
},
{
title: "用户服务协议",
url: "https://ruoyi.vip/protocol.html"
}
]
}
}
export default config

9
src/env.d.ts vendored

@ -0,0 +1,9 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
declare module "uview-plus";

@ -0,0 +1,14 @@
import App from './App.vue'
import plugins from './plugins'
import uviewPlus from 'uview-plus'
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
app.use(uviewPlus)
app.use(plugins)
return {
app
}
}

@ -0,0 +1,72 @@
{
"name" : "ruoyi-vue3",
"appid" : "__UNI__3DD118D",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
}

@ -0,0 +1,75 @@
{
"name": "uni-preset-vue",
"version": "0.0.0",
"scripts": {
"dev:app": "uni -p app",
"dev:app-android": "uni -p app-android",
"dev:app-ios": "uni -p app-ios",
"dev:custom": "uni -p",
"dev:h5": "uni",
"dev:h5:ssr": "uni --ssr",
"dev:mp-alipay": "uni -p mp-alipay",
"dev:mp-baidu": "uni -p mp-baidu",
"dev:mp-jd": "uni -p mp-jd",
"dev:mp-kuaishou": "uni -p mp-kuaishou",
"dev:mp-lark": "uni -p mp-lark",
"dev:mp-qq": "uni -p mp-qq",
"dev:mp-toutiao": "uni -p mp-toutiao",
"dev:mp-weixin": "uni -p mp-weixin",
"dev:quickapp-webview": "uni -p quickapp-webview",
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
"build:app": "uni build -p app",
"build:app-android": "uni build -p app-android",
"build:app-ios": "uni build -p app-ios",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "uni build -p mp-alipay",
"build:mp-baidu": "uni build -p mp-baidu",
"build:mp-jd": "uni build -p mp-jd",
"build:mp-kuaishou": "uni build -p mp-kuaishou",
"build:mp-lark": "uni build -p mp-lark",
"build:mp-qq": "uni build -p mp-qq",
"build:mp-toutiao": "uni build -p mp-toutiao",
"build:mp-weixin": "uni build -p mp-weixin",
"build:quickapp-webview": "uni build -p quickapp-webview",
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
"type-check": "vue-tsc --noEmit"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-3080720230703001",
"@dcloudio/uni-app-plus": "3.0.0-3080720230703001",
"@dcloudio/uni-components": "3.0.0-3080720230703001",
"@dcloudio/uni-h5": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-alipay": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-baidu": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-jd": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-lark": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-qq": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-toutiao": "3.0.0-3080720230703001",
"@dcloudio/uni-mp-weixin": "3.0.0-3080720230703001",
"@dcloudio/uni-quickapp-webview": "3.0.0-3080720230703001",
"@ttou/uview-typings": "^2.0.5",
"clipboard": "^2.0.11",
"dayjs": "^1.11.9",
"uview-plus": "^3.1.36",
"vue": "^3.2.45",
"vue-i18n": "^9.1.9"
},
"devDependencies": {
"@dcloudio/types": "^3.3.2",
"@dcloudio/uni-automator": "3.0.0-3080720230703001",
"@dcloudio/uni-cli-shared": "3.0.0-3080720230703001",
"@dcloudio/uni-stacktracey": "3.0.0-3080720230703001",
"@dcloudio/vite-plugin-uni": "3.0.0-3080720230703001",
"@vue/tsconfig": "^0.1.3",
"sass": "^1.64.2",
"sass-loader": "10",
"typescript": "^4.9.4",
"vite": "4.0.4",
"vue-tsc": "^1.0.24"
}
}

@ -0,0 +1,266 @@
{
"easycom": {
"custom": {
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
"qiun-(.*)": "@/components/qiun-data-charts/components/qiun-$1/qiun-$1.vue"
}
},
"pages": [
{
"path": "pages/index",
"style": {
"navigationBarTitleText": "若依移动端框架",
"navigationStyle": "custom"
}
},
{
"path": "pages/login",
"style": {
"navigationBarTitleText": "登录"
}
},
{
"path": "pages/work",
"style": {
"navigationBarTitleText": "工作台"
}
},
{
"path": "pages/template",
"style": {
"navigationBarTitleText": "模板"
}
},
{
"path": "pages/mine",
"style": {
"navigationBarTitleText": "我的"
}
},
{
"path": "pages/common/webview/index",
"style": {
"navigationBarTitleText": "浏览网页"
}
},
{
"path": "pages/common/textview/index",
"style": {
"navigationBarTitleText": "浏览文本"
}
}
],
"subPackages": [
{
"root": "pages_mine/pages",
"pages": [
{
"path": "avatar/index",
"style": {
"navigationBarTitleText": "修改头像"
}
},
{
"path": "info/index",
"style": {
"navigationBarTitleText": "个人信息"
}
},
{
"path": "info/edit",
"style": {
"navigationBarTitleText": "编辑资料"
}
},
{
"path": "pwd/index",
"style": {
"navigationBarTitleText": "修改密码"
}
},
{
"path": "setting/index",
"style": {
"navigationBarTitleText": "应用设置"
}
},
{
"path": "help/index",
"style": {
"navigationBarTitleText": "常见问题"
}
},
{
"path": "about/index",
"style": {
"navigationBarTitleText": "关于我们"
}
}
]
},
{
"root": "pages_template/pages",
"pages": [
{
"path": "wxCenter/index",
"style": {
"navigationBarTitleText": "wxCenter 仿微信个人中心",
"navigationStyle": "custom"
}
},
{
"path": "keyboardPay/index",
"style": {
"navigationBarTitleText": "keyboardPay 自定义键盘支付"
}
},
{
"path": "mallMenu/index2",
"style": {
"navigationBarTitleText": "mallMenu-商城分类"
}
},
{
"path": "mallMenu/index1",
"style": {
"navigationBarTitleText": "mallMenu-商城分类"
}
},
{
"path": "coupon/index",
"style": {
"navigationBarTitleText": "coupon-优惠券"
}
},
{
"path": "login/index1",
"style": {
"navigationBarTitleText": "美团登录"
}
},
{
"path": "login/index2",
"style": {
"navigationBarTitleText": "水滴登录"
}
},
{
"path": "citySelect/index",
"style": {
"navigationBarTitleText": "城市选择"
}
},
{
"path": "submitBar/index",
"style": {
"navigationBarTitleText": "提交订单栏"
}
},
{
"path": "comment/index",
"style": {
"navigationBarTitleText": "评论"
}
},
{
"path": "comment/reply",
"style": {
"navigationBarTitleText": "评论详情"
}
},
{
"path": "order/index",
"style": {
"navigationBarTitleText": "订单"
}
},
{
"path": "login/code",
"style": {
"navigationBarTitleText": "登录获取验证码"
}
},
{
"path": "address/index",
"style": {
"navigationBarTitleText": "用户地址"
}
},
{
"path": "address/addSite",
"style": {
"navigationBarTitleText": "添加用户地址"
}
}
]
},
{
"root": "pages_qiun/pages",
"pages": [
{
"path": "sport/index",
"style": {
"pageOrientation": "auto"
}
},
{
"path": "school/index",
"style": {
"pageOrientation": "auto"
}
},
{
"path": "finance/index",
"style": {
"pageOrientation": "auto"
}
},
{
"path": "main/index",
"style": {
"pageOrientation": "auto"
}
}
]
}
],
"tabBar": {
"color": "#000000",
"selectedColor": "#000000",
"borderStyle": "white",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index",
"iconPath": "static/images/tabbar/home.png",
"selectedIconPath": "static/images/tabbar/home_.png",
"text": "首页"
},
{
"pagePath": "pages/work",
"iconPath": "static/images/tabbar/work.png",
"selectedIconPath": "static/images/tabbar/work_.png",
"text": "工作台"
},
{
"pagePath": "pages/template",
"iconPath": "static/images/tabbar/work.png",
"selectedIconPath": "static/images/tabbar/work_.png",
"text": "模板"
},
{
"pagePath": "pages/mine",
"iconPath": "static/images/tabbar/mine.png",
"selectedIconPath": "static/images/tabbar/mine_.png",
"text": "我的"
}
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "RuoYi",
"navigationBarBackgroundColor": "#FFFFFF"
}
}

@ -0,0 +1,43 @@
<template>
<view>
<uni-card class="view-title" :title="title">
<text class="uni-body view-content">{{ content }}</text>
</uni-card>
</view>
</template>
<script>
export default {
data() {
return {
title: '',
content: ''
}
},
onLoad(options) {
this.title = options.title
this.content = options.content
uni.setNavigationBarTitle({
title: options.title
})
}
}
</script>
<style scoped>
page {
background-color: #ffffff;
}
.view-title {
font-weight: bold;
}
.view-content {
font-size: 26rpx;
padding: 12px 5px 0;
color: #333;
line-height: 24px;
font-weight: normal;
}
</style>

@ -0,0 +1,34 @@
<template>
<view v-if="params.url">
<web-view :webview-styles="webviewStyles" :src="`${params.url}`"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
params: {},
webviewStyles: {
progress: {
color: "#FF3333"
}
}
}
},
props: {
src: {
type: [String],
default: null
}
},
onLoad(event) {
this.params = event
if (event.title) {
uni.setNavigationBarTitle({
title: event.title
})
}
}
}
</script>

@ -0,0 +1,81 @@
<template>
<view class="content">
<image class="logo" src="@/static/logo.png"></image>
<view class="text-area">
<text class="title">Hello RuoYi-Vue</text>
</view>
<view class="text-area">
<up-text type="primary" text="uview-plus"></up-text>
</view>
<view class="charts-box">
<qiun-data-charts type="column" :chartData="chartData" />
</view>
</view>
</template>
<script>
export default {
data() {
return {
chartData: {},
};
},
onReady() {
this.getServerData();
},
methods: {
getServerData() {
//
setTimeout(() => {
let res = {
categories: ["2016", "2017", "2018", "2019", "2020", "2021"],
series: [
{
name: "目标值",
data: [35, 36, 31, 33, 13, 34]
},
{
name: "完成量",
data: [18, 27, 21, 24, 6, 28]
}
]
};
this.chartData = JSON.parse(JSON.stringify(res));
}, 500);
},
}
};
</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;
}
.charts-box {
width: 100%;
height: 300px;
}
</style>

@ -0,0 +1,191 @@
<template>
<view class="normal-login-container">
<view class="logo-content align-center justify-center flex">
<image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
</image>
<text class="title">若依移动端登录</text>
</view>
<view class="login-form-content">
<view class="input-item flex align-center">
<view class="iconfont icon-user icon"></view>
<input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" />
</view>
<view class="input-item flex align-center">
<view class="iconfont icon-password icon"></view>
<input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" />
</view>
<view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
<view class="iconfont icon-code icon"></view>
<input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" />
<view class="login-code">
<image :src="codeUrl" @click="getCode" class="login-code-img"></image>
</view>
</view>
<view class="action-btn">
<button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button>
</view>
</view>
<view class="xieyi text-center">
<text class="text-grey1">登录即代表同意</text>
<text @click="handleUserAgrement" class="text-blue">用户协议</text>
<text @click="handlePrivacy" class="text-blue">隐私协议</text>
</view>
</view>
</template>
<script setup>
import modal from '@/plugins/modal'
import { getCodeImg } from '@/api/login'
import { ref } from "vue";
import config from '@/config.js'
import store from '@/store'
const codeUrl = ref("");
const captchaEnabled = ref(true);
const globalConfig = ref(config);
const loginForm = ref({
username: "admin",
password: "admin123",
code: "",
uuid: ''
});
//
function getCode() {
getCodeImg().then(res => {
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled
if (captchaEnabled.value) {
codeUrl.value = 'data:image/gif;base64,' + res.img
loginForm.value.uuid = res.uuid
}
})
};
async function handleLogin() {
if (loginForm.value.username === "") {
modal.msgError("请输入您的账号")
} else if (loginForm.value.password === "") {
modal.msgError("请输入您的密码")
} else if (loginForm.value.code === "" && captchaEnabled.value) {
modal.msgError("请输入验证码")
} else {
modal.loading("登录中,请耐心等待...")
pwdLogin()
}
};
//
async function pwdLogin() {
store.dispatch('Login', loginForm.value).then(() => {
modal.closeLoading()
loginSuccess()
}).catch(() => {
if (captchaEnabled.value) {
modal.closeLoading()
getCode()
}
})
};
function loginSuccess(result) {
//
store.dispatch('GetInfo').then(res => {
uni.switchTab({
url: '/pages/index'
});
})
}
//
function handlePrivacy() {
let site = globalConfig.value.appInfo.agreements[0];
uni.navigateTo({
url: `/pages/common/webview/index?title=${site.title}&url=${site.url}`
});
};
//
function handleUserAgrement() {
let site = globalConfig.value.appInfo.agreements[1]
uni.navigateTo({
url: `/pages/common/webview/index?title=${site.title}&url=${site.url}`
});
};
getCode();
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
.normal-login-container {
width: 100%;
.logo-content {
width: 100%;
font-size: 21px;
text-align: center;
padding-top: 15%;
image {
border-radius: 4px;
}
.title {
margin-left: 10px;
}
}
.login-form-content {
text-align: center;
margin: 20px auto;
margin-top: 15%;
width: 80%;
.input-item {
margin: 20px auto;
background-color: #f5f6f7;
height: 45px;
border-radius: 20px;
.icon {
font-size: 38rpx;
margin-left: 10px;
color: #999;
}
.input {
width: 100%;
font-size: 14px;
line-height: 20px;
text-align: left;
padding-left: 15px;
}
}
.login-btn {
margin-top: 40px;
height: 45px;
}
.xieyi {
color: #333;
margin-top: 20px;
}
.login-code {
height: 38px;
float: right;
.login-code-img {
height: 38px;
position: absolute;
margin-left: 10px;
width: 200rpx;
}
}
}
}
</style>

@ -0,0 +1,236 @@
<template>
<view class="mine-container" :style="{height: `${windowHeight}px`}">
<!--顶部个人信息栏-->
<view class="header-section">
<view class="flex padding justify-between">
<view class="flex align-center">
<view v-if="!avatar" class="cu-avatar xl round bg-white">
<view class="iconfont icon-people text-gray icon"></view>
</view>
<image v-if="avatar" @click="handleToAvatar" :src="avatar" class="cu-avatar xl round" mode="widthFix">
</image>
<view v-if="!name" @click="handleToLogin" class="login-tip">
点击登录
</view>
<view v-if="name" @click="handleToInfo" class="user-info">
<view class="u_title">
用户名{{ name }}
</view>
</view>
</view>
<view @click="handleToInfo" class="flex align-center">
<text>个人信息</text>
<view class="iconfont icon-right"></view>
</view>
</view>
</view>
<view class="content-section">
<view class="mine-actions grid col-4 text-center">
<view class="action-item" @click="handleJiaoLiuQun">
<view class="iconfont icon-friendfill text-pink icon"></view>
<text class="text">交流群</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-service text-blue icon"></view>
<text class="text">在线客服</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-community text-mauve icon"></view>
<text class="text">反馈社区</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-dianzan text-green icon"></view>
<text class="text">点赞我们</text>
</view>
</view>
<view class="menu-list">
<view class="list-cell list-cell-arrow" @click="handleToEditInfo">
<view class="menu-item-box">
<view class="iconfont icon-user menu-icon"></view>
<view>编辑资料</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleHelp">
<view class="menu-item-box">
<view class="iconfont icon-help menu-icon"></view>
<view>常见问题</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleAbout">
<view class="menu-item-box">
<view class="iconfont icon-aixin menu-icon"></view>
<view>关于我们</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleToSetting">
<view class="menu-item-box">
<view class="iconfont icon-setting menu-icon"></view>
<view>应用设置</view>
</view>
</view>
</view>
</view>
</view>
<!-- <view>
<uni-popup ref="popup" type="dialog">
<uni-popup-dialog type="info" cancelText="关闭" confirmText="退出"
title="通知" content="确定注销并退出系统吗"
@confirm="dialogConfirm"
@close="dialogClose">
</uni-popup-dialog>
</uni-popup>
</view> -->
</template>
<script setup>
import storage from '@/utils/storage'
import store from '@/store'
import { ref } from "vue";
import config from '@/config.js'
const name=store.state.user.name;
const version= config.appInfo.version;
const avatar=ref(store.state.user.avatar);
const windowHeight=ref(uni.getSystemInfoSync().windowHeight - 50);
const popup = ref(null);
uni.$on('refresh', () => {
avatar.value=store.state.user.avatar;
})
console.log(avatar.value)
function handleToInfo() {
uni.navigateTo({
url: '/pages_mine/info/index'
});
};
function handleToEditInfo() {
uni.navigateTo({
url: '/pages_mine/info/edit'
});
};
function handleToSetting() {
uni.navigateTo({
url: '/pages_mine/setting/index'
});
};
function handleToLogin() {
uni.reLaunch({
url: '/pages/login'
});
};
function handleToAvatar() {
uni.navigateTo({
url: '/pages_mine/avatar/index'
});
};
function handleLogout() {
popup.value.open();
};
function dialogConfirm() {
//console.log('----------------------------')
store.dispatch('LogOut').then(() => {
uni.reLaunch({
url: '/pages/login'
});
})
};
function dialogClose() {
//console.log('')
};
function handleHelp() {
uni.navigateTo({
url: '/pages_mine/help/index'
});
};
function handleAbout() {
uni.navigateTo({
url: '/pages_mine/about/index'
});
};
function handleJiaoLiuQun() {
uni.showToast({
title: 'QQ群133713780',
mask: false,
icon:"none",
duration: 1000
});
};
function handleBuilding() {
uni.showToast({
title: '模块建设中~',
mask: false,
icon:"none",
duration: 1000
});
}
</script>
<style lang="scss">
page {
background-color: #f5f6f7;
}
.mine-container {
width: 100%;
height: 100%;
.header-section {
padding: 15px 15px 45px 15px;
background-color: #3c96f3;
color: white;
.login-tip {
font-size: 18px;
margin-left: 10px;
}
.cu-avatar {
border: 2px solid #eaeaea;
.icon {
font-size: 40px;
}
}
.user-info {
margin-left: 15px;
.u_title {
font-size: 18px;
line-height: 30px;
}
}
}
.content-section {
position: relative;
top: -50px;
.mine-actions {
margin: 15px 15px;
padding: 20px 0px;
border-radius: 8px;
background-color: white;
.action-item {
.icon {
font-size: 28px;
}
.text {
display: block;
font-size: 13px;
margin: 8px 0px;
}
}
}
}
}
</style>

@ -0,0 +1,113 @@
export default [
{
groupName: '部件',
groupName_en: 'Parts',
list: [
{
path: '/pages_template/pages/coupon/index',
icon: 'coupon',
title: 'Coupon 优惠券',
title_en: 'Coupon',
},
{
path: '/pages_template/pages/citySelect/index',
icon: 'citySelect',
title: 'CitySelect 城市选择',
title_en: 'CitySelect',
},
{
path: '/pages_template/pages/submitBar/index',
icon: 'submitBar',
title: 'SubmitBar 提交订单栏',
title_en: 'SubmitBar',
}
]
},
{
groupName: '报表',
groupName_en: 'Parts',
list: [
{
path: '/pages_qiun/pages/finance/index',
icon: 'coupon',
title: '财务报告',
title_en: 'finace',
},
{
path: '/pages_qiun/pages/main/index',
icon: 'coupon',
title: '数据报表中心',
title_en: 'main',
},
{
path: '/pages_qiun/pages/school/index',
icon: 'coupon',
title: '智慧教育报表中心',
title_en: 'school',
},
{
path: '/pages_qiun/pages/sport/index',
icon: 'coupon',
title: '运动报告',
title_en: 'sport',
},
]
},
{
groupName: '页面',
groupName_en: 'Page',
list: [
{
path: '/pages_template/pages/wxCenter/index',
icon: 'wxCenter',
title: 'WxCenter 仿微信个人中心',
title_en: 'WxCenter',
},
{
path: '/pages_template/pages/keyboardPay/index',
icon: 'keyboardPay',
title: 'KeyboardPay 自定义键盘支付模板',
title_en: 'KeyboardPay',
},
{
path: '/pages_template/pages/mallMenu/index1',
icon: 'mall_menu_1',
title: 'MallMenu 垂直分类(左右独立)',
title_en: 'MallMenu 1',
}, {
path: '/pages_template/pages/mallMenu/index2',
icon: 'mall_menu_2',
title: 'MallMenu 垂直分类(左右联动)',
title_en: 'MallMenu 2',
}, {
path: '/pages_template/pages/comment/index',
icon: 'comment',
title: 'Comment 评论列表',
title_en: 'Comment',
}, {
path: '/pages_template/pages/order/index',
icon: 'order',
title: 'Order 订单列表',
title_en: 'Order',
},
{
path: '/pages_template/pages/login/index1',
icon: 'login',
title: 'Login 登录界面',
title_en: 'Login',
},
{
path: '/pages_template/pages/login/index2',
icon: 'login',
title: 'Login 水滴登录',
title_en: 'Login',
},
{
path: '/pages_template/pages/address/index',
icon: 'address',
title: 'Address 收货地址',
title_en: 'Address',
},
]
}
]

@ -0,0 +1,65 @@
<template>
<view class="wrap">
<view class="list-wrap">
<u-cell-group title-bg-color="rgb(243, 244, 246)" :title="getGroupTitle(item)" v-for="(item, index) in list"
:key="index">
<u-cell :titleStyle="{ fontWeight: 500 }" @click="openPage(item1.path)" :title="getFieldTitle(item1)"
v-for="(item1, index1) in item.list" :key="index1">
<template v-slot:icon>
<image class="u-cell-icon" :src="getIcon(item1.icon)" mode="widthFix"></image>
</template>
</u-cell>
</u-cell-group>
</view>
<u-gap height="70"></u-gap>
<!-- <u-tabbar :list="vuex_tabbar" :mid-button="true"></u-tabbar> -->
</view>
</template>
<script>
import list from "./template.config.js";
export default {
data() {
return {
list: list,
// desc: ''
}
},
computed: {
getIcon() {
return path => {
return '../static/uview/demo/' + path + '.png';
return 'https://cdn.uviewui.com/uview/example/' + path + '.png';
}
},
},
methods: {
openPage(path) {
this.$u.route({
url: path
})
},
getGroupTitle(item) {
return item.groupName
},
getFieldTitle(item) {
return item.title
}
}
}
</script>
<style>
/* page {
background-color: rgb(240, 242, 244);
} */
</style>
<style lang="scss" scoped>
.u-cell-icon {
width: 36rpx;
height: 36rpx;
margin-right: 8rpx;
}
</style>

@ -0,0 +1,184 @@
<template>
<view class="work-container">
<!-- 轮播图 -->
<uni-swiper-dot class="uni-swiper-dot-box" :info="data" :current="current" field="content">
<swiper class="swiper-box" :current="swiperDotIndex" @change="changeSwiper">
<swiper-item v-for="(item, index) in data" :key="index">
<view class="swiper-item" @click="clickBannerItem(item)">
<image :src="item.image" mode="aspectFill" :draggable="false" />
</view>
</swiper-item>
</swiper>
</uni-swiper-dot>
<!-- 宫格组件 -->
<uni-section title="系统管理" type="line"></uni-section>
<view class="grid-body">
<uni-grid :column="4" :showBorder="false" @change="changeGrid">
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="person-filled" size="30"></uni-icons>
<text class="text">用户管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="staff-filled" size="30"></uni-icons>
<text class="text">角色管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="color" size="30"></uni-icons>
<text class="text">菜单管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="settings-filled" size="30"></uni-icons>
<text class="text">部门管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="heart-filled" size="30"></uni-icons>
<text class="text">岗位管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="bars" size="30"></uni-icons>
<text class="text">字典管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="gear-filled" size="30"></uni-icons>
<text class="text">参数设置</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="chat-filled" size="30"></uni-icons>
<text class="text">通知公告</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="wallet-filled" size="30"></uni-icons>
<text class="text">日志管理</text>
</view>
</uni-grid-item>
</uni-grid>
</view>
</view>
</template>
<script setup>
import { ref } from "vue";
import modal from "@/plugins/modal"
const current=ref(0);
const swiperDotIndex=ref(0);
const data=ref([{
image: '/static/images/banner/banner01.jpg'
},
{
image: '/static/images/banner/banner02.jpg'
},
{
image: '/static/images/banner/banner03.jpg'
}
]);
function clickBannerItem(item) {
console.info(item)
};
function changeSwiper(e) {
current.value = e.detail.current
}
function changeGrid(e) {
modal.showToast({
title: '模块建设中',
mask: false,
icon:'loading',
duration: 1000
});
}
</script>
<style lang="scss">
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #fff;
min-height: 100%;
height: auto;
}
view {
font-size: 14px;
line-height: inherit;
}
/* #endif */
.text {
text-align: center;
font-size: 26rpx;
margin-top: 10rpx;
}
.grid-item-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 0;
}
.uni-margin-wrap {
width: 690rpx;
width: 100%;
;
}
.swiper {
height: 300rpx;
}
.swiper-box {
height: 150px;
}
.swiper-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
height: 300rpx;
line-height: 300rpx;
}
@media screen and (min-width: 500px) {
.uni-swiper-dot-box {
width: 400px;
/* #ifndef APP-NVUE */
margin: 0 auto;
/* #endif */
margin-top: 8px;
}
.image {
width: 100%;
}
}
</style>

@ -0,0 +1,71 @@
<template>
<view class="about-container">
<view class="header-section text-center">
<image style="width: 150rpx;height: 150rpx;" src="/static/logo200.png" mode="widthFix">
</image>
<uni-title type="h2" title="若依移动端"></uni-title>
</view>
<view class="content-section">
<view class="menu-list">
<view class="list-cell list-cell-arrow">
<view class="menu-item-box">
<view>版本信息</view>
<view class="text-right">v{{version}}</view>
</view>
</view>
<view class="list-cell list-cell-arrow">
<view class="menu-item-box">
<view>官方邮箱</view>
<view class="text-right">ruoyi@xx.com</view>
</view>
</view>
<view class="list-cell list-cell-arrow">
<view class="menu-item-box">
<view>服务热线</view>
<view class="text-right">400-999-9999</view>
</view>
</view>
<view class="list-cell list-cell-arrow">
<view class="menu-item-box">
<view>公司网站</view>
<view class="text-right">
<uni-link :href="url" :text="url" showUnderLine="false"></uni-link>
</view>
</view>
</view>
</view>
</view>
<view class="copyright">
<view>Copyright &copy; 2022 ruoyi.vip All Rights Reserved.</view>
</view>
</view>
</template>
<script setup>
import config from '@/config.js'
const url=config.appInfo.site_url;
const version=config.appInfo.version;
</script>
<style lang="scss">
page {
background-color: #f8f8f8;
}
.copyright {
margin-top: 50rpx;
text-align: center;
line-height: 60rpx;
color: #999;
}
.header-section {
display: flex;
padding: 30rpx 0 0;
flex-direction: column;
align-items: center;
}
</style>

@ -0,0 +1,634 @@
<template>
<view class="container">
<view class="page-body uni-content-info">
<view class='cropper-content'>
<view v-if="isShowImg" class="uni-corpper" :style="'width:'+cropperInitW+'px;height:'+cropperInitH+'px;background:#000'">
<view class="uni-corpper-content" :style="'width:'+cropperW+'px;height:'+cropperH+'px;left:'+cropperL+'px;top:'+cropperT+'px'">
<image :src="imageSrc" :style="'width:'+cropperW+'px;height:'+cropperH+'px'"></image>
<view class="uni-corpper-crop-box" @touchstart.stop="contentStartMove" @touchmove.stop="contentMoveing" @touchend.stop="contentTouchEnd"
:style="'left:'+cutL+'px;top:'+cutT+'px;right:'+cutR+'px;bottom:'+cutB+'px'">
<view class="uni-cropper-view-box">
<view class="uni-cropper-dashed-h"></view>
<view class="uni-cropper-dashed-v"></view>
<view class="uni-cropper-line-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
<view class="uni-cropper-line-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
<view class="uni-cropper-line-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
<view class="uni-cropper-line-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
<view class="uni-cropper-point point-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
<view class="uni-cropper-point point-tr" data-drag="topTight"></view>
<view class="uni-cropper-point point-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
<view class="uni-cropper-point point-rb" data-drag="rightBottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
<view class="uni-cropper-point point-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove" @touchend.stop="dragEnd"></view>
<view class="uni-cropper-point point-bl" data-drag="bottomLeft"></view>
<view class="uni-cropper-point point-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
<view class="uni-cropper-point point-lt" data-drag="leftTop"></view>
</view>
</view>
</view>
</view>
</view>
<view class='cropper-config'>
<button type="primary reverse" @click="getImage" style='margin-top: 30rpx;'> 选择头像 </button>
<button type="warn" @click="getImageInfo" style='margin-top: 30rpx;'> 提交 </button>
</view>
<canvas canvas-id="myCanvas" :style="'position:absolute;border: 1px solid red; width:'+imageW+'px;height:'+imageH+'px;top:-9999px;left:-9999px;'"></canvas>
</view>
</view>
</template>
<script>
import config from '@/config'
import store from "@/store"
import { uploadAvatar } from "@/api/system/user"
const baseUrl = config.baseUrl
let sysInfo = uni.getSystemInfoSync()
let SCREEN_WIDTH = sysInfo.screenWidth
let PAGE_X, // x
PAGE_Y, // y
PR = sysInfo.pixelRatio, // dpi
T_PAGE_X, // x
T_PAGE_Y, // Y
CUT_L, // left
CUT_T, // top
CUT_R, //
CUT_B, //
CUT_W, //
CUT_H, //
IMG_RATIO, //
IMG_REAL_W, //
IMG_REAL_H, //
DRAFG_MOVE_RATIO = 1, //,
INIT_DRAG_POSITION = 100, //
DRAW_IMAGE_W = sysInfo.screenWidth //
export default {
/**
* 页面的初始数据
*/
data() {
return {
imageSrc: store.getters.avatar,
isShowImg: false,
//
cropperInitW: SCREEN_WIDTH,
cropperInitH: SCREEN_WIDTH,
//
cropperW: SCREEN_WIDTH,
cropperH: SCREEN_WIDTH,
// left top
cropperL: 0,
cropperT: 0,
transL: 0,
transT: 0,
//
scaleP: 0,
imageW: 0,
imageH: 0,
//
cutL: 0,
cutT: 0,
cutB: SCREEN_WIDTH,
cutR: '100%',
qualityWidth: DRAW_IMAGE_W,
innerAspectRadio: DRAFG_MOVE_RATIO
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
this.loadImage()
},
methods: {
setData: function (obj) {
let that = this
Object.keys(obj).forEach(function (key) {
that.$set(that.$data, key, obj[key])
})
},
getImage: function () {
var _this = this
uni.chooseImage({
success: function (res) {
_this.setData({
imageSrc: res.tempFilePaths[0],
})
_this.loadImage()
},
})
},
loadImage: function () {
var _this = this
uni.getImageInfo({
src: _this.imageSrc,
success: function success(res) {
IMG_RATIO = 1 / 1
if (IMG_RATIO >= 1) {
IMG_REAL_W = SCREEN_WIDTH
IMG_REAL_H = SCREEN_WIDTH / IMG_RATIO
} else {
IMG_REAL_W = SCREEN_WIDTH * IMG_RATIO
IMG_REAL_H = SCREEN_WIDTH
}
let minRange = IMG_REAL_W > IMG_REAL_H ? IMG_REAL_W : IMG_REAL_H
INIT_DRAG_POSITION = minRange > INIT_DRAG_POSITION ? INIT_DRAG_POSITION : minRange
//
if (IMG_RATIO >= 1) {
let cutT = Math.ceil((SCREEN_WIDTH / IMG_RATIO - (SCREEN_WIDTH / IMG_RATIO - INIT_DRAG_POSITION)) / 2)
let cutB = cutT
let cutL = Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH + INIT_DRAG_POSITION) / 2)
let cutR = cutL
_this.setData({
cropperW: SCREEN_WIDTH,
cropperH: SCREEN_WIDTH / IMG_RATIO,
// left right
cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2),
cutL: cutL,
cutT: cutT,
cutR: cutR,
cutB: cutB,
//
imageW: IMG_REAL_W,
imageH: IMG_REAL_H,
scaleP: IMG_REAL_W / SCREEN_WIDTH,
qualityWidth: DRAW_IMAGE_W,
innerAspectRadio: IMG_RATIO
})
} else {
let cutL = Math.ceil((SCREEN_WIDTH * IMG_RATIO - (SCREEN_WIDTH * IMG_RATIO)) / 2)
let cutR = cutL
let cutT = Math.ceil((SCREEN_WIDTH - INIT_DRAG_POSITION) / 2)
let cutB = cutT
_this.setData({
cropperW: SCREEN_WIDTH * IMG_RATIO,
cropperH: SCREEN_WIDTH,
// left right
cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2),
cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
cutL: cutL,
cutT: cutT,
cutR: cutR,
cutB: cutB,
//
imageW: IMG_REAL_W,
imageH: IMG_REAL_H,
scaleP: IMG_REAL_W / SCREEN_WIDTH,
qualityWidth: DRAW_IMAGE_W,
innerAspectRadio: IMG_RATIO
})
}
_this.setData({
isShowImg: true
})
uni.hideLoading()
}
})
},
// touchStart
contentStartMove(e) {
PAGE_X = e.touches[0].pageX
PAGE_Y = e.touches[0].pageY
},
// touchMove
contentMoveing(e) {
var _this = this
var dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
var dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
//
if (dragLengthX > 0) {
if (this.cutL - dragLengthX < 0) dragLengthX = this.cutL
} else {
if (this.cutR + dragLengthX < 0) dragLengthX = -this.cutR
}
if (dragLengthY > 0) {
if (this.cutT - dragLengthY < 0) dragLengthY = this.cutT
} else {
if (this.cutB + dragLengthY < 0) dragLengthY = -this.cutB
}
this.setData({
cutL: this.cutL - dragLengthX,
cutT: this.cutT - dragLengthY,
cutR: this.cutR + dragLengthX,
cutB: this.cutB + dragLengthY
})
PAGE_X = e.touches[0].pageX
PAGE_Y = e.touches[0].pageY
},
contentTouchEnd() {
},
//
getImageInfo() {
var _this = this
uni.showLoading({
title: '图片生成中...',
})
//
const ctx = uni.createCanvasContext('myCanvas')
ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H)
ctx.draw(true, () => {
// * canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W
var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H
var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W
var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H
uni.canvasToTempFilePath({
x: canvasL,
y: canvasT,
width: canvasW,
height: canvasH,
destWidth: canvasW,
destHeight: canvasH,
quality: 0.5,
canvasId: 'myCanvas',
success: function (res) {
uni.hideLoading()
let data = {name: 'avatarfile', filePath: res.tempFilePath}
uploadAvatar(data).then(response => {
//store.commit('SET_AVATAR', response.imgUrl)
/*cloud*/
store.commit('SET_AVATAR',baseUrl + response.imgUrl)
uni.showToast({ title: "修改成功", icon: 'success' })
uni.$emit('refresh');
uni.navigateBack();
})
}
})
})
},
// touchStart
dragStart(e) {
T_PAGE_X = e.touches[0].pageX
T_PAGE_Y = e.touches[0].pageY
CUT_L = this.cutL
CUT_R = this.cutR
CUT_B = this.cutB
CUT_T = this.cutT
},
// touchMove
dragMove(e) {
var _this = this
var dragType = e.target.dataset.drag
switch (dragType) {
case 'right':
var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
if (CUT_R + dragLength < 0) dragLength = -CUT_R
this.setData({
cutR: CUT_R + dragLength
})
break
case 'left':
var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
if (CUT_L - dragLength < 0) dragLength = CUT_L
if ((CUT_L - dragLength) > (this.cropperW - this.cutR)) dragLength = CUT_L - (this.cropperW - this.cutR)
this.setData({
cutL: CUT_L - dragLength
})
break
case 'top':
var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
if (CUT_T - dragLength < 0) dragLength = CUT_T
if ((CUT_T - dragLength) > (this.cropperH - this.cutB)) dragLength = CUT_T - (this.cropperH - this.cutB)
this.setData({
cutT: CUT_T - dragLength
})
break
case 'bottom':
var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
if (CUT_B + dragLength < 0) dragLength = -CUT_B
this.setData({
cutB: CUT_B + dragLength
})
break
case 'rightBottom':
var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B
if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R
let cutB = CUT_B + dragLengthY
let cutR = CUT_R + dragLengthX
this.setData({
cutB: cutB,
cutR: cutR
})
break
default:
break
}
}
}
}
</script>
<style>
/* pages/uni-cropper/index.wxss */
.uni-content-info {
/* position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: block;
align-items: center;
flex-direction: column; */
}
.cropper-config {
padding: 20rpx 40rpx;
}
.cropper-content {
min-height: 750rpx;
width: 100%;
}
.uni-corpper {
position: relative;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
box-sizing: border-box;
}
.uni-corpper-content {
position: relative;
}
.uni-corpper-content image {
display: block;
width: 100%;
min-width: 0 !important;
max-width: none !important;
height: 100%;
min-height: 0 !important;
max-height: none !important;
image-orientation: 0deg !important;
margin: 0 auto;
}
/* 移动图片效果 */
.uni-cropper-drag-box {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
cursor: move;
background: rgba(0, 0, 0, 0.6);
z-index: 1;
}
/* 内部的信息 */
.uni-corpper-crop-box {
position: absolute;
background: rgba(255, 255, 255, 0.3);
z-index: 2;
}
.uni-corpper-crop-box .uni-cropper-view-box {
position: relative;
display: block;
width: 100%;
height: 100%;
overflow: visible;
outline: 1rpx solid #69f;
outline-color: rgba(102, 153, 255, .75)
}
/* 横向虚线 */
.uni-cropper-dashed-h {
position: absolute;
top: 33.33333333%;
left: 0;
width: 100%;
height: 33.33333333%;
border-top: 1rpx dashed rgba(255, 255, 255, 0.5);
border-bottom: 1rpx dashed rgba(255, 255, 255, 0.5);
}
/* 纵向虚线 */
.uni-cropper-dashed-v {
position: absolute;
left: 33.33333333%;
top: 0;
width: 33.33333333%;
height: 100%;
border-left: 1rpx dashed rgba(255, 255, 255, 0.5);
border-right: 1rpx dashed rgba(255, 255, 255, 0.5);
}
/* 四个方向的线 为了之后的拖动事件*/
.uni-cropper-line-t {
position: absolute;
display: block;
width: 100%;
background-color: #69f;
top: 0;
left: 0;
height: 1rpx;
opacity: 0.1;
cursor: n-resize;
}
.uni-cropper-line-t::before {
content: '';
position: absolute;
top: 50%;
right: 0rpx;
width: 100%;
-webkit-transform: translate3d(0, -50%, 0);
transform: translate3d(0, -50%, 0);
bottom: 0;
height: 41rpx;
background: transparent;
z-index: 11;
}
.uni-cropper-line-r {
position: absolute;
display: block;
background-color: #69f;
top: 0;
right: 0rpx;
width: 1rpx;
opacity: 0.1;
height: 100%;
cursor: e-resize;
}
.uni-cropper-line-r::before {
content: '';
position: absolute;
top: 0;
left: 50%;
width: 41rpx;
-webkit-transform: translate3d(-50%, 0, 0);
transform: translate3d(-50%, 0, 0);
bottom: 0;
height: 100%;
background: transparent;
z-index: 11;
}
.uni-cropper-line-b {
position: absolute;
display: block;
width: 100%;
background-color: #69f;
bottom: 0;
left: 0;
height: 1rpx;
opacity: 0.1;
cursor: s-resize;
}
.uni-cropper-line-b::before {
content: '';
position: absolute;
top: 50%;
right: 0rpx;
width: 100%;
-webkit-transform: translate3d(0, -50%, 0);
transform: translate3d(0, -50%, 0);
bottom: 0;
height: 41rpx;
background: transparent;
z-index: 11;
}
.uni-cropper-line-l {
position: absolute;
display: block;
background-color: #69f;
top: 0;
left: 0;
width: 1rpx;
opacity: 0.1;
height: 100%;
cursor: w-resize;
}
.uni-cropper-line-l::before {
content: '';
position: absolute;
top: 0;
left: 50%;
width: 41rpx;
-webkit-transform: translate3d(-50%, 0, 0);
transform: translate3d(-50%, 0, 0);
bottom: 0;
height: 100%;
background: transparent;
z-index: 11;
}
.uni-cropper-point {
width: 5rpx;
height: 5rpx;
background-color: #69f;
opacity: .75;
position: absolute;
z-index: 3;
}
.point-t {
top: -3rpx;
left: 50%;
margin-left: -3rpx;
cursor: n-resize;
}
.point-tr {
top: -3rpx;
left: 100%;
margin-left: -3rpx;
cursor: n-resize;
}
.point-r {
top: 50%;
left: 100%;
margin-left: -3rpx;
margin-top: -3rpx;
cursor: n-resize;
}
.point-rb {
left: 100%;
top: 100%;
-webkit-transform: translate3d(-50%, -50%, 0);
transform: translate3d(-50%, -50%, 0);
cursor: n-resize;
width: 36rpx;
height: 36rpx;
background-color: #69f;
position: absolute;
z-index: 1112;
opacity: 1;
}
.point-b {
left: 50%;
top: 100%;
margin-left: -3rpx;
margin-top: -3rpx;
cursor: n-resize;
}
.point-bl {
left: 0%;
top: 100%;
margin-left: -3rpx;
margin-top: -3rpx;
cursor: n-resize;
}
.point-l {
left: 0%;
top: 50%;
margin-left: -3rpx;
margin-top: -3rpx;
cursor: n-resize;
}
.point-lt {
left: 0%;
top: 0%;
margin-left: -3rpx;
margin-top: -3rpx;
cursor: n-resize;
}
/* 裁剪框预览内容 */
.uni-cropper-viewer {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.uni-cropper-viewer image {
position: absolute;
z-index: 2;
}
</style>

@ -0,0 +1,109 @@
<template>
<view class="help-container">
<view v-for="(item, findex) in list" :key="findex" :title="item.title" class="list-title">
<view class="text-title">
<view :class="item.icon"></view>{{ item.title }}
</view>
<view class="childList">
<view v-for="(child, zindex) in item.childList" :key="zindex" class="question" hover-class="hover"
@click="handleText(child)">
<view class="text-item">{{ child.title }}</view>
<view class="line" v-if="zindex !== item.childList.length - 1"></view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from "vue";
const list =ref([{
icon: 'iconfont icon-github',
title: '若依问题',
childList: [{
title: '若依开源吗?',
content: '开源'
}, {
title: '若依可以商用吗?',
content: '可以'
}, {
title: '若依官网地址多少?',
content: 'http://ruoyi.vip'
}, {
title: '若依文档地址多少?',
content: 'http://doc.ruoyi.vip'
}]
},
{
icon: 'iconfont icon-help',
title: '其他问题',
childList: [{
title: '如何退出登录?',
content: '请点击[我的] - [应用设置] - [退出登录]即可退出登录',
}, {
title: '如何修改用户头像?',
content: '请点击[我的] - [选择头像] - [点击提交]即可更换用户头像',
}, {
title: '如何修改登录密码?',
content: '请点击[我的] - [应用设置] - [修改密码]即可修改登录密码',
}]
}
])
function handleText(item) {
uni.navigateTo({
url: `/pages/common/textview/index?title=${item.title}&content=${item.content}`
});
}
</script>
<style lang="scss" scoped>
page {
background-color: #f8f8f8;
}
.help-container {
margin-bottom: 100rpx;
padding: 30rpx;
}
.list-title {
margin-bottom: 30rpx;
}
.childList {
background: #ffffff;
box-shadow: 0px 0px 10rpx rgba(193, 193, 193, 0.2);
border-radius: 16rpx;
margin-top: 10rpx;
}
.line {
width: 100%;
height: 1rpx;
background-color: #F5F5F5;
}
.text-title {
color: #303133;
font-size: 32rpx;
font-weight: bold;
margin-left: 10rpx;
.iconfont {
font-size: 16px;
margin-right: 10rpx;
}
}
.text-item {
font-size: 28rpx;
padding: 24rpx;
}
.question {
color: #606266;
font-size: 28rpx;
}
</style>

@ -0,0 +1,132 @@
<template>
<view class="container">
<view class="example">
<uni-forms ref="form" :model="user" labelWidth="80px">
<uni-forms-item label="用户昵称" name="nickName">
<uni-easyinput v-model="user.nickName" placeholder="请输入昵称" />
</uni-forms-item>
<uni-forms-item label="手机号码" name="phonenumber">
<uni-easyinput v-model="user.phonenumber" placeholder="请输入手机号码" />
</uni-forms-item>
<uni-forms-item label="邮箱" name="email">
<uni-easyinput v-model="user.email" placeholder="请输入邮箱" />
</uni-forms-item>
<uni-forms-item label="性别" name="sex" required>
<uni-data-checkbox v-model="user.sex" :localdata="sexs" />
</uni-forms-item>
</uni-forms>
<button type="primary" @click="submit"></button>
</view>
</view>
</template>
<script>
import { getUserProfile } from "@/api/system/user"
import { updateUserProfile } from "@/api/system/user"
export default {
data() {
return {
user: {
nickName: "",
phonenumber: "",
email: "",
sex: ""
},
sexs: [{
text: '男',
value: "0"
}, {
text: '女',
value: "1"
}],
rules: {
nickName: {
rules: [{
required: true,
errorMessage: '用户昵称不能为空'
}]
},
phonenumber: {
rules: [{
required: true,
errorMessage: '手机号码不能为空'
}, {
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
errorMessage: '请输入正确的手机号码'
}]
},
email: {
rules: [{
required: true,
errorMessage: '邮箱地址不能为空'
}, {
format: 'email',
errorMessage: '请输入正确的邮箱地址'
}]
}
}
}
},
onLoad() {
this.getUser()
},
onReady() {
this.$refs.form.setRules(this.rules)
},
methods: {
getUser() {
getUserProfile().then(response => {
this.user = response.data
})
},
submit(ref) {
this.$refs.form.validate().then(res => {
updateUserProfile(this.user).then(response => {
uni.showToast({
title: '修改成功',
mask: false,
duration: 1000
});
uni.navigateBack();
})
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
.example {
padding: 15px;
background-color: #fff;
}
.segmented-control {
margin-bottom: 15px;
}
.button-group {
margin-top: 15px;
display: flex;
justify-content: space-around;
}
.form-item {
display: flex;
align-items: center;
flex: 1;
}
.button {
display: flex;
align-items: center;
height: 35px;
line-height: 35px;
margin-left: 10px;
}
</style>

@ -0,0 +1,44 @@
<template>
<view class="container">
<uni-list>
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'person-filled'}" title="昵称" :rightText="user.nickName" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'phone-filled'}" title="手机号码" :rightText="user.phonenumber" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'email-filled'}" title="邮箱" :rightText="user.email" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'auth-filled'}" title="岗位" :rightText="postGroup" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'staff-filled'}" title="角色" :rightText="roleGroup" />
<uni-list-item showExtraIcon="true" :extraIcon="{type: 'calendar-filled'}" title="创建日期" :rightText="user.createTime" />
</uni-list>
</view>
</template>
<script>
import { getUserProfile } from "@/api/system/user"
export default {
data() {
return {
user: {},
roleGroup: "",
postGroup: ""
}
},
onLoad() {
this.getUser()
},
methods: {
getUser() {
getUserProfile().then(response => {
this.user = response.data
this.roleGroup = response.roleGroup
this.postGroup = response.postGroup
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
</style>

@ -0,0 +1,91 @@
<template>
<view class="pwd-retrieve-container">
<uni-forms ref="form" :value="user" labelWidth="80px">
<uni-forms-item name="oldPassword" label="旧密码">
<uni-easyinput type="password" v-model="user.oldPassword" placeholder="请输入旧密码" />
</uni-forms-item>
<uni-forms-item name="newPassword" label="新密码">
<uni-easyinput type="password" v-model="user.newPassword" placeholder="请输入新密码" />
</uni-forms-item>
<uni-forms-item name="confirmPassword" label="确认密码">
<uni-easyinput type="password" v-model="user.confirmPassword" placeholder="请确认新密码" />
</uni-forms-item>
<button type="primary" @click="submit"></button>
</uni-forms>
</view>
</template>
<script>
import { updateUserPwd } from "@/api/system/user"
export default {
data() {
return {
user: {
oldPassword: undefined,
newPassword: undefined,
confirmPassword: undefined
},
rules: {
oldPassword: {
rules: [{
required: true,
errorMessage: '旧密码不能为空'
}]
},
newPassword: {
rules: [{
required: true,
errorMessage: '新密码不能为空',
},
{
minLength: 6,
maxLength: 20,
errorMessage: '长度在 6 到 20 个字符'
}
]
},
confirmPassword: {
rules: [{
required: true,
errorMessage: '确认密码不能为空'
}, {
validateFunction: (rule, value, data) => data.newPassword === value,
errorMessage: '两次输入的密码不一致'
}
]
}
}
}
},
onReady() {
this.$refs.form.setRules(this.rules)
},
methods: {
submit() {
this.$refs.form.validate().then(res => {
updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
uni.showToast({
title: '修改成功',
mask: false,
duration: 1000
});
uni.navigateBack();
})
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
.pwd-retrieve-container {
padding-top: 36rpx;
padding: 15px;
}
</style>

@ -0,0 +1,105 @@
<template>
<view class="setting-container" :style="{height: `${windowHeight}px`}">
<view class="menu-list">
<view class="list-cell list-cell-arrow" @click="handleToPwd">
<view class="menu-item-box">
<view class="iconfont icon-password menu-icon"></view>
<view>修改密码</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleToUpgrade">
<view class="menu-item-box">
<view class="iconfont icon-refresh menu-icon"></view>
<view>检查更新</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleCleanTmp">
<view class="menu-item-box">
<view class="iconfont icon-clean menu-icon"></view>
<view>清理缓存</view>
</view>
</view>
</view>
<view class="cu-list menu">
<view class="cu-item item-box">
<view class="content text-center" @click="handleLogout">
<text class="text-black">退出登录</text>
</view>
</view>
</view>
</view>
<view>
<uni-popup ref="popup" type="dialog">
<uni-popup-dialog type="info" cancelText="关闭" confirmText="退出"
title="通知" content="确定注销并退出系统吗"
@confirm="dialogConfirm"
@close="dialogClose">
</uni-popup-dialog>
</uni-popup>
</view>
</template>
<script setup>
import { ref } from "vue";
import store from '@/store'
const windowHeight=ref(uni.getSystemInfoSync().windowHeight) ;
const popup = ref(null);
function handleToPwd() {
uni.navigateTo({
url: '/pages/mine/pwd/index'
});
};
function handleToUpgrade() {
uni.showToast({
title: '模块建设中~',
mask: false,
icon:"none",
duration: 1000
});
};
function handleCleanTmp() {
uni.showToast({
title: '模块建设中~',
mask: false,
icon:"none",
duration: 1000
});
};
function handleLogout() {
popup.value.open();
};
function dialogConfirm() {
//console.log('----------------------------')
store.dispatch('LogOut').then(() => {
uni.reLaunch({
url: '/pages/login'
});
})
};
function dialogClose() {
//console.log('')
};
</script>
<style lang="scss" scoped>
.page {
background-color: #f8f8f8;
}
.item-box {
background-color: #FFFFFF;
margin: 30rpx;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 10rpx;
border-radius: 8rpx;
color: #303133;
font-size: 32rpx;
}
</style>

@ -0,0 +1,147 @@
<template>
<view>
<view class="top-swiper">
<view class="box">
<view style="height: 44px;"></view>
<swiper class="swiper" :previous-margin="swiper.margin" :next-margin='swiper.margin' :circular="true"
@change="swiperChange">
<swiper-item v-for="(item,index) in card_menu" :key="index" @click="toUrl(item.url)">
<!-- <image class='le-img' :src='item' :class="{'le-active':swiper.index == index}"></image> -->
<view class="le-img" :class="{'le-active':swiper.index == index}">
<view class="img_box">
<image class="card_img" :src="item.img" mode="aspectFill"></image>
</view>
<view class="detail_box">
<view class="title_box">{{item.title}}</view>
<view class="author_box">By:{{item.author}}</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
card_menu: {
type: Array,
default: []
}
},
data() {
return {
swiper: {
margin: "150rpx",
index: 0,
list: [
"/static/images/douyin/0.jpg",
"/static/images/douyin/4.jpg",
"/static/images/douyin/7.jpg",
]
}
}
},
components: {
},
mounted() {
},
methods: {
//swiper
swiperChange: function(e) {
this.swiper.index = e.detail.current;
},
toUrl(url){
this.$Common.navigateTo(url);
}
}
}
</script>
<style lang="scss">
.top-swiper {
margin-bottom: 30rpx;
.box {
padding-top: var(--status-bar-height);
box-sizing: content-box;
position: absolute;
z-index: 5;
top: 0;
left: 0;
width: 100%;
height: auto;
}
.swiper {
height: 600rpx;
margin: 0 20rpx;
.le-img {
width: 100%;
height: 100%;
display: block;
transform: scale(0.9);
transition: transform 0.3s ease-in-out 0s;
border-radius: 10px;
background-color: #fff;
overflow: hidden;
&.le-active {
transform: scale(1);
}
.img_box {
width: 100%;
height: 65%;
overflow: hidden;
.card_img {
height: 100%;
width: 100%;
}
}
.detail_box {
width: 100%;
height: 35%;
overflow: hidden;
.title_box {
width: 100%;
text-align: center;
font-size: 40rpx;
margin: 30rpx 0;
}
.author_box {
width: 100%;
text-align: center;
font-size: 30rpx;
position: relative;
height: 80rpx;
line-height: 80rpx;
&::before {
content: "";
height: 1px;
width: 150rpx;
position: absolute;
transform: translateX(-50%);
left: 50%;
top: 0;
background: #000;
}
}
}
}
}
}
</style>

@ -0,0 +1,139 @@
<template>
<view class="content">
<scroll-view v-if="true" scroll-y class="data_body" :style="{height:scrollHeight}">
<!--数据进度条-->
<view class="progress">
<data-progress :progressList="userHealthyLineBar" :borderRadius="20" padMiddle="true"></data-progress>
</view>
<view class="split_line"></view>
<!-- 新增小程序会员趋势-->
<view class="friend_operate">
<text-block :content="baseData"></text-block>
<view class="trend_title">新增小程序会员趋势</view>
<view class="charts-box">
<qiun-data-charts
type="mix"
canvasId="three_a"
:canvas2d="isCanvas2d"
:reshow="delayload"
:opts="{yAxis:{data:[{position: 'left',title: '销售额/万',max:userTrand?userTrand.yAxis[0].max:0,min:userTrand?userTrand.yAxis[0].min:0},{position: 'right',title: '',max:userTrand?userTrand.yAxis[1].max:0,min:userTrand?userTrand.yAxis[1].min:0,unit:'%'}]}}"
:chartData="userTrand"/>
</view>
</view>
<view class="split_line"></view>
<!-- 会员扫码率趋势-->
<view class="friend_operate">
<text-block :content="scanTrand"></text-block>
<view class="trend_title">会员扫码率趋势</view>
<view class="charts-box">
<qiun-data-charts
type="mix"
canvasId="three_b"
:canvas2d="isCanvas2d"
:reshow="delayload"
:opts="{yAxis:{data:[{position: 'left',title: '',max:scanTrandPrecent?scanTrandPrecent.yAxis[0].max:0,min:scanTrandPrecent?scanTrandPrecent.yAxis[0].min:0,unit:'%'}]}}"
:chartData="scanTrandPrecent"/>
</view>
</view>
<view class="split_line"></view>
<!-- 小程序活跃会员占比-->
<view class="friend_operate">
<text-block :content="miniActive"></text-block>
<view class="charts-box">
<qiun-data-charts
type="mix"
canvasId="three_c"
:canvas2d="isCanvas2d"
:reshow="delayload"
:opts="{yAxis:{data:[{position: 'left',title: '销售额/万',max:miniActivePrecent?miniActivePrecent.yAxis[0].max:0,min:miniActivePrecent?miniActivePrecent.yAxis[0].min:0},{position: 'right',title: '',max:miniActivePrecent?miniActivePrecent.yAxis[1].max:0,min:miniActivePrecent?miniActivePrecent.yAxis[1].min:0,unit:'%'}]}}"
:chartData="miniActivePrecent"
/>
</view>
</view>
</scroll-view>
<view v-else class="container padding_stand-big normal_color">
<li class="iconfont icon-cry cry"></li>暂无数据
</view>
</view>
</template>
<script>
import DataProgress from "../data-progress/data-progress.vue"
import userHealthyLineBar from '../../static/json/user-healthy/1.json';
import baseData from '../../static/json/user-healthy/2.json';
import userTrand from '../../static/json/user-healthy/3.json';
import scanTrand from '../../static/json/user-healthy/4.json';
import scanTrandPrecent from '../../static/json/user-healthy/5.json';
import miniActive from '../../static/json/user-healthy/6.json';
import miniActivePrecent from '../../static/json/user-healthy/7.json';
var _self;
export default {
name:'user-healthy',
props: {
scrollHeight:{
type:String,
default:"600px"
}
},
components:{
DataProgress
},
data() {
return {
userHealthyLineBar,
baseData,
userTrand,
scanTrand,
scanTrandPrecent,
miniActive,
miniActivePrecent,
delayload:false,
isCanvas2d:this.$Config.ISCANVAS2D,
}
},
mounted() {
this.getData();
},
methods:{
async getData(){
uni.showLoading();
await setTimeout(() => {
this.delayload = true;
uni.hideLoading();
}, 1000)
}
}
}
</script>
<style scoped lang="less">
.content{
padding-top: 10rpx;
.progress,.firend_operate{
padding: 0 10rpx;
}
.progress{
margin-bottom: 20rpx;
}
.friend_operate{
padding: 30rpx 10rpx;
.title{
text-align:left;
margin-bottom: 20rpx;
}
.trend_title{
text-align: right;
font-size: 22rpx;
color: #ff9900;
margin-top: 20rpx;
}
}
}
</style>

@ -0,0 +1,200 @@
<template>
<view class="content">
<scroll-view v-if="true" scroll-y class="data_body" :style="{height:scrollHeight}">
<!--数据进度条-->
<view class="progress">
<data-progress :progressList="userOperateLineBar" :borderRadius="20" padMiddle="true"></data-progress>
</view>
<view class="split_line"></view>
<!-- 活跃会员-->
<view class="friend_operate">
<view class="title">活跃会员</view>
<text-block :content="userActive"></text-block>
</view>
<!-- 会员消费 -->
<view class="friend_operate" style="padding-bottom: 30rpx;">
<view class="title">会员消费</view>
<text-block :content="userConsume"></text-block>
</view>
<view class="split_line"></view>
<!-- 会员ARPU -->
<view class="friend_operate">
<view class="title">会员ARPU
<text class="font-small">(会员年度平均销售金额)</text>
<text class="trend_title">目标增量{{userARPU.targetAdd}}</text>
</view>
<view class="charts-box">
<qiun-data-charts type="mix"
:chartData="userARPU"
:reshow="delayload"
:canvas2d="isCanvas2d"
canvasId="two_a"
:opts="{yAxis:{data:[{title: '',max:userARPU?userARPU.yAxis[0].max:0,min:userARPU?userARPU.yAxis[0].min:0},{title: '',unit:'%',max:userARPU?userARPU.yAxis[1].max:0,min:userARPU?userARPU.yAxis[1].min:0,position:'right'}]},extra:{markLine:{data:[{value:userARPU?userARPU.target:'',LineColor:'#ff9900',showLabel:true}]}}}"/>
</view>
</view>
<view class="split_line"></view>
<!-- 会员消费频次 -->
<view class="friend_operate">
<view class="title">会员消费频次
<text class="font-middle">()</text>
<text class="trend_title">目标增量{{userARPU.targetAdd}}</text>
</view>
<view class="charts-box">
<qiun-data-charts type="mix"
:chartData="userARPU"
:reshow="delayload"
:canvas2d="isCanvas2d"
canvasId="two_b"
:opts="{yAxis:{data:[{title: '',max:userARPU?userARPU.yAxis[0].max:0,min:userARPU?userARPU.yAxis[0].min:0},{title: '',unit:'%',max:userARPU?userARPU.yAxis[1].max:0,min:userARPU?userARPU.yAxis[1].min:0,position:'right'}]},extra:{markLine:{data:[{value:userARPU?userARPU.target:'',LineColor:'#ff9900',showLabel:true}]}}}"/>
</view>
</view>
<view class="split_line"></view>
<!-- 微客群运营-->
<view class="friend_operate">
<view class="title">活跃会员分布
<text class="font-middle">(最近活跃时间)</text>
</view>
<senior-table :headers="dataTable.headers" :contents="dataTable.contents" :urlCol="dataTable.urlCol" :firstLineFixed="true" :sortCol="dataTable.sortCol" :computedCol="dataTable.computedCol" :formatCol="dataTable.formatCol"></senior-table>
</view>
<view class="split_line"></view>
<!-- X商品脱落率-->
<view class="friend_operate">
<view class="title">
X慢病 商品脱落率
</view>
<view style="display: flex;justify-content: space-between;">
<view v-for="(item,index) in xProductDropPrecent" class="charts-box" style="height: 130px;width: 45%;">
<qiun-data-charts
type="arcbar"
:chartData="item"
:canvasId="'two_c_'+ index"
:canvas2d="true"
:reshow="delayload"
:opts="{title:{name:item.series[0].data * 100 + '%',color:item.series[0].color,fontSize:25},subtitle:{name:item.series[0].name,color:'#666666',fontSize:12}}" />
</view>
</view>
</view>
<!-- 慢病病种脱落率-->
<view class="friend_operate">
<view class="title">慢病病种脱落率
</view>
<view class="charts-box">
<qiun-data-charts type="mix"
:chartData="illnessDropPrecent"
:reshow="delayload"
:canvas2d="true"
canvasId="two_d"
:opts="{yAxis:{data:[{title: ''}]}}"/>
</view>
</view>
<!-- W商品脱落率-->
<view class="friend_operate">
<view class="title">
W保健 商品脱落率
</view>
<view style="display: flex;justify-content: space-between;">
<view v-for="(item,index) in wProductDropPrecent" class="charts-box" style="height: 130px;width: 45%;">
<qiun-data-charts
type="arcbar"
:chartData="item"
:canvasId="'two_e_'+index"
:canvas2d="true"
:reshow="delayload"
:opts="{title:{name:item.series[0].data * 100 + '%',color:item.series[0].color,fontSize:25},subtitle:{name:item.series[0].name,color:'#666666',fontSize:12}}" />
</view>
</view>
</view>
</scroll-view>
<view v-else class="container padding_stand-big normal_color">
<li class="iconfont icon-cry cry"></li>暂无数据
</view>
</view>
</template>
<script>
import DataProgress from "../data-progress/data-progress.vue"
import SeniorTable from "../data-table/senior-table.vue"
import userOperateLineBar from '../../static/json/user-operate/1.json';
import userActive from '../../static/json/user-operate/2.json';
import userConsume from '../../static/json/user-operate/3.json';
import userARPU from '../../static/json/user-operate/4.json';
import dataTable from "../../static/json/user-operate/6.json"
import xProductDropPrecent from '../../static/json/user-operate/7.json';
import wProductDropPrecent from '../../static/json/user-operate/9.json';
import illnessDropPrecent from '../../static/json/user-operate/8.json';
export default {
name:'user-operate',
props: {
scrollHeight:{
type:String,
default:"600px"
}
},
components:{
DataProgress,SeniorTable
},
data() {
return {
userOperateLineBar,
userActive,
userConsume,
userARPU,
xProductDropPrecent,
wProductDropPrecent,
illnessDropPrecent,
dataTable,
delayload:false,
isCanvas2d:this.$Config.ISCANVAS2D
}
},
mounted() {
this.getData();
},
methods:{
async getData(){
uni.showLoading();
await setTimeout(() => {
this.delayload = true;
uni.hideLoading();
}, 1000)
}
}
}
</script>
<style scoped lang="less">
.content{
padding-top: 10rpx;
.progress,.firend_operate{
padding: 0 10rpx;
}
.progress{
margin-bottom: 20rpx;
}
.friend_operate{
padding: 30rpx 20rpx;
.title{
text-align:left;
margin-bottom: 30rpx;
font-size: 40rpx;
}
.trend_title{
float: right;
font-size: 22rpx;
color: #ff9900;
margin-top: 20rpx;
}
}
}
</style>

@ -0,0 +1,383 @@
<template>
<view class="content">
<scroll-view class="data_body" scroll-y :style="{height:scrollHeight}">
<template v-if="true">
<!-- 会员成长数据-->
<view class="view_item">
<view class="title">会员成长数据</view>
<view class="progress_circle">
<view v-for="(item,index) in CircleData" :key="index" :class="['progress_block','block_'+index]">
<view class="name">{{item.series[0].name}}</view>
<view class="value">{{item.series[0].value}}</view>
<view class="charts-box arcbar" style="height: 180rpx;width: 60%;">
<qiun-data-charts type="arcbar" :chartData="item" :canvasId="'four_a_'+index" :canvas2d="isCanvas2d"
:resshow="delayload"
:opts="{title:{name:item.series[0].precent,color:item.series[0].color,fontSize:15},subtitle:{name:'',color:'#666666',fontSize:12},extra:{arcbar:{backgroundColor:item.series[0].backgroundColor}}}" />
</view>
<view class="planet">
<view class="planet_shadow"></view>
<view class="crater1"></view>
<view class="crater2"></view>
<view class="crater3"></view>
<view class="crater4"></view>
</view>
<view class="star" :class="['star'+index]"></view>
<view class="star pink" :class="['star'+index]"></view>
<view class="star blue" :class="['star'+index]"></view>
<view class="star yellow" :class="['star'+index]"></view>
</view>
</view>
</view>
<view class="split_line"></view>
<!-- 会员数据来源 -->
<view class="friend_operate">
<view class="title">会员数据来源
<text class="font-small" style="color: #ff9900;">(Top5访问来源)</text>
</view>
<view v-if="delayload" class="charts-box">
<qiun-data-charts
type="ring"
canvasId="four_b"
:canvas2d="isCanvas2d"
:resshow="delayload"
:opts="{legend:{position: 'bottom'},title:{name: '',},subtitle: {name: ''}}"
:chartData="ProductRateData"/>
</view>
</view>
<view class="split_line"></view>
<!-- 服务评价概览-->
<view class="friend_operate">
<view class="title">服务评价概览</view>
<text-block :content="ServiceComment"></text-block>
</view>
<!-- 本周会员访问趋势图 -->
<view class="friend_operate">
<view class="title">本周会员访问趋势图</view>
<view v-if="delayload" class="charts-box" style="height: 300px;">
<qiun-data-charts
type="mix"
canvasId="four_c"
:canvas2d="isCanvas2d"
:resshow="delayload"
:opts="{yAxis:{data:[{position: 'left',title: '',min:0,unit:'万'}]}}"
:chartData="TrendData"
/>
</view>
</view>
<view class="split_line"></view>
<!-- 新增会员排行榜 -->
<view class="friend_operate">
<view class="title">新增会员排行榜</view>
<progress-bar :isRank="isRank" :content="RankData" />
</view>
</template>
<template v-else>
<view class="container padding_stand-big normal_color">
<li class="iconfont icon-cry cry"></li>暂无数据
</view>
</template>
</scroll-view>
</view>
</template>
<script>
import ProgressBar from "../progress-bar/progress-bar.vue"
import CircleData from "../../static/json/user-server/1.json"
import ProductRateData from '../../static/json/user-server/2.json';
import TrendData from '../../static/json/user-server/3.json';
import ServiceComment from '../../static/json/user-server/4.json';
import RankData from '../../static/json/user-server/5.json';
export default {
name:"user-server",
props:{
scrollHeight:{
type:String,
default:"600px"
}
},
components:{
ProgressBar
},
data(){
return {
CircleData,
TrendData,
ProductRateData,
ServiceComment,
RankData,
isRank:true,
isCanvas2d:this.$Config.ISCANVAS2D,
delayload: false, //
}
},
methods:{
async getData(){
uni.showLoading();
await setTimeout(() => {
this.delayload = true;
uni.hideLoading();
}, 1000)
}
},
mounted() {
this.getData();
}
}
</script>
<style scoped lang="scss">
.content{
padding-top: 10rpx;
}
.data_body{
height: 100%;
text-align: center;
color: #333333;
background-repeat: repeat;
background-color: #ffffff;
.friend_operate{
padding: 30rpx 20rpx;
.title{
text-align:left;
margin-bottom: 30rpx;
font-size: 40rpx;
}
}
.view_item{
padding: 30rpx 20rpx;
.title{
text-align:left;
margin-bottom: 30rpx;
font-size: 40rpx;
}
}
.progress_circle{
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
height: 450rpx;
.progress_block{
width: 45%;
border-radius: 20rpx;
height: 180rpx;
position: relative;
overflow: hidden;
.name{
color: #fff;
font-size: 24rpx;
position: absolute;
top: 20rpx;
left: 10rpx;
max-width: 144rpx;
}
.value{
color: #fff;
font-size: 40rpx;
position: absolute;
top: 64rpx;
left: 10rpx;
max-width: 144rpx;
}
.circle{
position: absolute;
right: 8rpx;
top: 16rpx;
}
.arcbar{
position: absolute;
right: -4rpx;
top: 8rpx;
}
}
.block_0{
background-color: #0FC3FF;
}
.block_1{
background-color: #FF6B8B;
}
.block_2{
background-color: #FFCB1D;
}
.block_3{
background-color: #3BDCAA;
}
}
}
.planet {
width: 60px;
height: 60px;
border-radius: 50%;
background: #333;
position: absolute;
left: -13px;
bottom: -26px;
overflow: hidden;
opacity: 0.5;
z-index: 0;
}
.planet_shadow {
position: absolute;
border-radius: 50%;
height: 100%;
width: 100%;
top: -40%;
right: -10%;
border: 35px solid rgba(0, 0, 0, .15);
}
.crater1,
.crater2,
.crater3,
.crater4 {
position: absolute;
border-radius: 50%;
background: rgba(0, 0, 0, .3);
box-shadow: inset 3px 3px 0 rgba(0, 0, 0, .2);
}
.crater1 {
width: 20px;
height: 20px;
left: 25%;
top: 20%;
}
.crater2 {
width: 10px;
height: 10px;
left: 50%;
top: 60%;
}
.crater3 {
width: 15px;
height: 15px;
left: 30%;
top: 65%;
}
.crater4 {
width: 15px;
height: 15px;
left: 60%;
top: 35%;
}
.star {
display: block;
width: 5px;
height: 5px;
border-radius: 50%;
background: #FFF;
top: 10px;
left: 50px;
position: relative;
transform-origin: 100% 0;
box-shadow: 0 0 5px 5px rgba(255, 255, 255, .3);
opacity: 0;
z-index: 2;
}
.star0{
animation: star-ani 4s infinite ease-out;
}
.star1{
animation: star-ani 5s infinite ease-out;
}
.star2{
animation: star-ani 6s infinite ease-out;
}
.star3{
animation: star-ani 7s infinite ease-out;
}
.star:after {
content: '';
display: block;
top: 20px;
left: 60px;
border: 0px solid #fff;
border-width: 0px 90px 2px 90px;
border-color: transparent transparent transparent rgba(255, 255, 255, .3);
transform: rotate(-45deg) translate3d(1px, 3px, 0);
box-shadow: 0 0 1px 0 rgba(255, 255, 255, .1);
transform-origin: 0% 100%;
animation: shooting-ani 100s infinite ease-out;
}
.pink {
top: 10px;
left: 60px;
background: #ff5a99;
animation-delay: 5s;
-webkit-animation-delay: 5s;
-moz-animation-delay: 5s;
}
.pink:after {
border-color: transparent transparent transparent #ff5a99;
animation-delay: 5s;
-webkit-animation-delay: 5s;
-moz-animation-delay: 5s;
}
.blue {
top: 15px;
left: 70px;
background: cyan;
animation-delay: 7s;
-webkit-animation-delay: 7s;
-moz-animation-delay: 7s;
}
.blue:after {
border-color: 'transpareanimation-delay: 12s';
-webkit-animation-delay: 7s;
-moz-animation-delay: 7s;
animation-delay: 7s;
}
.yellow {
top: 0px;
left: 80px;
background: #ffcd5c;
animation-delay: 5.8s;
}
.yellow:after {
border-color: transparent transparent transparent #ffcd5c;
animation-delay: 5.8s;
}
@keyframes star-ani {
0% {
opacity: 0;
transform: scale(0) rotate(0) translate3d(0, 0, 0);
-webkit-transform: scale(0) rotate(0) translate3d(0, 0, 0);
-moz-transform: scale(0) rotate(0) translate3d(0, 0, 0);
}
50% {
opacity: 0.5;
transform: scale(1) rotate(0) translate3d(-20px, 20px, 0);
-webkit-transform: scale(1) rotate(0) translate3d(-20px, 20px, 0);
-moz-transform: scale(1) rotate(0) translate3d(-20px, 20px, 0);
}
100% {
opacity: 0;
transform: scale(1) rotate(0) translate3d(-30px, 30px, 0);
-webkit-transform: scale(1) rotate(0) translate3d(-30px, 30px, 0);
-moz-transform: scale(1) rotate(0) translate3d(-30px, 30px, 0);
}
}
</style>

@ -0,0 +1,130 @@
<template>
<view class="content">
<scroll-view v-if="true" scroll-y class="data_body" :style="{height:scrollHeight}">
<!--数据进度条-->
<view class="progress">
<data-progress :progressList="wechatLineBar" :borderRadius="20" padMiddle="true"></data-progress>
</view>
<view class="split_line"></view>
<!-- 微好友运营-->
<view class="friend_operate">
<view class="title">微好友运营</view>
<text-block :content="friendTextBlock"></text-block>
<view style="display: flex;justify-content: space-around;">
<view v-for="(item,index) in panelData" :key="index" class="charts-box"
style="width: 45%;height: 200px;">
<qiun-data-charts type="gauge"
:opts="{title:{name: item.series[0].data * 100 + '%',color: '#24ABFD',offsetY:30},subtitle: {name: item.series[0].name,color: '#666666',fontSize: 15,offsetY:70},extra:{gauge:{type:'progress',width:20,splitLine:{fixRadius:-10,width:15,},}}}"
:chartData="item" :reshow="delayload" :canvas2d="isCanvas2d" :canvasId="'one_a_' + index" />
</view>
</view>
<view class="trend_title">新增微好友&小程序会员趋势</view>
<view class="charts-box">
<qiun-data-charts type="mix" :chartData="friendTrand" :reshow="delayload"
:canvas2d="isCanvas2d" canvasId="one_b" :opts="{yAxis:{data:[{title: ''}]}}" />
</view>
</view>
<view class="split_line"></view>
<!-- 微客群运营-->
<view class="friend_operate">
<view class="title">微客群运营</view>
<text-block :content="friendTextBlock"></text-block>
<view class="trend_title">新增人群&退群人数趋势</view>
<view class="charts-box">
<qiun-data-charts type="mix" :chartData="teamTrand" :reshow="delayload" :canvas2d="isCanvas2d"
canvasId="one_c" :opts="{yAxis:{data:[{title: '',max:teamTrand?teamTrand.yAxis[0].max:0,min:teamTrand?teamTrand.yAxis[0].min:0}]}}" />
</view>
</view>
<view class="split_line"></view>
<!-- 客户联系-->
<view class="friend_operate">
<view class="title">客户联系1对1运营执行</view>
<senior-table :headers="dataTable.headers" :contents="dataTable.contents" :urlCol="dataTable.urlCol" :firstLineFixed="true" :sortCol="dataTable.sortCol"></senior-table>
</view>
</scroll-view>
<view v-else class="container padding_stand-big normal_color">
<li class="iconfont icon-cry cry"></li>暂无数据
</view>
</view>
</template>
<script>
import DataProgress from "../data-progress/data-progress.vue"
import SeniorTable from "../data-table/senior-table.vue"
import wechatLineBar from '../../static/json/wechat/1.json';
import friendTextBlock from '../../static/json/wechat/2.json';
import panelData from '../../static/json/wechat/3.json';
import friendTrand from '../../static/json/wechat/4.json';
import teamTrand from '../../static/json/wechat/5.json';
import dataTable from "../../static/json/wechat/6.json"
export default {
name:'wechat',
props: {
scrollHeight:{
type:String,
default:"600px"
}
},
components:{
DataProgress,
SeniorTable,
},
data() {
return {
wechatLineBar,
friendTextBlock,
friendTrand,
panelData,
teamTrand,
dataTable,
scrollTop: 0,
delayload: false,
isCanvas2d: this.$Config.ISCANVAS2D,
}
},
mounted() {
this.getData();
},
methods:{
async getData() {
uni.showLoading();
await setTimeout(() => {
this.delayload = true;
uni.hideLoading();
}, 1000)
}
}
}
</script>
<style scoped lang="less">
.content{
padding-top: 10rpx;
.progress,.firend_operate{
padding: 0 10rpx;
}
.progress{
margin-bottom: 20rpx;
}
.friend_operate{
padding: 30rpx 20rpx;
.title{
text-align:left;
margin-bottom: 30rpx;
font-size: 40rpx;
}
.trend_title{
text-align: right;
font-size: 22rpx;
color: #ff9900;
margin-top: 50rpx;
}
}
}
</style>

@ -0,0 +1,93 @@
<template>
<view class="column">
<view v-for="(item,index) in progressList" :key="index" :class="['row','font-small','progress',padMiddle?'paddingMiddle':'']">
<text class="title">{{item.name}}</text>
<view class="body">
<view class="number">{{item.now?item.now+"/":""}}{{item.expect}} [{{item.value}}%]</view>
<progress :percent="item.value" backgroundColor="#C9C9C9"
:border-radius="borderRadius?borderRadius+'rpx':'0px'"
:color="time"
stroke-width="16" />
</view>
</view>
</view>
</template>
<script>
export default {
name:'data-progress',
props: {
progressList: {
type: Array,
default: ()=> {
return []
}
},
borderRadius:{
type:Number,
default:0
},
padMiddle:{
type:String,
default:"false"
}
},
data() {
return {
time:0
}
},
watch:{
"progressList":{
deep: true,
handler: function(newVal, oldVal) {
this.time = newVal.filter(x=>x.name=="时间进度")[0].value;
}
}
},
created() {
this.time = this.progressList.filter(x=>x.name=="时间进度")[0].value;
}
}
</script>
<style lang="scss">
.paddingMiddle{
padding: 18rpx 10rpx;
}
.progress{
.title{
font-size: 28rpx;
width: 170rpx;
display: flex;
align-items: center;
}
.body{
position: relative;
flex: 1;
.number{
color: #fff;
position: absolute;
z-index: 2;
left: 26rpx;
height: 100%;
display: flex;
align-items: center;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
height: 44rpx;
}
progress{
padding: 6rpx 0;
}
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,218 @@
<template>
<div class="dropdown-item">
<!-- selected -->
<view :class="['dropdown-item__selected',listWidth!='150rpx'?'dropdown-item__right':'dropdown-item__left']"
@click="changePopup" :style="{maxWidth:selectWidth}">
<view class="selected__name">{{selectItem.text}}</view>
<view class="selected__icon"
:class="showClass === 'show'? 'up' : 'down'"
>
<li class="iconfont icon-caretdown"></li>
</view>
</view>
<view class="dropdown-item__content" :style="{top: contentTop + 'rpx'}" v-if="showList">
<!-- dropdown -->
<view :class="['list', showClass]" :style="{left: contentLeft>0?contentLeft + 'rpx':'auto',right: contentRight>0?contentRight + 'rpx':'auto',}">
<view class="list__option"
v-for="(item, index) in list" :key="index"
@click="choose(item)">
<view>{{item.text}}</view>
<icon v-if="item.value === value" type="success_no_circle" size="20"/>
</view>
</view>
<!-- dropdown-mask -->
<view :class="['dropdown-mask', showClass]" v-if="showList" @click="closePopup"></view>
</view>
</div>
</template>
<script>
export default {
components: {
},
props: {
value: [Number, String, Object],
list: {
type: Array,
default: ()=> {
return []
}
},
contentTop:{
type:String,
default:"185"
},
contentLeft:{
type:String,
default:"0"
},
contentRight:{
type:String,
default:"0"
},
listWidth:{
type:String,
default:'150rpx'
},
selectWidth:{
type:String,
default:'150rpx'
}
},
data() {
return {
showList: "",
showClass: '',
selectItem: {},
}
},
watch: {
list(newVal,oldVal){
this.selectItem = newVal[0];
}
},
mounted() {
this.showList = this.active;
this.selectItem = this.list[0];
},
methods: {
choose(item) {
if(item.value != "auto"){
this.selectItem = item
}
this.$emit('changeItem', item);
this.closePopup();
},
selectAuto(){
this.selectItem = {text: '指定日期',value: 'auto'};
},
changePopup() {
if(this.showList) {
this.closePopup()
} else {
this.openPopup()
}
},
openPopup() {
setTimeout(() => {
this.showClass = 'show';
this.showList = true;
}, 100);
},
closePopup() {
this.showClass = ''
setTimeout(() => {
this.showList = false
}, 200);
},
close() {
this.showClass = ''
this.showList = false
},
}
}
</script>
<style lang="scss">
li{
list-style-type:none;
}
.dropdown-item__content{
z-index: 10!important;
}
.dropdown-item {
width: 100%;
flex:1;
position: relative;
&__selected {
position: relative;
padding: 10rpx 0;
box-sizing: border-box;
color: #fff;
.selected__name {
font-size: 28rpx;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.selected__icon {
margin-left: 20rpx;
&.down {
transition: transform .3s;
transform: rotateZ(0);
}
&.up {
transition: transform .3s;
transform: rotateZ(-180deg);
}
}
}
&__left{
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
&__right{
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
&__content {
position: fixed;
left: 0;
right: 0;
overflow: hidden;
top: 0;
bottom: 0;
z-index: 1;
.list {
max-height: 400px;
text-align: center;
overflow-y: auto;
position: absolute;
z-index: 1200;
background: #fff;
transform: translateY(-100%);
transition: all .3s;
&.show {
transform: translateY(0);
}
&__option {
font-size:30rpx;
padding: 18rpx;
display: flex;
justify-content: space-between;
color: #303133;
&:not(:last-child) {
border-bottom: 1rpx solid #DDDDDD;
}
}
}
.dropdown-mask {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
transition: all .3s;
z-index: 1100;
&.show {
background:rgba(0,0,0,0.5);
}
}
}
&:not(:last-child):after {
content: ' ';
position: absolute;
width: 2rpx;
top: 36rpx;
bottom: 36rpx;
right: 0;
background: $uni-border-color;
}
}
</style>

@ -0,0 +1,125 @@
<template>
<view>
<view v-if="copyContent.length > 0" class="ranking">
<view class="ranking-item" v-for="(content,index) in copyContent" :key="index" :style="{padding:progressPadding+'rpx'}">
<view class="name">{{content.name}}</view>
<view class="progress" >
<text :style="{background:content.background,width:content.width + '%',height:progressWidth+'rpx'}"></text>
</view>
<view class="num">{{content.num}}</view>
</view>
</view>
</view>
</template>
<script>
export default{
name:'ranking-list',
props:{
content:{
type: Array,
default() {
return []
}
},
isPC:{
type:Boolean,
default:false
},
isRank:{
type:Boolean,
default:false
}
},
data(){
return{
progressWidth:24,
progressPadding:10,
maxNumber:0,
culCount:0,
copyContent:[]
}
},
watch:{
content(newV){
this.init()
}
},
methods:{
init(){
this.copyContent = this.deepClone(this.content)
if(this.copyContent && this.copyContent.length >0){
if(this.isRank){
this.copyContent = this.copyContent.sort((a,b) => b.num - a.num);
this.maxNumber = this.copyContent[0].num;
}else{
this.maxNumber = Math.max.apply(Math,this.copyContent.map(item => { return item.num }));
}
this.copyContent.map((item,index) =>{
item.width = this.computeWidth(this.maxNumber,item.num);
});
}
},
computeWidth(max,current){
let num = (current / max) * 100;
return num.toFixed(2);
},
deepClone(obj) {
var cloneObj = new obj.constructor()
if(obj === null) return obj
if(obj instanceof Date) return new Date(obj)
if(obj instanceof RegExp) return new RegExp(obj)
if (typeof obj !== 'object') return obj
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
cloneObj[i] = this.deepClone(obj[i])
}
}
return cloneObj
}
},
mounted() {
if(this.isPC){
this.progressWidth = 40;
this.progressPadding = 30;
}
this.init();
}
}
</script>
<style scoped lang="scss">
.ranking-item{
display: flex;
margin-bottom: 13rpx;
align-content: center;
height: 50rpx;
.name{
padding-right: 10rpx;
color: #868688;
font-size: 20rpx;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.progress{
flex:5;
text-align: left;
padding-right: 10rpx;
text{
display: inline-block;
border-radius: 30rpx;
vertical-align:top;
}
}
.num{
font-size: 26rpx;
color: #3EB2F5;
flex: 1;
}
}
</style>

@ -0,0 +1,93 @@
<template>
<view>
<view class="ranking">
<view class="ranking-item" v-for="(content,index) in content" :key="index">
<view class="name">{{content.name}}</view>
<view class="progress" >
<text :style="{backgroundImage:'linear-gradient(to top right,'+getColor(0,index)+','+getColor(1,index)+')',width:content.width + '%'}"></text>
</view>
<view class="num">{{content.num}}</view>
</view>
</view>
</view>
</template>
<script>
export default{
name:'ranking-list',
props:{
content:{
type: Array,
default() {
return []
}
}
},
methods:{
init(){
if(this.content && this.content.length >0){
this.content = this.content.sort((a,b) => b.num - a.num);
let max = this.content[0].num;
this.content.map((item,index) =>{
item.width = this.computeWidth(max,item.num);
});
this.$emit("updateRanking",this.content)
}
},
computeWidth(max,current){
let num = (current / max) * 100;
return num.toFixed(2);
},
getColor(id,index){
let color = "";
switch(index){
case 0:
color = id == 0 ? "#fff":"#A80BFC";
break;
case 1:
color = id == 0 ? "#fff":"#740CFF";
break;
case 2:
color = id == 0 ? "#fff":"#4A08DC";
break;
default :
color = id == 0 ? "#fff":"#1936DA";
break;
}
return color;
},
},
mounted() {
this.init();
}
}
</script>
<style scoped lang="scss">
.ranking-item{
display: flex;
margin-bottom: 13rpx;
padding: 10rpx;
align-content: center;
.name{
padding-right: 10rpx;
color: #868688;
}
.progress{
flex:5;
text-align: left;
padding-right: 10rpx;
text{
display: inline-block;
height: 100%;
}
}
.num{
font-size: 26rpx;
color: #3EB2F5;
}
}
</style>

@ -0,0 +1,186 @@
<template>
<view class="text_block">
<template v-for="(item,index) in content">
<view v-if="item.kind == 1" :key="index" :style="{backgroundImage:'linear-gradient(to top right,'+item.background[0]+','+item.background[1]+')'}" :class="[(index+1)%3==0 ? '':'marginRight','kind','kind_one','breathe-blue']">
<view class="view_100" :style="{fontSize:item.content[0].size,color:item.content[0].colorvalue}">{{item.content[0].value}}</view>
<view class="view_100" :style="{fontSize:item.content[1].size,color:item.content[1].colortext}">{{item.content[1].text}}</view>
</view>
<view v-else-if="item.kind == 2" :key="index" :class="[(index+1)%3==0 ? '':'marginRight','kind','kind_two','breathe-blue']" :style="{backgroundImage:'linear-gradient(to top right,'+item.background[0]+','+item.background+')' ,marginRight:(index+1)%3==0?'0rpx':'40rpx'}">
<view v-for="(content,i) in item.content" :key="i" class="two_1">
<text :style="{fontSize:content.size,color:content.colortext}">{{content.text}}:</text>
<text :style="{fontSize:content.size,color:content.colorvalue}">{{content.value}}</text>
</view>
</view>
<view v-else-if="item.kind == 3" :key="index" class="kind kind_three breathe-blue" :style="{backgroundImage:'linear-gradient(to top right,'+item.background[0]+','+item.background+')'}">
<view class="view_100" :style="{fontSize:item.content[0].size,color:item.content[0].colorvalue}">{{item.content[0].value}}</view>
<view class="view_100" :style="{fontSize:item.content[1].size,color:item.content[1].colortext}">{{item.content[1].text}}</view>
<view class="three_3 view_100">
<view v-for="(j,i) in 2" :key="i">
<text :style="{fontSize:item.content[i+2].size,color:item.content[i+2].colortext}">{{item.content[i+2].text}}:</text>
<text :style="{fontSize:item.content[i+2].size,color:item.content[i+2].colorvalue}">{{item.content[i+2].value}}</text>
</view>
</view>
</view>
<view v-else-if="item.kind == 4" :key="index" :class="[(index+1)%3==0 ? '':'marginRight','kind','kind_four','breathe-blue']" :style="{backgroundImage:'linear-gradient(to top right,'+item.background[0]+','+item.background[1]+')',marginRight:(index+1)%3==0?'0rpx':'40rpx'}">
<view class="view_100" :style="{fontSize:item.content[0].size,color:item.content[0].colortext}">{{item.content[0].text}}</view>
<view class="view_100" :style="{fontSize:item.content[1].size,color:item.content[1].colorvalue}">{{item.content[1].value}}</view>
<view class="four_3" :style="{fontSize:item.content[2].size,color:item.content[2].colorvalue}">
<text :style="{fontSize:item.content[3].size,color:item.content[3].colorvalue}">{{item.content[2].text}}</text>
<li v-if="item.content[3].text == 'up'" class="iconfont icon-up icon" :style="{color:item.content[3].colortext}"></li>
<li v-else class="iconfont icon-down icon" :style="{color:item.content[3].colortext}"></li>
<text :style="{fontSize:item.content[3].size,color:item.content[3].colorvalue}">{{item.content[3].value}}</text>
</view>
</view>
<view v-else-if="item.kind == 5" :key="index" :class="[(index+1)%3==0 ? '':'marginRight','kind','kind_five','breathe-red']" :style="{backgroundImage:'linear-gradient(to top right,'+item.background[0]+','+item.background[1]+')',marginRight:(index+1)%3==0?'0rpx':'40rpx'}">
<view class="view_100" :style="{fontSize:item.content[0].size,color:item.content[0].colortext}">{{item.content[0].text}}</view>
<view class="view_100" :style="{fontSize:item.content[1].size,color:item.content[1].colorvalue}">{{item.content[1].value}}</view>
<view class="five_3 view_100">
<view v-for="(j,i) in 2" :key="i">
<text :style="{fontSize:item.content[j+2].size,color:item.content[j+2].colortext}">{{item.content[j+2].text}}</text>
<text :style="{fontSize:item.content[j+2].size,color:item.content[j+2].colorvalue}">{{item.content[j+2].value}}</text>
</view>
</view>
<view class="five_4">
<text :style="{fontSize:item.content[4].size,color:item.content[4].colortext}">{{item.content[4].text}}</text>
<text :style="{fontSize:item.content[4].size,color:item.content[4].colorvalue}">{{item.content[4].value}}</text>
</view>
</view>
</template>
</view>
</template>
<script>
export default {
props:{
content: {
type: Array,
default: []
},
},
data() {
return {
}
},
methods: {
},
mounted() {
uni.onWindowResize((res) => {
console.log('变化后的窗口宽度=' + res.size.windowWidth)
console.log('变化后的窗口高度=' + res.size.windowHeight)
})
}
}
</script>
<style lang="scss">
.text_block{
display: flex;
width: 100%;
flex-wrap: wrap;
.marginRight{
margin-right: 36rpx!important;
}
.view_100{
width: 100%;
}
.CPT_DYBG {
overflow: hidden;
position: relative;
}
.kind{
width: 24%;
padding: 10rpx;
margin-bottom: 40rpx;
display: flex;
justify-content: center;
flex-wrap: wrap;
border-radius: 16rpx;
margin-left: 16rpx;
box-shadow: -4px 4px 4px #ccc;
position: relative;
}
.kind_one{
border-radius: 10rpx;
}
.kind_two{
border-radius: 10rpx;
}
.kind_three{
border-radius: 16rpx;
width: 300rpx;
margin: 0 auto;
.three_3{
display: flex;
justify-content: space-around;
}
}
.kind_four{
border-radius: 10rpx;
.four_3{
display: flex;
li {
list-style-type:none;
}
.icon{
margin-top: -8rpx;
transform: scale(0.8);
}
}
}
.kind_five{
border-radius: 20rpx;
.five_3{
view{
width: 100%;
}
}
}
}
// .breathe-blue {
// position:relative;
// color:#fff;
// text-align:center;
// cursor:pointer;
// box-shadow:0 1px 2px rgba(0,0,0,.3);
// overflow:hidden;
// -webkit-animation-timing-function:ease-in-out;
// -webkit-animation-name:breatheblue;
// -webkit-animation-duration:2000ms;
// -webkit-animation-iteration-count:infinite;
// -webkit-animation-direction:alternate;
// }
// @keyframes breatheblue {
// 0% {
// opacity:.8;
// box-shadow:0 1px 2px rgba(62,178,245,0.5);
// }
// 100% {
// opacity:1;
// box-shadow:0 1px 30px rgba(147,116,247,0.6);
// }
// }
// .breathe-red {
// position:relative;
// color:#fff;
// text-align:center;
// cursor:pointer;
// box-shadow:0 1px 2px rgba(0,0,0,.3);
// overflow:hidden;
// -webkit-animation-timing-function:ease-in-out;
// -webkit-animation-name:breathered;
// -webkit-animation-duration:2000ms;
// -webkit-animation-iteration-count:infinite;
// -webkit-animation-direction:alternate;
// }
// @keyframes breathered {
// 0% {
// opacity:.8;
// box-shadow:0 1px 2px rgba(247,126,137,0.5);
// }
// 100% {
// opacity:1;
// box-shadow:0 1px 30px rgba(247,149,59,0.9);
// }
// }
</style>

@ -0,0 +1,600 @@
/**
* @1900-2100区间内的公历农历互转
* @charset UTF-8
* @github https://github.com/jjonline/calendar.js
* @Author Jea杨(JJonline@JJonline.Cn)
* @Time 2014-7-21
* @Time 2016-8-13 Fixed 2033hexAttribution Annals
* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug
* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
* @Version 1.0.3
* @公历转农历calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
* @农历转公历calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
*/
/* eslint-disable */
var calendar = {
/**
* 农历1900-2100的润大小信息表
* @Array Of Property
* @return Hex
*/
lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
/** Add By JJonline@JJonline.Cn**/
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
0x0d520], // 2100
/**
* 公历每个月份的天数普通表
* @Array Of Property
* @return Number
*/
solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
/**
* 天干地支之天干速查表
* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
* @return Cn string
*/
Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
/**
* 天干地支之地支速查表
* @Array Of Property
* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
* @return Cn string
*/
Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
/**
* 天干地支之地支速查表<=>生肖
* @Array Of Property
* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
* @return Cn string
*/
Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
/**
* 24节气速查表
* @Array Of Property
* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
* @return Cn string
*/
solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
/**
* 1900-2100各年的24节气日期速查表
* @Array Of Property
* @return 0x string For splice
*/
sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
'97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
'97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
'97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
'97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
'9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
'7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
'977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
'7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
'7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
'665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
/**
* 数字转中文速查表
* @Array Of Property
* @trans ['日','一','二','三','四','五','六','七','八','九','十']
* @return Cn string
*/
nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
/**
* 日期转农历称呼速查表
* @Array Of Property
* @trans ['初','十','廿','卅']
* @return Cn string
*/
nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
/**
* 月份转农历称呼速查表
* @Array Of Property
* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
* @return Cn string
*/
nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
/**
* 返回农历y年一整年的总天数
* @param lunar Year
* @return Number
* @eg:var count = calendar.lYearDays(1987) ;//count=387
*/
lYearDays: function (y) {
var i;
var sum = 348
for (i = 0x8000; i > 0x8; i >>= 1) {
sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0
}
return (sum + this.leapDays(y))
},
/**
* 返回农历y年闰月是哪个月若y年没有闰月 则返回0
* @param lunar Year
* @return Number (0-12)
* @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
*/
leapMonth: function (y) { // 闰字编码 \u95f0
return (this.lunarInfo[y - 1900] & 0xf)
},
/**
* 返回农历y年闰月的天数 若该年没有闰月则返回0
* @param lunar Year
* @return Number (02930)
* @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
*/
leapDays: function (y) {
if (this.leapMonth(y)) {
return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
}
return (0)
},
/**
* 返回农历y年m月非闰月的总天数计算m为闰月时的天数请使用leapDays方法
* @param lunar Year
* @return Number (-12930)
* @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
*/
monthDays: function (y, m) {
if (m > 12 || m < 1) {
return -1
}// 月份参数从1至12参数错误返回-1
return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
},
/**
* 返回公历(!)y年m月的天数
* @param solar Year
* @return Number (-128293031)
* @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
*/
solarDays: function (y, m) {
if (m > 12 || m < 1) {
return -1
} // 若参数错误 返回-1
var ms = m - 1
if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
} else {
return (this.solarMonth[ms])
}
},
/**
* 农历年份转换为干支纪年
* @param lYear 农历年的年份数
* @return Cn string
*/
toGanZhiYear: function (lYear) {
var ganKey = (lYear - 3) % 10
var zhiKey = (lYear - 3) % 12
if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
},
/**
* 公历月日判断所属星座
* @param cMonth [description]
* @param cDay [description]
* @return Cn string
*/
toAstro: function (cMonth, cDay) {
var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
},
/**
* 传入offset偏移量返回干支
* @param offset 相对甲子的偏移量
* @return Cn string
*/
toGanZhi: function (offset) {
return this.Gan[offset % 10] + this.Zhi[offset % 12]
},
/**
* 传入公历(!)y年获得该年第n个节气的公历日期
* @param y公历年(1900-2100)n二十四节气中的第几个节气(1~24)从n=1(小寒)算起
* @return day Number
* @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
*/
getTerm: function (y, n) {
if (y < 1900 || y > 2100) {
return -1
}
if (n < 1 || n > 24) {
return -1
}
var _table = this.sTermInfo[y - 1900]
var _info = [
parseInt('0x' + _table.substr(0, 5)).toString(),
parseInt('0x' + _table.substr(5, 5)).toString(),
parseInt('0x' + _table.substr(10, 5)).toString(),
parseInt('0x' + _table.substr(15, 5)).toString(),
parseInt('0x' + _table.substr(20, 5)).toString(),
parseInt('0x' + _table.substr(25, 5)).toString()
]
var _calday = [
_info[0].substr(0, 1),
_info[0].substr(1, 2),
_info[0].substr(3, 1),
_info[0].substr(4, 2),
_info[1].substr(0, 1),
_info[1].substr(1, 2),
_info[1].substr(3, 1),
_info[1].substr(4, 2),
_info[2].substr(0, 1),
_info[2].substr(1, 2),
_info[2].substr(3, 1),
_info[2].substr(4, 2),
_info[3].substr(0, 1),
_info[3].substr(1, 2),
_info[3].substr(3, 1),
_info[3].substr(4, 2),
_info[4].substr(0, 1),
_info[4].substr(1, 2),
_info[4].substr(3, 1),
_info[4].substr(4, 2),
_info[5].substr(0, 1),
_info[5].substr(1, 2),
_info[5].substr(3, 1),
_info[5].substr(4, 2)
]
return parseInt(_calday[n - 1])
},
/**
* 传入农历数字月份返回汉语通俗表示法
* @param lunar month
* @return Cn string
* @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
*/
toChinaMonth: function (m) { // 月 => \u6708
if (m > 12 || m < 1) {
return -1
} // 若参数错误 返回-1
var s = this.nStr3[m - 1]
s += '\u6708'// 加上月字
return s
},
/**
* 传入农历日期数字返回汉字表示法
* @param lunar day
* @return Cn string
* @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
*/
toChinaDay: function (d) { // 日 => \u65e5
var s
switch (d) {
case 10:
s = '\u521d\u5341';
break
case 20:
s = '\u4e8c\u5341';
break
break
case 30:
s = '\u4e09\u5341';
break
break
default :
s = this.nStr2[Math.floor(d / 10)]
s += this.nStr1[d % 10]
}
return (s)
},
/**
* 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是立春
* @param y year
* @return Cn string
* @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
*/
getAnimal: function (y) {
return this.Animals[(y - 4) % 12]
},
/**
* 传入阳历年月日获得详细的公历农历object信息 <=>JSON
* @param y solar year
* @param m solar month
* @param d solar day
* @return JSON object
* @eg:console.log(calendar.solar2lunar(1987,11,01));
*/
solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
// 年份限定、上限
if (y < 1900 || y > 2100) {
return -1// undefined转换为数字变为NaN
}
// 公历传参最下限
if (y == 1900 && m == 1 && d < 31) {
return -1
}
// 未传参 获得当天
if (!y) {
var objDate = new Date()
} else {
var objDate = new Date(y, parseInt(m) - 1, d)
}
var i;
var leap = 0;
var temp = 0
// 修正ymd参数
var y = objDate.getFullYear()
var m = objDate.getMonth() + 1
var d = objDate.getDate()
var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
for (i = 1900; i < 2101 && offset > 0; i++) {
temp = this.lYearDays(i)
offset -= temp
}
if (offset < 0) {
offset += temp;
i--
}
// 是否今天
var isTodayObj = new Date()
var isToday = false
if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
isToday = true
}
// 星期几
var nWeek = objDate.getDay()
var cWeek = this.nStr1[nWeek]
// 数字表示周几顺应天朝周一开始的惯例
if (nWeek == 0) {
nWeek = 7
}
// 农历年
var year = i
var leap = this.leapMonth(i) // 闰哪个月
var isLeap = false
// 效验闰月
for (i = 1; i < 13 && offset > 0; i++) {
// 闰月
if (leap > 0 && i == (leap + 1) && isLeap == false) {
--i
isLeap = true;
temp = this.leapDays(year) // 计算农历闰月天数
} else {
temp = this.monthDays(year, i)// 计算农历普通月天数
}
// 解除闰月
if (isLeap == true && i == (leap + 1)) {
isLeap = false
}
offset -= temp
}
// 闰月导致数组下标重叠取反
if (offset == 0 && leap > 0 && i == leap + 1) {
if (isLeap) {
isLeap = false
} else {
isLeap = true;
--i
}
}
if (offset < 0) {
offset += temp;
--i
}
// 农历月
var month = i
// 农历日
var day = offset + 1
// 天干地支处理
var sm = m - 1
var gzY = this.toGanZhiYear(year)
// 当月的两个节气
// bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
// 依据12节气修正干支月
var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
if (d >= firstNode) {
gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
}
// 传入的日期的节气与否
var isTerm = false
var Term = null
if (firstNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 2]
}
if (secondNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 1]
}
// 日柱 当月一日与 1900/1/1 相差天数
var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
var gzD = this.toGanZhi(dayCyclical + d - 1)
// 该日期所属的星座
var astro = this.toAstro(m, d)
return {
'lYear': year,
'lMonth': month,
'lDay': day,
'Animal': this.getAnimal(year),
'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month),
'IDayCn': this.toChinaDay(day),
'cYear': y,
'cMonth': m,
'cDay': d,
'gzYear': gzY,
'gzMonth': gzM,
'gzDay': gzD,
'isToday': isToday,
'isLeap': isLeap,
'nWeek': nWeek,
'ncWeek': '\u661f\u671f' + cWeek,
'isTerm': isTerm,
'Term': Term,
'astro': astro
}
},
/**
* 传入农历年月日以及传入的月份是否闰月获得详细的公历农历object信息 <=>JSON
* @param y lunar year
* @param m lunar month
* @param d lunar day
* @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
* @return JSON object
* @eg:console.log(calendar.lunar2solar(1987,9,10));
*/
lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
var isLeapMonth = !!isLeapMonth
var leapOffset = 0
var leapMonth = this.leapMonth(y)
var leapDay = this.leapDays(y)
if (isLeapMonth && (leapMonth != m)) {
return -1
}// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) {
return -1
}// 超出了最大极限值
var day = this.monthDays(y, m)
var _day = day
// bugFix 2016-9-25
// if month is leap, _day use leapDays method
if (isLeapMonth) {
_day = this.leapDays(y, m)
}
if (y < 1900 || y > 2100 || d > _day) {
return -1
}// 参数合法性效验
// 计算农历的时间差
var offset = 0
for (var i = 1900; i < y; i++) {
offset += this.lYearDays(i)
}
var leap = 0;
var isAdd = false
for (var i = 1; i < m; i++) {
leap = this.leapMonth(y)
if (!isAdd) { // 处理闰月
if (leap <= i && leap > 0) {
offset += this.leapDays(y);
isAdd = true
}
}
offset += this.monthDays(y, i)
}
// 转换闰月农历 需补充该年闰月的前一个月的时差
if (isLeapMonth) {
offset += day
}
// 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
var calObj = new Date((offset + d - 31) * 86400000 + stmap)
var cY = calObj.getUTCFullYear()
var cM = calObj.getUTCMonth() + 1
var cD = calObj.getUTCDate()
return this.solar2lunar(cY, cM, cD)
}
}
export default calendar

@ -0,0 +1,170 @@
<template>
<view class="uni-calendar-item__weeks-box" :class="{
'uni-calendar-item--disable':weeks.disable,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
}"
@click="choiceDate(weeks)">
<view class="uni-calendar-item__weeks-box-item">
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
<text class="uni-calendar-item__weeks-box-text" :class="{
'uni-calendar-item--isDay-text': weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.date}}</text>
<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
}">今天</text>
<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.isDay?'今天': (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--extra':weeks.extraInfo.info,
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.extraInfo.info}}</text>
</view>
</view>
</template>
<script>
export default {
props: {
weeks: {
type: Object,
default () {
return {}
}
},
calendar: {
type: Object,
default: () => {
return {}
}
},
selected: {
type: Array,
default: () => {
return []
}
},
lunar: {
type: Boolean,
default: false
}
},
methods: {
choiceDate(weeks) {
this.$emit('change', weeks)
}
}
}
</script>
<style lang="scss" scoped>
.uni-calendar-item__weeks-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
}
.uni-calendar-item__weeks-box-text {
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar-item__weeks-lunar-text {
font-size: $uni-font-size-sm;
color: $uni-text-color;
}
.uni-calendar-item__weeks-box-item {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
width: 100rpx;
height: 100rpx;
}
.uni-calendar-item__weeks-box-circle {
position: absolute;
top: 5px;
right: 5px;
width: 8px;
height: 8px;
border-radius: 8px;
background-color: $uni-color-error;
}
.uni-calendar-item--disable {
background-color: rgba(249, 249, 249, $uni-opacity-disabled);
color: $uni-text-color-disable;
}
.uni-calendar-item--isDay-text {
color: $uni-color-primary;
}
.uni-calendar-item--isDay {
background-color: $uni-color-primary;
opacity: 0.8;
color: #fff;
}
.uni-calendar-item--extra {
color: $uni-color-error;
opacity: 0.8;
}
.uni-calendar-item--checked {
background-color: $uni-color-primary;
color: #fff;
opacity: 0.8;
}
.uni-calendar-item--multiple {
background-color: $uni-color-primary;
color: #fff;
opacity: 0.8;
}
.uni-calendar-item--before-checked {
background-color: #ff5a5f;
color: #fff;
}
.uni-calendar-item--after-checked {
background-color: #ff5a5f;
color: #fff;
}
</style>

@ -0,0 +1,512 @@
<template>
<view class="uni-calendar">
<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
<view class="uni-calendar__header-btn-box" @click="close">
<text class="uni-calendar__header-text uni-calendar--fixed-width">取消</text>
</view>
<view class="uni-calendar__header-btn-box" @click="confirm">
<text class="uni-calendar__header-text uni-calendar--fixed-width">确定</text>
</view>
</view>
<view class="uni-calendar__header">
<view class="uni-calendar__header-btn-box" @click.stop="pre">
<view class="uni-calendar__header-btn uni-calendar--left"></view>
</view>
<picker mode="date" :value="date" fields="month" @change="bindDateChange">
<text class="uni-calendar__header-text">{{ (nowDate.year||'') +'年'+( nowDate.month||'') +'月'}}</text>
</picker>
<view class="uni-calendar__header-btn-box" @click.stop="next">
<view class="uni-calendar__header-btn uni-calendar--right"></view>
</view>
<text class="uni-calendar__backtoday" @click="backtoday"></text>
</view>
<view class="uni-calendar__box">
<view v-if="showMonth" class="uni-calendar__box-bg">
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
</view>
<view class="uni-calendar__weeks">
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
</view>
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
<calendar-item :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></calendar-item>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import Calendar from './util.js';
import calendarItem from './uni-calendar-item.vue'
/**
* Calendar 日历
* @description 日历组件可以查看日期选择任意范围内的日期打点操作常用场景如酒店日期预订火车机票选择购买日期上下班打卡等
* @tutorial https://ext.dcloud.net.cn/plugin?id=56
* @property {String} date 自定义当前时间默认为今天
* @property {Boolean} lunar 显示农历
* @property {String} startDate 日期选择范围-开始日期
* @property {String} endDate 日期选择范围-结束日期
* @property {Boolean} range 范围选择
* @property {Boolean} insert = [true|false] 插入模式,默认为false
* @value true 弹窗模式
* @value false 插入模式
* @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
* @property {Array} selected 打点期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
* @property {Boolean} showMonth 是否选择月份为背景
* @event {Function} change 日期改变`insert :ture` 时生效
* @event {Function} confirm 确认选择`insert :false` 时生效
* @event {Function} monthSwitch 切换月份时触发
* @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
*/
export default {
components: {
calendarItem
},
props: {
date: {
type: String,
default: ''
},
selected: {
type: Array,
default () {
return []
}
},
lunar: {
type: Boolean,
default: false
},
startDate: {
type: String,
default: ''
},
endDate: {
type: String,
default: ''
},
range: {
type: Boolean,
default: false
},
insert: {
type: Boolean,
default: true
},
showMonth: {
type: Boolean,
default: true
},
clearDate: {
type: Boolean,
default: true
}
},
data() {
return {
show: false,
weeks: [],
calendar: {},
nowDate: '',
aniMaskShow: false
}
},
watch: {
date(newVal) {
this.cale.setDate(newVal)
this.init(this.cale.selectDate.fullDate)
},
startDate(val){
this.cale.resetSatrtDate(val)
},
endDate(val){
this.cale.resetEndDate(val)
},
selected(newVal) {
this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
this.weeks = this.cale.weeks
}
},
created() {
//
this.cale = new Calendar({
// date: new Date(),
selected: this.selected,
startDate: this.startDate,
endDate: this.endDate,
range: this.range,
})
//
this.cale.setDate(this.date)
this.init(this.cale.selectDate.fullDate)
// this.setDay
},
methods: {
// 穿
clean() {
this.aniMaskShow = false
this.$nextTick(() => {
setTimeout(() => {
this.show = false
this.$emit('close')
}, 300)
})
},
bindDateChange(e) {
const value = e.detail.value + '-1'
this.cale.setDate(value)
this.init(value)
},
/**
* 初始化日期显示
* @param {Object} date
*/
init(date) {
this.weeks = this.cale.weeks
this.nowDate = this.calendar = this.cale.getInfo(date)
},
/**
* 打开日历弹窗
*/
open() {
//
if (this.clearDate && !this.insert) {
this.cale.cleanMultipleStatus()
this.cale.setDate(this.date)
this.init(this.cale.selectDate.fullDate)
}
this.show = true
this.$nextTick(() => {
setTimeout(() => {
this.aniMaskShow = true
}, 50)
})
},
/**
* 关闭日历弹窗
*/
close() {
this.aniMaskShow = false
this.$nextTick(() => {
setTimeout(() => {
this.show = false
this.$emit('close')
}, 300)
})
},
/**
* 确认按钮
*/
confirm() {
this.setEmit('confirm')
this.close()
},
/**
* 变化触发
*/
change() {
if (!this.insert) return
this.setEmit('change')
},
/**
* 选择月份触发
*/
monthSwitch() {
let {
year,
month
} = this.nowDate
this.$emit('monthSwitch', {
year,
month: Number(month)
})
},
/**
* 派发事件
* @param {Object} name
*/
setEmit(name) {
let {
year,
month,
date,
fullDate,
lunar,
extraInfo
} = this.calendar
this.$emit(name, {
range: this.cale.multipleStatus,
year,
month,
date,
fulldate: fullDate,
lunar,
extraInfo: extraInfo || {}
})
},
/**
* 选择天触发
* @param {Object} weeks
*/
choiceDate(weeks) {
if (weeks.disable) return
this.calendar = weeks
//
this.cale.setMultiple(this.calendar.fullDate)
this.weeks = this.cale.weeks
this.change()
},
/**
* 回到今天
*/
backtoday() {
console.log(this.cale.getDate(new Date()).fullDate);
let date = this.cale.getDate(new Date()).fullDate
this.cale.setDate(date)
this.init(date)
this.change()
},
/**
* 上个月
*/
pre() {
const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
this.setDate(preDate)
this.monthSwitch()
},
/**
* 下个月
*/
next() {
const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
this.setDate(nextDate)
this.monthSwitch()
},
/**
* 设置日期
* @param {Object} date
*/
setDate(date) {
this.cale.setDate(date)
this.weeks = this.cale.weeks
this.nowDate = this.cale.getInfo(date)
}
}
}
</script>
<style lang="scss" scoped>
.uni-calendar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.uni-calendar__mask {
position: fixed;
bottom: 0;
top: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
transition-property: opacity;
transition-duration: 0.3s;
opacity: 0;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-calendar--mask-show {
opacity: 1
}
.uni-calendar--fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
transition-property: transform;
transition-duration: 0.3s;
transform: translateY(460px);
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-calendar--ani-show {
transform: translateY(0);
}
.uni-calendar__content {
background-color: #fff;
}
.uni-calendar__header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
height: 50px;
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar--fixed-top {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: space-between;
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 1px;
}
.uni-calendar--fixed-width {
width: 50px;
// padding: 0 15px;
}
.uni-calendar__backtoday {
position: absolute;
right: 0;
top: 25rpx;
padding: 0 5px;
padding-left: 10px;
height: 25px;
line-height: 25px;
font-size: 12px;
border-top-left-radius: 25px;
border-bottom-left-radius: 25px;
color: $uni-text-color;
background-color: $uni-bg-color-hover;
}
.uni-calendar__header-text {
text-align: center;
width: 100px;
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar__header-btn-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
}
.uni-calendar__header-btn {
width: 10px;
height: 10px;
border-left-color: $uni-text-color-placeholder;
border-left-style: solid;
border-left-width: 2px;
border-top-color: $uni-color-subtitle;
border-top-style: solid;
border-top-width: 2px;
}
.uni-calendar--left {
transform: rotate(-45deg);
}
.uni-calendar--right {
transform: rotate(135deg);
}
.uni-calendar__weeks {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-calendar__weeks-item {
flex: 1;
}
.uni-calendar__weeks-day {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
height: 45px;
border-bottom-color: #F5F5F5;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar__weeks-day-text {
font-size: 14px;
}
.uni-calendar__box {
position: relative;
}
.uni-calendar__box-bg {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.uni-calendar__box-bg-text {
font-size: 200px;
font-weight: bold;
color: $uni-text-color-grey;
opacity: 0.1;
text-align: center;
/* #ifndef APP-NVUE */
line-height: 1;
/* #endif */
}
</style>

@ -0,0 +1,357 @@
import CALENDAR from './calendar.js'
class Calendar {
constructor({
date,
selected,
startDate,
endDate,
range
} = {}) {
// 当前日期
this.date = this.getDate(new Date()) // 当前初入日期
// 打点信息
this.selected = selected || [];
// 范围开始
this.startDate = startDate
// 范围结束
this.endDate = endDate
this.range = range
// 多选状态
this.cleanMultipleStatus()
// 每周日期
this.weeks = {}
// this._getWeek(this.date.fullDate)
}
/**
* 设置日期
* @param {Object} date
*/
setDate(date) {
this.selectDate = this.getDate(date)
this._getWeek(this.selectDate.fullDate)
}
/**
* 清理多选状态
*/
cleanMultipleStatus() {
this.multipleStatus = {
before: '',
after: '',
data: []
}
}
/**
* 重置开始日期
*/
resetSatrtDate(startDate) {
// 范围开始
this.startDate = startDate
}
/**
* 重置结束日期
*/
resetEndDate(endDate) {
// 范围结束
this.endDate = endDate
}
/**
* 获取任意时间
*/
getDate(date, AddDayCount = 0, str = 'day') {
if (!date) {
date = new Date()
}
if (typeof date !== 'object') {
date = date.replace(/-/g, '/')
}
const dd = new Date(date)
switch (str) {
case 'day':
dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
break
case 'month':
if (dd.getDate() === 31) {
dd.setDate(dd.getDate() + AddDayCount)
} else {
dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
}
break
case 'year':
dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
break
}
const y = dd.getFullYear()
const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期不足10补0
const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号不足10补0
return {
fullDate: y + '-' + m + '-' + d,
year: y,
month: m,
date: d,
day: dd.getDay()
}
}
/**
* 获取上月剩余天数
*/
_getLastMonthDays(firstDay, full) {
let dateArr = []
for (let i = firstDay; i > 0; i--) {
const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
dateArr.push({
date: beforeDate,
month: full.month - 1,
lunar: this.getlunar(full.year, full.month - 1, beforeDate),
disable: true
})
}
return dateArr
}
/**
* 获取本月天数
*/
_currentMonthDys(dateData, full) {
let dateArr = []
let fullDate = this.date.fullDate
for (let i = 1; i <= dateData; i++) {
let isinfo = false
let nowDate = full.year + '-' + (full.month < 10 ?
full.month : full.month) + '-' + (i < 10 ?
'0' + i : i)
// 是否今天
let isDay = fullDate === nowDate
// 获取打点信息
let info = this.selected && this.selected.find((item) => {
if (this.dateEqual(nowDate, item.date)) {
return item
}
})
// 日期禁用
let disableBefore = true
let disableAfter = true
if (this.startDate) {
let dateCompBefore = this.dateCompare(this.startDate, fullDate)
disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
}
if (this.endDate) {
let dateCompAfter = this.dateCompare(fullDate, this.endDate)
disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
}
let multiples = this.multipleStatus.data
let checked = false
let multiplesStatus = -1
if (this.range) {
if (multiples) {
multiplesStatus = multiples.findIndex((item) => {
return this.dateEqual(item, nowDate)
})
}
if (multiplesStatus !== -1) {
checked = true
}
}
let data = {
fullDate: nowDate,
year: full.year,
date: i,
multiple: this.range ? checked : false,
beforeMultiple: this.dateEqual(this.multipleStatus.before, nowDate),
afterMultiple: this.dateEqual(this.multipleStatus.after, nowDate),
month: full.month,
lunar: this.getlunar(full.year, full.month, i),
disable: !disableBefore || !disableAfter,
isDay
}
if (info) {
data.extraInfo = info
}
dateArr.push(data)
}
return dateArr
}
/**
* 获取下月天数
*/
_getNextMonthDays(surplus, full) {
let dateArr = []
for (let i = 1; i < surplus + 1; i++) {
dateArr.push({
date: i,
month: Number(full.month) + 1,
lunar: this.getlunar(full.year, Number(full.month) + 1, i),
disable: true
})
}
return dateArr
}
/**
* 获取当前日期详情
* @param {Object} date
*/
getInfo(date) {
if (!date) {
date = new Date()
}
const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
return dateInfo
}
/**
* 比较时间大小
*/
dateCompare(startDate, endDate) {
// 计算截止时间
startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
// 计算详细项的截止时间
endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
if (startDate <= endDate) {
return true
} else {
return false
}
}
/**
* 比较时间是否相等
*/
dateEqual(before, after) {
// 计算截止时间
before = new Date(before.replace('-', '/').replace('-', '/'))
// 计算详细项的截止时间
after = new Date(after.replace('-', '/').replace('-', '/'))
if (before.getTime() - after.getTime() === 0) {
return true
} else {
return false
}
}
/**
* 获取日期范围内所有日期
* @param {Object} begin
* @param {Object} end
*/
geDateAll(begin, end) {
var arr = []
var ab = begin.split('-')
var ae = end.split('-')
var db = new Date()
db.setFullYear(ab[0], ab[1] - 1, ab[2])
var de = new Date()
de.setFullYear(ae[0], ae[1] - 1, ae[2])
var unixDb = db.getTime() - 24 * 60 * 60 * 1000
var unixDe = de.getTime() - 24 * 60 * 60 * 1000
for (var k = unixDb; k <= unixDe;) {
k = k + 24 * 60 * 60 * 1000
arr.push(this.getDate(new Date(parseInt(k))).fullDate)
}
return arr
}
/**
* 计算阴历日期显示
*/
getlunar(year, month, date) {
return CALENDAR.solar2lunar(year, month, date)
}
/**
* 设置打点
*/
setSelectInfo(data, value) {
this.selected = value
this._getWeek(data)
}
/**
* 获取多选状态
*/
setMultiple(fullDate) {
let {
before,
after
} = this.multipleStatus
if (!this.range) return
if (before && after) {
this.multipleStatus.before = ''
this.multipleStatus.after = ''
this.multipleStatus.data = []
} else {
if (!before) {
this.multipleStatus.before = fullDate
} else {
this.multipleStatus.after = fullDate
if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
} else {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
}
}
}
this._getWeek(fullDate)
}
/**
* 获取每周数据
* @param {Object} dateData
*/
_getWeek(dateData) {
const {
fullDate,
year,
month,
date,
day
} = this.getDate(dateData)
let firstDay = new Date(year, month - 1, 1).getDay()
let currentDay = new Date(year, month, 0).getDate()
let dates = {
lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
nextMonthDays: [], // 下个月开始几天
weeks: []
}
let canlender = []
const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
let weeks = {}
// 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
for (let i = 0; i < canlender.length; i++) {
if (i % 7 === 0) {
weeks[parseInt(i / 7)] = new Array(7)
}
weeks[parseInt(i / 7)][i % 7] = canlender[i]
}
this.canlender = canlender
this.weeks = weeks
}
//静态方法
// static init(date) {
// if (!this.instance) {
// this.instance = new Calendar(date);
// }
// return this.instance;
// }
}
export default Calendar

@ -0,0 +1,134 @@
<template>
<scroll-view class="wuc-tab" :class="tabClass" :style="tabStyle" scroll-with-animation scroll-x :scroll-left="scrollLeft">
<div v-if="!textFlex">
<div class="wuc-tab-item" :class="[index === tabCur ? selectClass + ' cur':'']" v-for="(item,index) in tabList" :key="index" :id="index" @tap="tabSelect(index,$event)">
<text :class="item.icon"></text>
<span>{{item.name}}</span>
</div>
</div>
<div class="flex text-center" v-if="textFlex">
<div class="wuc-tab-item flex-sub" :class="index === tabCur ? selectClass + ' cur':''" v-for="(item,index) in tabList" :key="index" :id="index" @tap="tabSelect(index,$event)">
<text :class="item.icon"></text>
<span>{{item.name}}</span>
</div>
</div>
</scroll-view>
</template>
<script>
export default {
name: 'wuc-tab',
data() {
return {};
},
props: {
tabList: {
type: Array,
default() {
return [];
}
},
tabCur: {
type: Number,
default() {
return 0;
}
},
tabClass: {
type: String,
default() {
return '';
}
},
tabStyle: {
type: String,
default() {
return '';
}
},
textFlex: {
type: Boolean,
default() {
return false;
}
},
selectClass: {
type: String,
default() {
return 'text-blue';
}
}
},
methods: {
tabSelect(index, e) {
if (this.currentTab === index) return false;
this.$emit('update:tabCur', index);
this.$emit('changeTab', this.tabList[index]);
}
},
computed: {
scrollLeft() {
return (this.tabCur - 1) * 60;
}
}
};
</script>
<style>
div,
scroll-view,
swiper {
box-sizing: border-box;
}
.wuc-tab {
white-space: nowrap;
}
.wuc-tab-item {
height: 90rpx;
display: inline-block;
line-height: 90rpx;
margin: 0 10upx;
padding: 0 20upx;
}
.wuc-tab-item.cur {
color: #40A2ED;
background-color: #fff;
}
.wuc-tab.fixed {
position: fixed;
width: 100%;
top: 0;
z-index: 1024;
box-shadow: 0 1upx 6upx rgba(0, 0, 0, 0.1);
}
.flex {
display: flex;
}
.text-center {
text-align: center;
}
.flex-sub {
flex: 1;
}
.text-blue{
color:#40A2ED;
}
.text-white{
color:#ffffff;
}
.bg-white{
background-color: #ffffff;
}
.bg-blue{
background-color: #40A2ED;
}
.text-orange{
color: #f37b1d
}
.text-xl {
font-size: 36upx;
}
</style>

@ -0,0 +1,582 @@
<template>
<view class="body">
<!-- <view class="topLine" :style="{height: topBar+'px'}"></view> -->
<view class="nav row_align_center" id="nav">
<li style="color: #fff;z-index: 999;" :class="['iconfont icon-zuojiantou back']" @click="gotoBack()"></li>
</view>
<view class="top_head">
<view class="text_des">
<text class="month_num">{{ nowTime.month }}</text>
<text class="month_text"></text>
<text class="month_year">{{ nowTime.year }}</text>
<text class="point">.</text>
<text class="title">财务报告</text>
</view>
<view class="top_desc">
<view class="text-gray">结余</view>
<view class="remaining">{{ myWallet.remaining }}</view>
<view class="row head_block">
<view class="flex_1">
<text class="text-gray">支出</text>
<text class="text_green">{{ myWallet.expend }}</text>
</view>
<view class="flex_1">
<text class="text-gray">收入</text>
<text class="income">{{ myWallet.income }}</text>
</view>
</view>
</view>
</view>
<view class="main">
<view class="row_block">
<view class="the_title" style="justify-content: space-between;">
<view class="left_title">
<view class="title_icon"></view>
<text class="margin_stand-samll font-big wide">历史趋势</text>
</view>
<view class="right_btn">
<view v-for="(item, index) in historyBtn" :key="index" :class="item.state ? 'active_btn' : ''"
@click="changeHistoryBtn(item.type)">{{ item.name }}</view>
</view>
</view>
<view class="charts-box" style="height: 200px;">
<qiun-data-charts type="line" canvasId="finance_a" :canvas2d="isCanvas2d" :resshow="delayload"
:opts="{ xAxis: { itemCount: 12, disableGrid: true }, yAxis: { disableGrid: true, data: [{ disabled: true }] } }"
:chartData="historyData" />
</view>
</view>
<view class="row_block">
<view class="the_title">
<view class="title_icon"></view>
<text class="margin_stand-samll font-big wide">钱都去哪了</text>
</view>
<view v-if="delayload" class="charts-box">
<qiun-data-charts type="ring" canvasId="finance_b" :canvas2d="isCanvas2d" :resshow="delayload"
:opts="{ padding: [15, 0, 4, 0], legend: { position: 'bottom' }, title: { name: expendCount }, subtitle: { name: '支出', fontSize: '20' } }"
:chartData="expendDetail" />
</view>
<view class="the_title">
<text class="margin_stand-samll font-middle wide">支出单笔最贵</text>
</view>
<view class="extend_rank">
<view class="rank_item" v-for="(item, index) in extendRank" :key="index">
<image :src="getImage(index)" mode="widthFix"></image>
<text class="name">{{ item.name }}</text>
<text class="desc">{{ item.desc }}</text>
<text class="text_green money">{{ item.money }}</text>
</view>
</view>
</view>
<view class="row_block">
<view class="the_title">
<view class="title_icon"></view>
<text class="margin_stand-samll font-big wide">{{ nowTime.month }}月明细</text>
</view>
<view class="detail_list">
<view v-for="(item, index) in detail_list" :key="index" class="detail_item">
<view>
<view class="font-middle">{{ item.date }}</view>
<view class="font-small">{{ item.time }}</view>
</view>
<view class="icon">
<li :class="['iconfont', item.type == 'income' ? 'icon-income' : 'icon-expend']"></li>
</view>
<view class="right_content">
<view class="money">{{ item.type == 'income' ? '+' : '-' }}{{ item.money }}</view>
<view class="text-gray font-middle">{{ item.desc }}</view>
</view>
</view>
</view>
</view>
<view class="end_block">
<view class="the_title" style="margin-bottom: 40rpx;">
<view class="title_icon"></view>
<text class="margin_stand-samll font-big wide">我的支出水平</text>
</view>
<view class="level_bar">
<view v-for="(item, index) in extend_level_bar" :key="index" :style="{ width: item.width }"
:class="item.state ? 'text_green font-middle' : ''">{{ item.name }}</view>
</view>
<view class="level_bar">
<view v-for="(item, index) in extend_level_bar" :key="index" :style="{ width: item.width }"
:class="item.state ? 'active_bar' : 'default_bar'"></view>
</view>
<view class="level_bar">
<view v-for="(item, index) in extend_level_bar" :key="index" :style="{ width: item.width }"
:class="item.state ? 'text_green font-middle' : ''">{{ item.range }}</view>
</view>
<view class="extend_message">
<li style="color: #ccc;" :class="['iconfont icon-message']"></li>
<view>
我的支出水平已超过
<text>{{ extend_morethan }}</text>
的乡镇居民
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import ProgressBar from "../../components/progress-bar/progress-bar.vue"
import dataOne from '../../static/json/finance/1.json';
import expendDetail from '../../static/json/finance/2.json';
let _now = new Date();
let now_time = {};
now_time.year = _now.getFullYear()
now_time.month = _now.getMonth() + 1
now_time.day = _now.getDay()
export default {
components: {
ProgressBar
},
data() {
return {
info: '大便超人', //
scrollHeight: "600px", //
isCanvas2d: this.$Config.ISCANVAS2D,
historyData: {},
dataOne,
expendDetail,
expendCount: 0,
delayload: false,
nowTime: {
year: now_time.year,
month: now_time.month,
day: now_time.day
},
historyBtn: [{
name: "支出",
state: 1,
type: "expend"
},
{
name: "收入",
state: 0,
type: "income"
},
{
name: "结余",
state: 0,
type: "remaining"
},
],
myWallet: {
remaining: 3000.34,
expend: 5240.32,
income: 8240.66
},
extendRank: [{
name: "腐败聚会",
desc: now_time.month + "月6日12:34-跨界空间轰趴",
money: "422.12"
},
{
name: "沐浴按摩",
desc: now_time.month + "月12日21:34-乔杉沐浴城",
money: "318.00"
},
{
name: "食品酒水",
desc: now_time.month + "月1日21:34-school酒馆",
money: "289.50"
},
],
extend_level_bar: [
{ name: "低消费", range: "<2000元", width: "20%" },
{ name: "中间消费", range: "2000-5000元", width: "35%" },
{ name: "较高消费", range: "5000-8000元", width: "25%", state: 1 },
{ name: "高消费", range: ">8000元", width: "20%" },
],
extend_morethan: "68%",
detail_list: [
{ date: now_time.month + "-01", time: "11:01", "type": "extend", money: "10.00", desc: "银行卡转出" },
{ date: now_time.month + "-01", time: "13:45", "type": "income", money: "18.00", desc: "银行卡收入" },
{ date: now_time.month + "-02", time: "06:21", "type": "extend", money: "123.45", desc: "信用卡转出" },
{ date: now_time.month + "-03", time: "07:38", "type": "income", money: "23.00", desc: "银行卡收入" },
{ date: now_time.month + "-08", time: "16:28", "type": "extend", money: "23.56", desc: "信用卡转出" },
{ date: now_time.month + "-09", time: "15:25", "type": "income", money: "850.12", desc: "银行卡收入" },
{ date: now_time.month + "-09", time: "18:52", "type": "income", money: "1.88", desc: "银行卡收入" },
{ date: now_time.month + "-11", time: "21:12", "type": "extend", money: "220.21", desc: "银行卡转出" },
{ date: now_time.month + "-12", time: "13:08", "type": "income", money: "32.28", desc: "银行卡收入" },
{ date: now_time.month + "-12", time: "12:41", "type": "extend", money: "122.12", desc: "信用卡转出" },
{ date: now_time.month + "-13", time: "17:21", "type": "income", money: "10.00", desc: "银行卡收入" },
]
};
},
watch: {
"historyBtn": {
deep: true,
handler: function (newVal, oldVal) {
this.filterHistoryData();
}
}
},
methods: {
async getData() {
uni.showLoading();
this.filterHistoryData();
for (let i = 0; i < this.expendDetail.series.length; i++) {
this.expendDetail.series[i].format = "pieDemo"
}
let length = this.expendDetail.series[0].data.length
for (let i = 0; i < length; i++) {
this.expendCount += this.expendDetail.series[0].data[i].value
}
await setTimeout(() => {
this.delayload = true;
uni.hideLoading();
}, 1000)
},
changeHistoryBtn(type) {
for (let i = 0; i < this.historyBtn.length; i++) {
if (this.historyBtn[i].type == type) {
this.historyBtn[i].state = 1
} else {
this.historyBtn[i].state = 0
}
}
},
filterHistoryData() {
let type = this.historyBtn.filter(x => x.state == 1)[0].type;
switch (type) {
case "expend":
this.historyData = this.dataOne.expend;
break;
case "income":
this.historyData = this.dataOne.income;
break;
case "remaining":
this.historyData = this.dataOne.remaining;
break;
}
},
gotoBack() {
this.$Common.navigateBack("/index/index");
},
getImage(index) {
switch (index) {
case 0:
return "https://s1.ax1x.com/2023/03/31/ppRYrfP.png";
break;
case 1:
return "https://s1.ax1x.com/2023/03/31/ppRYySf.png";
break;
case 2:
return "https://s1.ax1x.com/2023/03/31/ppRY6l8.png";
break;
}
}
},
onReady() {
//#ifndef H5
uni.showShareMenu();
//#endif
this.getData()
}
}
</script>
<style scoped lang="scss">
.body {
height: 100%;
background-color: #560594;
margin: 0;
padding-bottom: 20rpx;
li {
list-style-type: none;
}
.nav {
position: fixed;
top: 50rpx;
left: 20rpx;
}
.text_green {
color: #4ECDB6;
}
.main {
width: 100%;
padding: 0 10rpx;
box-sizing: border-box;
margin-top: 20rpx;
.detail_list {
height: 700rpx;
overflow: auto;
color: #9E9E9E;
.detail_item {
display: flex;
margin: 20rpx 0;
align-items: center;
.icon {
width: 30%;
text-align: center;
li {
font-size: 80rpx;
}
}
.right_content {
width: 50%;
text-align: center;
}
.icon-income {
color: #4AABF9;
}
.icon-expend {
color: #E45521;
}
.money {
color: #000;
}
}
}
.extend_message {
margin-top: 20rpx;
color: #ccc;
display: flex;
text {
color: #ff9900;
}
}
.level_bar {
width: 100%;
height: 40rpx;
border-radius: 40rpx;
overflow: hidden;
display: flex;
color: #ccc;
font-size: 20rpx;
text-align: right;
line-height: 40rpx;
view {
border-right: 2rpx solid #fff;
position: relative;
}
.name {
position: absolute;
top: -30rpx;
right: -40rpx;
}
.range {
position: absolute;
bottom: 30rpx;
right: -40rpx;
}
.default_bar {
background-color: #A0DFCD;
}
.active_bar {
background-color: #02AE7A;
}
}
.right_btn {
float: right;
display: flex;
color: #ccc;
font-size: 22rpx;
view {
line-height: 50rpx;
height: 50rpx;
margin: 0 20rpx;
}
.active_btn {
padding: 0rpx 20rpx;
border: 1px solid #ccc;
border-radius: 40rpx;
}
}
.end_block {
width: 100%;
box-sizing: border-box;
background-color: #fff;
border-radius: 12rpx;
position: relative;
padding: 20rpx;
}
.row_block {
width: 100%;
box-sizing: border-box;
background-color: #fff;
border-radius: 12rpx;
position: relative;
padding: 20rpx;
&::after {
content: "";
height: 0px;
width: 92%;
position: absolute;
transform: translateX(-50%);
left: 50%;
bottom: 0;
border-top: 1px dashed #ccc;
}
}
.the_title {
display: flex;
align-items: center;
.left_title {
display: flex;
align-items: center;
}
.title_icon {
background-color: #7E7E7E;
height: 40rpx;
width: 10rpx;
border-radius: 10rpx;
margin-right: 20rpx;
font-size: 16px;
font-weight: 600;
}
}
.extend_rank {
width: 100%;
background-color: #F5F5F5;
box-sizing: border-box;
padding: 10rpx;
.rank_item {
width: 100%;
margin: 20rpx 0;
box-sizing: border-box;
display: flex;
font-size: 26rpx;
justify-content: space-between;
align-items: center;
image {
width: 10%;
}
text {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
display: block;
}
.name {
margin: 0 10rpx;
color: #7D7D7D;
width: 20%;
}
.desc {
width: 50%;
color: #ccc;
}
.money {
width: 20%;
text-align: right;
}
}
}
}
.top_head {
height: 435rpx;
width: 100%;
padding: 110rpx 10rpx 0rpx 10rpx;
background: url("https://img1.qunarzz.com/travel/d3/1704/db/34de73c353d44db5.jpg_r_640x426x70_53f464ca.jpg") no-repeat center 0px;
background-size: 100% 100%;
box-sizing: border-box;
.top_desc {
width: 100%;
border-radius: 20rpx;
background-color: #fff;
margin-top: 20rpx;
padding: 20rpx;
box-sizing: border-box;
.text-gray {
font-size: 28rpx;
color: #ccc;
margin-right: 10rpx;
}
.remaining {
font-size: 46rpx;
}
.flex_1 {
flex: 1;
}
.head_block {
margin-top: 20rpx;
.income {
color: #E34B5E;
}
}
}
.text_des {
height: 100rpx;
color: #fff;
font-weight: 900;
position: relative;
margin-left: 60rpx;
text {
display: inline-block;
height: 100%;
}
.month_num {
font-size: 90rpx;
}
.month_text {
font-size: 56rpx;
}
.month_year {
font-size: 22rpx;
position: absolute;
left: 60rpx;
top: 20rpx;
}
.point {
font-size: 40rpx;
}
.title {
font-size: 40rpx;
}
}
}
}
</style>

@ -0,0 +1,342 @@
<template>
<view class="window">
<!-- #ifndef H5 -->
<view class="topLine" :style="{ height: topBar + 'px' }"></view>
<!-- #endif -->
<view class="nav row_align_center" id="nav">
<li :class="['iconfont icon-zuojiantou back']" @click="gotoBack()"></li>
<text class="title">{{ title ? title : '' }}</text>
<li class="iconfont icon-zuojiantou back hidden"></li>
</view>
<view class="row_align_center head" id="head">
<!-- 日期下拉列表 -->
<drop-down ref="caleDrop" @tap="changDrop(1)" @changeItem="changeTime" :list="timeArray" :contentTop="top"
selectWidth="260rpx" contentLeft="0"></drop-down>
<!-- 日历选择日期 -->
<view v-if="showCalendar"
:class="['dropdown-item__selected', listWidth != '150rpx' ? 'dropdown-item__right' : 'dropdown-item__left']"
@click="openCalendar" class="calendar_drag">
<view class="selected__name">{{ nowDate }}</view>
<li class="iconfont icon-calendar" style="margin-left: 10rpx;"></li>
</view>
<!-- 公司区域下拉列表 -->
<drop-down ref="companyDrop" @tap="changDrop(2)" @changeItem="changeLocation" :list="locationArray"
:contentTop="top" contentRight="10" :selectWidth="showCalendar ? '200rpx' : '300rpx'" listWidth="75%">
</drop-down>
</view>
<uni-calendar ref="calendar" :insert="false" :start-date="startDate" :end-date="endDate" :clearDate="false"
@confirm="confirm">
</uni-calendar>
<!--滑动列表头-->
<wuc-tab id="wuctab" :tab-list="tabList" :tabCur.sync="tabCur" tab-class="text-center text-white bg-blue"
select-class="text-white"></wuc-tab>
<!--主体内容-->
<view class="data_body" :style="{ height: scrollHeight }">
<view v-if="tabCur == 0">
<wechat :scrollHeight="scrollHeight" />
</view>
<view v-else-if="tabCur == 1">
<user-operate :scrollHeight="scrollHeight" />
</view>
<view v-else-if="tabCur == 2">
<user-healthy :scrollHeight="scrollHeight" />
</view>
<view v-else-if="tabCur == 3">
<user-server :scrollHeight="scrollHeight"></user-server>
</view>
</view>
<!--水印-->
<view class="water-mark-mask row_wrap" :style="{ height: scrollHeight }">
<text class="container" v-for="(count, index) in 10" :key="index">{{ info.name }}</text>
</view>
</view>
</template>
<script>
import Wechat from "../../components/data-center/wechat.vue"
import UserOperate from "../../components/data-center/user-operate.vue"
import UserHealthy from "../../components/data-center/user-healthy.vue"
import UserServer from "../../components/data-center/user-server.vue"
export default {
components: {
WucTab: resolve => require(['@/components/wuc-tab/wuc-tab.vue'], resolve),
DropDown: resolve => require(['@/components/drop-down/drop-down.vue'], resolve),
UniCalendar: resolve => require(['@/components/uni-calendar/uni-calendar.vue'], resolve),
Wechat,
UserOperate,
UserHealthy,
UserServer,
},
data() {
return {
tabList: this.$Config.TABLIST, //
timeArray: this.$Config.TIMEARRAY, //
info: '大便超人', //
title: "数据报表中心", //
showDataTime: "today", //
tabCur: 0, //
topBar: 17, //
top: '180', //
scrollHeight: "100%", //
nowDate: this.$Common.getNowDate(), //
endDate: this.$Common.getNowDate(), //
startDate: this.$Common.getPreMonth(this.$Common.getNowDate()), //,
showCalendar: false,
};
},
computed: {
locationArray() {
return [{
value: "GDBJ-ENTRY-1",
text: "天猫"
}, {
value: "GDBJ-ENTRY-201",
text: "京东"
}];
}
},
methods: {
gotoBack() {
this.$Common.navigateBack("/index/index");
},
changDrop(index) {
if (index == 1 && this.$refs.companyDrop.showList) {
this.$refs.companyDrop.closePopup()
} else if (index == 2 && this.$refs.caleDrop.showList) {
this.$refs.caleDrop.closePopup()
}
},
//
openCalendar() {
this.$refs.calendar.open();
},
//
confirm(e) {
if (this.nowDate != e.fulldate || !this.showCalendar) {
this.showCalendar = true;
this.$refs.caleDrop.selectAuto();
this.nowDate = e.fulldate;
this.showDataTime = e.fulldate.replace(/-/g, "");
this.$Common.tipMsg("当前时间:" + this.showDataTime)
}
},
//
changeTime(e) {
if (e.value == "auto") {
this.openCalendar();
} else if (this.showDataTime != e.value) {
this.showDataTime = e.value;
this.showCalendar = false;
this.$Common.tipMsg("当前时间:" + this.showDataTime)
}
},
changeLocation(e) {
this.$Common.tipMsg("当前选中平台:" + e.text)
},
//
async getTelephoneInfo() {
var telephoneInfo = await this.$Common.getTelephoneInfo();
let hasHeight = 0;
if (telephoneInfo.top >= 40) {
this.top = telephoneInfo.statusBarHeight * 2 + 150;
this.topBar = telephoneInfo.statusBarHeight;
}
//
const query = wx.createSelectorQuery();
query.select('#nav').boundingClientRect();
query.select('#head').boundingClientRect();
query.select('#wuctab').boundingClientRect();
query.exec(res => {
res.map((item, index) => {
hasHeight += item.height;
})
this.scrollHeight = (telephoneInfo.screenHeight - hasHeight - this.topBar) + 'px';
})
},
getH5Info() {
uni.getSystemInfo({
success: e => {
let hasHeight = 0;
let element = wx.createSelectorQuery().in(this);
element.select('#nav').boundingClientRect();
element.select('#head').boundingClientRect();
element.select('#wuctab').boundingClientRect();
element.exec(res => {
res.map((item, index) => {
hasHeight += item.height;
})
this.scrollHeight = (e.screenHeight - hasHeight) + 'px';
})
},
fail: (err) => {
reject(err);
}
})
}
},
onReady() {
//#ifndef H5
uni.showShareMenu();
this.getTelephoneInfo();
//#endif
//#ifdef H5
this.getH5Info();
//#endif
}
};
</script>
<style lang="scss">
page,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
li {
list-style-type: none;
}
.window {
height: 100vh;
overflow: hidden;
.topLine {
background-color: #40A2ED;
width: 100%;
}
scroll-view {
box-sizing: border-box;
}
.swiper {
box-sizing: border-box;
}
.nav {
background-image: url(http://photo.gdbjyy.cn/image/BCAI/top_bg.jpg);
background-size: 100% 100%;
.back {
font-size: 54rpx;
padding: 20rpx 14rpx 15rpx 14rpx;
color: #fff;
}
.title {
color: #fff;
font-size: 30rpx;
flex: 1;
text-align: center;
}
.hidden {
visibility: hidden;
}
}
.head {
padding: 0 16rpx 14rpx 16rpx;
color: #fff;
background-color: #40A2ED;
justify-content: space-between;
font-size: 26rpx !important;
.calendar_drag {
width: 340rpx;
display: flex;
justify-content: center;
align-items: center;
.calendar_name {
margin-right: 10rpx;
}
.icon-calendar {
font-size: 26rpx;
margin-top: 4rpx;
}
}
}
.data_body {
overflow: auto;
text-align: center;
color: #333333;
background-repeat: repeat;
background-color: #ffffff;
position: relative;
.item {
padding: 0 20rpx;
margin-bottom: 20rpx;
.name {
font-weight: 600;
font-size: 36rpx;
}
.operate {
view {
padding: 5rpx 12rpx;
color: #fff;
}
.bg-blue {
background-color: #40A2ED;
}
.bg-yellow {
background-color: #FFC300;
}
}
.tip {
margin-bottom: 30rpx;
.update {
color: #C4100A;
margin-left: auto;
font-size: 30rpx;
}
}
}
.cry {
font-size: 96rpx;
margin-bottom: 10rpx;
}
}
}
.water-mark-mask {
width: 100%;
position: fixed;
left: 0;
bottom: 0;
z-index: 1000;
justify-content: space-between;
pointer-events: none; //
flex: 1;
overflow: hidden;
text {
width: 50%;
color: #909399;
opacity: 0.25;
transform: rotate(-15deg);
}
}
.histogram {
height: 100%;
width: 100%;
canvas {
margin-top: 40rpx;
}
}
</style>

@ -0,0 +1,257 @@
<template>
<view class="body window">
<view class="topLine" :style="{ height: topBar + 'px' }"></view>
<view class="nav row_align_center" id="nav">
<li :class="['iconfont icon-zuojiantou back']" @click="gotoBack()"></li>
<text class="title">{{ title ? title : '' }}</text>
<li class="iconfont icon-zuojiantou back hidden"></li>
</view>
<view class="data_body">
<scroll-view class="scroll_list" scroll-y :style="{ height: scrollHeight }">
<!-- 教学科研情况 -->
<view class="view_block">
<view class="title">教学科研情况</view>
<progress-bar :content="RankData" @updateRanking="updateRanking"></progress-bar>
</view>
<!-- 学历分布状况 -->
<view class="view_block">
<view class="title">学历分布状况
<text class="font-small" style="color: #ccc;">(教职工)</text>
</view>
<view class="charts-box" style="height: 300px;">
<qiun-data-charts type="rose" :chartData="ProductRateData" canvasId="school_a"
:canvas2d="isCanvas2d" :resshow="delayload" />
</view>
</view>
<!-- 学业成绩 -->
<view class="view_block">
<view class="title">学业成绩分布图
<text class="font-small" style="color: #ccc;">(班级)</text>
</view>
<view class="charts-box" style="height: 300px;">
<qiun-data-charts type="radar" :chartData="RadarModel" background="none" canvasId="school_b"
:animation="false" :canvas2d="isCanvas2d" :resshow="delayload" />
</view>
</view>
<!-- 图书借阅情况 -->
<view class="view_block">
<view class="title">图书借阅情况</view>
<view class="charts-box" style="height: 300px;">
<qiun-data-charts type="line" canvasId="school_c" :canvas2d="isCanvas2d" :resshow="delayload"
:ontouch="true"
:opts="{ enableScroll: true, xAxis: { scrollShow: true, itemCount: 4, disableGrid: true }, series: { style: 'curve' } }"
:chartData="friendTrand" />
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import ProgressBar from "../../components/progress-bar/progress-bar.vue"
import RankData from '../../static/json/school/1.json';
import ProductRateData from '../../static/json/school/2.json';
import RadarModel from '../../static/json/school/3.json';
import friendTrand from '../../static/json/school/4.json';
export default {
components: {
ProgressBar
},
data() {
return {
info: "大便超人", //
title: "智慧教育报表中心", //
showDataTime: "today", //
tabCur: 0, //
topBar: 17, //
top: '180', //
scrollHeight: "600px", //
friendTrand,
RankData,
ProductRateData,
RadarModel,
isCanvas2d: this.$Config.ISCANVAS2D,
delayload: false, //
};
},
computed: {
locationArray() {
return [{ value: "GDBJ-ENTRY-1", text: "天猫" }, { value: "GDBJ-ENTRY-201", text: "京东" }];
}
},
methods: {
async getData() {
uni.showLoading();
await setTimeout(() => {
this.delayload = true;
uni.hideLoading();
}, 1000)
},
gotoBack() {
this.$Common.navigateBack("/index/index");
},
//
async getTelephoneInfo() {
var telephoneInfo = await this.$Common.getTelephoneInfo();
let hasHeight = 0;
if (telephoneInfo.top >= 40) {
this.top = telephoneInfo.statusBarHeight * 2 + 150;
this.topBar = telephoneInfo.statusBarHeight;
}
//
const query = wx.createSelectorQuery();
query.select('#nav').boundingClientRect();
query.exec(res => {
res.map((item, index) => {
hasHeight += item.height;
})
this.scrollHeight = (telephoneInfo.screenHeight - hasHeight - this.topBar) + 'px';
})
},
updateRanking(nVal) {
this.RankData = nVal;
},
},
onLoad() {
//#ifndef H5
uni.showShareMenu();
//#endif
this.getData()
this.getTelephoneInfo();
}
}
</script>
<style scoped lang="scss">
.body {
height: 100vh;
margin: 0;
padding: 0 20rpx;
font-family: "montserrat";
background-image: linear-gradient(125deg, #CB9FFE, #5894F7, #ABCDFA, #74A3F6, #CB9FFE);
background-size: 400%;
animation: bganimation 15s infinite;
}
li {
list-style-type: none;
}
page,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.window {
height: 100vh;
overflow: hidden;
.topLine {
width: 100%;
}
scroll-view {
box-sizing: border-box;
}
.swiper {
box-sizing: border-box;
}
.nav {
background-size: 100% 100%;
.back {
font-size: 54rpx;
padding: 20rpx 14rpx 15rpx 14rpx;
color: #fff;
}
.title {
color: #fff;
font-size: 30rpx;
flex: 1;
text-align: center;
}
.hidden {
visibility: hidden;
}
}
.head {
padding: 0 16rpx 14rpx 16rpx;
color: #fff;
background-color: #40A2ED;
justify-content: space-between;
font-size: 26rpx !important;
.calendar_drag {
width: 340rpx;
display: flex;
justify-content: center;
align-items: center;
.calendar_name {
margin-right: 10rpx;
}
.icon-calendar {
font-size: 26rpx;
margin-top: 4rpx;
}
}
}
.data_body {
overflow: auto;
text-align: center;
color: #333333;
background-repeat: repeat;
height: 100%;
.scroll_list {
height: 100%;
.view_block {
background-color: #fff;
padding: 16rpx 20rpx 10rpx 20rpx;
border-radius: 20rpx;
margin-bottom: 40rpx;
.title {
text-align: left;
margin-bottom: 30rpx;
font-size: 30rpx;
}
.trend_title {
text-align: right;
font-size: 22rpx;
color: #ff9900;
margin-top: 50rpx;
}
}
}
}
}
@keyframes bganimation {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
</style>

@ -0,0 +1,760 @@
<template>
<view class="body">
<view class="nav row_align_center" id="nav">
<li style="z-index: 999;font-size: 50rpx;" :class="['iconfont icon-zuojiantou back']" @click="gotoBack()">
</li>
</view>
<view class="head">
<view class="title">运动报告</view>
<view class="customer_img">
<!-- <open-data type="userAvatarUrl" class="img"></open-data> -->
<image class="img" src="https://s1.ax1x.com/2022/11/16/zZUoK1.jpg" mode="widthFix"></image>
</view>
</view>
<view class="score_view">
<view class="title">本次评分</view>
<view class="detail">
<view class="socre">98</view>
<li :class="['iconfont icon-up text-green']" @click="gotoBack()"></li>
<view class="up_socre">0.4</view>
</view>
</view>
<view class="census_view">
<view class="left">
<view class="text_gray small_text">消耗(千卡)</view>
<view class="middle_text text_wide_900">165</view>
</view>
<view class="right">
<view class="text_gray small_text">心率主要集中在</view>
<view style="font-size: 30rpx;">燃烧脂肪</view>
</view>
</view>
<view class="census_view">
<view class="left">
<view class="text_gray small_text">时长(分钟)</view>
<view class="middle_text text_wide_900">75</view>
</view>
<view class="center">
<view class="text_gray small_text">累计打卡()</view>
<view class="middle_text text_wide_900">24</view>
</view>
<view class="right">
<view class="text_gray small_text">平均心率(/分钟)</view>
<view class="middle_text text_wide_900">98</view>
</view>
</view>
<view class="consume_view">
<view class="wrap"><span class="consume_tip">身体消耗</span></view>
<li :class="['iconfont icon-niunai consume_icon']"></li>
<view class="desc">
<view class="small_text">约消耗</view>
<view class="text_wide_900"><text class="left">1000</text><text class="right">毫升牛奶</text></view>
</view>
</view>
<view class="heart_rate_view">
<view class="left">
<li :class="['iconfont icon-zhexiantu']"></li>
<text class="title">心率变化曲线</text>
</view>
<view class="right text_gray">心率变化</view>
</view>
<view v-if="heartRateData.series" class="heart_rate_chart">
<view class="charts-box">
<qiun-data-charts type="tline" canvasId="sport_a" :canvas2d="isCanvas2d" :resshow="delayload"
:opts="{ padding: [0, 20, 10, 0], legend: { position: 'top', lineHeight: 20 }, xAxis: { disableGrid: true, format: 'xAxisDemo3' }, yAxis: { data: [{ min: 0, max: 175 }], gridType: 'solid' }, dataLabel: false, dataPointShape: false }"
:chartData="heartRateData" />
</view>
</view>
<view class="title_view">
<view class="left">
<li :class="['iconfont icon-xinlv']"></li>
<text class="title">心率区间</text>
</view>
</view>
<view class="heart_rate_range">
<view class="top">
<view class="item" v-for="(item, index) in heatRateRange" :key="index">
<view class="name text_gray">{{ item.name }}</view>
<view class="data">{{ item.type }}{{ item.data }}<text class="unit text_gray">分钟</text></view>
</view>
</view>
<view v-if="heartRateRangeData" class="charts-box">
<qiun-data-charts type="ring" canvasId="sport_b" :canvas2d="isCanvas2d" :resshow="delayload"
:opts="{ legend: { position: 'bottom' }, extra: { ring: { border: false, centerColor: '#312C34' } }, title: { name: '' }, subtitle: { name: '' } }"
:chartData="heartRateRangeData" />
</view>
</view>
<view class="title_view">
<view class="left">
<li :class="['iconfont icon-pie']"></li>
<text class="title">运动分析</text>
</view>
</view>
<view class="sport_analysis_view">
<view class="top">
<li class="iconfont icon-feiji"></li>
<text class="title font-s-34">跑步机</text>
</view>
<view class="middle">
<view class="left">
<li class="iconfont icon-clock"></li>
<view>3.24P.M</view>
</view>
<view class="right">
<li class="iconfont icon-huo"></li>
<view>热量消耗(千卡)</view>
</view>
</view>
<view class="bottom">
<view class="left">
<li class="iconfont icon-kongxinyuan"></li>
<view>燃烧脂肪</view>
</view>
<view class="right">
<view class="text_wide_600 font-s-40">637</view>
</view>
</view>
</view>
<view class="box_view speed_rank_view">
<view class="top">
<view class="item" v-for="(item, index) in speedRank" :key="index">
<view class="name text_gray">{{ item.name }}</view>
<view class="data">{{ item.data }}<text class="unit text_gray">{{ item.unit }}</text></view>
</view>
</view>
<view v-if="speedRankData" class="charts-box">
<qiun-data-charts type="bar" canvasId="sport_c" :canvas2d="isCanvas2d" :resshow="delayload"
:chartData="speedRankData" background="none"
:opts="{ xAxis: { disabled: true, disableGrid: true }, extra: { bar: { barBorderCircle: true, width: 20 } }, legend: { show: false } }" />
</view>
</view>
<view class="box_view">
<view v-if="speedAndRateData.series" class="charts-box">
<qiun-data-charts type="tline" canvasId="sport_d" :canvas2d="isCanvas2d" :resshow="delayload"
:opts="{ padding: [0, 20, 10, 0], legend: { position: 'top', lineHeight: 20 }, xAxis: { disableGrid: true, format: 'xAxisDemo3' }, yAxis: { data: [{ position: 'left', min: 0, max: 25 }, { position: 'right', min: 50, max: 175 }], gridType: 'solid' }, dataLabel: false, dataPointShape: false }"
:chartData="speedAndRateData" />
</view>
</view>
</view>
</template>
<script>
import heartRateData from "../../static/json/sport/1.json"
import heartRateRangeData from "../../static/json/sport/2.json"
import speedRankData from "../../static/json/sport/3.json"
import speedAndRateData from "../../static/json/sport/4.json"
export default {
components: {
},
data() {
return {
info: '大便超人', //
isCanvas2d: this.$Config.ISCANVAS2D,
heartRateData: {},
speedRankData: {},
speedAndRateData: {},
delayload: null,
heartRateRangeData: {},
heatRateRange: [{
name: "激活放松",
data: "5",
type: "≤"
},
{
name: "动态热身",
data: "13",
type: ""
},
{
name: "脂肪燃烧",
data: "24",
type: ""
},
{
name: "糖分消耗",
data: "8",
type: "≤"
},
{
name: "心肺训练",
data: "7",
type: ""
},
{
name: "极限锻炼",
data: "16",
type: ""
},
],
speedRank: [{
name: "距离",
data: "5",
unit: "公里"
},
{
name: "时长",
data: "12",
unit: "分钟"
},
{
name: "平均配速",
data: "6\'05\"",
unit: ""
}
]
};
},
watch: {
},
methods: {
async getData() {
uni.showLoading();
/*将钟点时间随机转成某一天的具体时间戳*/
if (typeof heartRateData.series[0].data[0][0] == 'string') {
for (let i = 0; i < heartRateData.series.length; i++) {
heartRateData.series[i].data.map(x => {
x[0] = "2018/08/08 " + x[0];
x[0] = this.tranTimestamp(x[0]);
return x[0];
})
}
}
if (typeof speedAndRateData.series[0].data[0][0] == 'string') {
for (let i = 0; i < speedAndRateData.series.length; i++) {
speedAndRateData.series[i].data.map(x => {
x[0] = "2018/08/08 " + x[0];
x[0] = this.tranTimestamp(x[0]);
return x[0];
})
}
}
this.heartRateData = heartRateData;
this.heartRateRangeData = heartRateRangeData;
this.speedRankData = speedRankData;
this.speedAndRateData = speedAndRateData;
this.delayload = true;
uni.hideLoading();
},
tranTimestamp(date) {
return new Date(date).getTime()
},
gotoBack() {
this.$Common.navigateBack("/index/index");
},
},
onReady() {
//#ifndef H5
uni.showShareMenu();
//#endif
this.getData()
}
}
</script>
<style scoped lang="scss">
.body {
height: 100%;
background-color: #1C191F;
margin: 0;
color: #fff;
padding: 80rpx 20rpx 0 20rpx;
width: 100%;
box-sizing: border-box;
padding-bottom: 50rpx;
.box_view {
width: 100%;
padding: 20rpx;
position: relative;
background-color: #312C34;
color: #FFFFFF;
box-sizing: border-box;
border-radius: 20rpx;
overflow: hidden;
margin-top: 30rpx;
}
.speed_rank_view {
.top {
width: 100%;
&:after {
content: "";
clear: both;
display: block;
}
.item {
float: left;
width: 33%;
box-sizing: border-box;
padding: 30rpx 20rpx;
text-align: left;
.name {
font-size: 26rpx;
}
.data {
font-size: 40rpx;
margin-top: 10rpx;
.unit {
font-size: 24rpx;
margin-left: 14rpx;
}
}
}
}
}
.sport_analysis_view {
width: 100%;
padding: 20rpx;
position: relative;
background-color: #312C34;
color: #FFFFFF;
box-sizing: border-box;
border-radius: 20rpx;
overflow: hidden;
.top {
width: 100%;
height: 120rpx;
display: flex;
align-items: center;
.icon-feiji {
margin-top: 10rpx;
}
.title {
margin-left: 10rpx;
}
}
.middle {
width: 100%;
display: flex;
justify-content: space-between;
font-size: 28rpx;
.iconfont {
font-size: 28rpx;
margin-right: 10rpx;
margin-top: 4rpx;
}
.left {
width: 50%;
height: 60rpx;
display: flex;
align-items: center;
justify-content: flex-start;
}
.right {
width: 50%;
height: 60rpx;
display: flex;
align-items: center;
justify-content: flex-end;
}
}
.bottom {
width: 100%;
display: flex;
justify-content: space-between;
font-size: 28rpx;
.iconfont {
font-size: 28rpx;
margin-right: 10rpx;
margin-top: 4rpx;
}
.left {
width: 50%;
height: 60rpx;
display: flex;
align-items: center;
justify-content: flex-start;
.icon-kongxinyuan {
color: #6FCEF7;
}
}
.right {
width: 50%;
height: 60rpx;
display: flex;
align-items: center;
justify-content: flex-end;
}
}
}
.heart_rate_range {
width: 100%;
position: relative;
background-color: #312C34;
color: #FFFFFF;
box-sizing: border-box;
border-radius: 20rpx;
overflow: hidden;
.top {
width: 100%;
&:after {
content: "";
clear: both;
display: block;
}
.item {
float: left;
width: 33%;
box-sizing: border-box;
padding: 30rpx 20rpx;
text-align: center;
.name {
font-size: 26rpx;
}
.data {
font-size: 40rpx;
margin-top: 10rpx;
.unit {
font-size: 24rpx;
margin-left: 14rpx;
}
}
}
}
}
.heart_rate_chart {
display: flex;
justify-content: center;
width: 100%;
position: relative;
background-color: #312C34;
color: #FFFFFF;
box-sizing: border-box;
border-radius: 20rpx;
overflow: hidden;
}
.title_view {
display: flex;
width: 100%;
align-items: center;
height: 150rpx;
.left {
display: flex;
align-items: center;
.iconfont {
font-size: 40rpx !important;
}
.title {
font-size: 34rpx;
margin-left: 20rpx;
}
}
}
.heart_rate_view {
display: flex;
width: 100%;
justify-content: space-around;
align-items: center;
height: 150rpx;
.left {
display: flex;
align-items: center;
.icon-zhexiantu {
font-size: 26rpx;
}
.title {
font-size: 34rpx;
margin-left: 20rpx;
}
}
.right {
font-size: 22rpx;
padding: 10rpx 30rpx;
border-radius: 40rpx;
background-color: #342E39;
}
}
.consume_view {
display: flex;
justify-content: center;
width: 100%;
height: 190rpx;
position: relative;
margin-top: 100rpx;
background-color: #312C34;
color: #FFFFFF;
box-sizing: border-box;
border-radius: 10rpx;
.consume_img {
width: 240rpx;
height: auto;
position: absolute;
top: -80rpx;
left: 20rpx;
}
.consume_icon {
font-size: 220rpx;
position: absolute;
top: -80rpx;
left: 20rpx;
}
.desc {
position: absolute;
right: 80rpx;
top: 20rpx;
view {
padding: 10rpx 0;
display: flex;
align-items: center;
}
.left {
font-size: 50rpx;
}
.right {
font-size: 30rpx;
margin-left: 10rpx;
font-weight: 400;
}
}
}
.text-green {
color: #10A764;
}
.text_gray {
color: #8E8B8B;
}
.small_text {
font-size: 24rpx;
}
.font-s-34 {
font-size: 34rpx;
}
.font-s-36 {
font-size: 36rpx;
}
.font-s-38 {
font-size: 38rpx;
}
.font-s-40 {
font-size: 40rpx;
}
.middle_text {
font-size: 36rpx;
}
.text_wide_900 {
font-weight: 900;
}
.text_wide_600 {
font-weight: 600;
}
.census_view {
width: 100%;
display: flex;
justify-content: space-around;
.left {
text-align: left;
view {
padding: 10rpx 0;
}
}
.center {
text-align: center;
view {
padding: 10rpx 0;
}
}
.right {
text-align: right;
view {
padding: 10rpx 0;
}
}
}
.score_view {
width: 100%;
.title {
color: #8E8B8B;
font-size: 24rpx;
}
.detail {
height: 120rpx;
width: 100%;
display: flex;
align-items: flex-end;
.icon-up {
margin-left: 40rpx;
height: 54rpx;
font-weight: 600;
}
.socre {
font-size: 80rpx;
font-weight: 900;
}
.up_socre {
color: #10A764;
height: 50rpx;
font-size: 24rpx;
font-weight: 600;
}
}
}
.head {
height: 140rpx;
line-height: 140rpx;
position: relative;
.title {
font-size: 40rpx;
margin-left: 20rpx;
}
.customer_img {
position: absolute;
bottom: 0rpx;
right: 20rpx;
width: 100rpx;
height: 100rpx;
margin: 0;
padding: 0;
background-size: 100% 100%;
border-radius: 100%;
overflow: hidden;
.img {
height: auto;
width: 100%;
}
}
}
li {
list-style-type: none;
}
.nav {
position: fixed;
top: 50rpx;
left: 20rpx;
}
}
.consume_view:nth-child(even) {
margin-right: 4%;
}
.consume_tip {
display: inline-block;
text-align: center;
width: 188rpx;
height: 30rpx;
line-height: 30rpx;
position: absolute;
top: 36rpx;
right: -44rpx;
z-index: 2;
overflow: hidden;
transform: rotate(45deg);
-ms-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-o-transform: rotate(45deg);
border: 1px dashed;
box-shadow: 0 0 0 3px #10A764, 0px 21px 5px -18px rgba(0, 0, 0, 0.6);
background: #10A764;
font-size: 16rpx;
}
.wrap {
width: 100%;
height: 100%;
position: absolute;
top: -12rpx;
left: 12rpx;
overflow: hidden;
}
.wrap:before {
content: "";
display: block;
border-radius: 8px 8px 0px 0px;
width: 80rpx;
height: 14rpx;
position: absolute;
right: 68rpx;
top: -1px;
background: #4D6530;
}
.wrap:after {
content: "";
display: block;
border-radius: 0px 8px 8px 0px;
width: 14rpx;
height: 80rpx;
position: absolute;
right: -1px;
top: 66rpx;
background: #4D6530;
}</style>

@ -0,0 +1,170 @@
let isReadyLogin = 1
let loginFlag = 1
export default {
//提示窗
tipMsg: function (title, icon, time, mask,callback) {
title = title == undefined ? "系统繁忙" : title;
icon = icon == undefined ? "none" : icon;
time = time == undefined ? 1300 : time;
mask = mask == undefined ? true : mask;
uni.showToast({
title: title,
icon: icon,
mask: mask,
duration: time,
success() {
if(callback){
setTimeout(()=>{
callback()
},time);
}
}
})
},
getTelephoneInfo(){
return new Promise((resolve, reject) => {
var data = uni.getStorageSync("telephoneInfo");
if(!data){
// 获取右上角胶囊的位置信息
//#ifndef H5
let btn = wx.getMenuButtonBoundingClientRect();
uni.getSystemInfo({
success: e => {
let info = {
screenHeight:e.screenHeight,
statusBarHeight:e.statusBarHeight,
windowWidth:e.windowWidth,
top:btn.top
}
uni.setStorageSync("telephoneInfo",info);
resolve(info);
},
fail: (err) => {
reject(err);
}
})
//#endif
}else{
resolve(data);
}
})
},
// 获取当前年月日
getNowDate(){
let date = new Date;
let now = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate();
return now;
},
// 获取上个月的年月日
getPreMonth(date) {
var arr = date.split('-');
var year = arr[0]; //获取当前日期的年份
var month = arr[1]; //获取当前日期的月份
var day = arr[2]; //获取当前日期的日
var days = new Date(year, month, 0);
days = days.getDate(); //获取当前日期中月的天数
var year2 = year;
var month2 = parseInt(month) - 1;
if (month2 == 0) {
year2 = parseInt(year2) - 1;
month2 = 12;
}
var day2 = day;
var days2 = new Date(year2, month2, 0);
days2 = days2.getDate();
if (day2 > days2) {
day2 = days2;
}
if (month2 < 10) {
month2 = '0' + month2;
}
var t2 = year2 + '-' + month2 + '-' + "01";
return t2;
},
//检测小程序更新
checkUpdateVersion(){
//新版本更新
if (uni.canIUse('getUpdateManager')) {
//判断当前微信版本是否支持版本更新
const updateManager = uni.getUpdateManager();
updateManager.onCheckForUpdate(function (res) {
if (res.hasUpdate) {
// 请求完新版本信息的回调
updateManager.onUpdateReady(function () {
uni.showModal({
title: '更新提示',
content: '已更新版本,是否重启小程序?',
showCancel:false,
cancelColor:'#eeeeee',
confirmColor:'#40A2ED',
success: function (res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
},
});
});
// 新的版本下载失败
updateManager.onUpdateFailed(function () {
uni.showModal({
title: '更新失败',
content: '请检查网络设置,若仍更新失败,重新搜索打开',
success(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
}
});
});
}
});
} else {
uni.showModal({
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。',
});
}
},
/**
* @param {string} url 目标页面的路由
* @param {Object} param 传递给目标页面的参数
* @description 处理目标页面的参数转成json字符串传递给param字段在目标页面通过JSON.parse(options.param)接收
*/
navigateTo(url, param = {},flag) {
if(isReadyLogin<=0 && !flag){
this.loginTip();
}else{
let part = '';
for(var item in param){
part += '&' + item + '=' + param[item];
}
url = url + part.replace('&','?');
uni.navigateTo({
url: url,
fail:err=> {
this.tipMsg('页面正在火速开发中,敬请期待!');
},
})
}
},
navigateBack(url, param = {}) {
if (loginFlag <= 0) {
this.tipMsg("很抱歉,你没有权限!");
} else {
let part = '';
for (var item in param) {
part += '&' + item + '=' + param[item];
}
url = "/pages" + url + part.replace('&', '?');
uni.navigateBack({
url: url,
fail: err => {
this.tipMsg('暂未开放该功能!');
},
})
}
},
}

@ -0,0 +1,79 @@
const COLOR = [
"#EE6A66", "#6BC588", "#FFC300", "#24ABFD"
];
var ISCANVAS2D = true;
switch (uni.getSystemInfoSync().platform) {
case 'android':
ISCANVAS2D = true
break;
case 'ios':
ISCANVAS2D = true
break;
default:
ISCANVAS2D = false
break;
}
const RESPOND = {
success: 0,
warn: 301,
error: 500,
};
const TIMEARRAY = [
{
text: '当天',
value: 'today'
},
{
text: '昨天',
value: 'yesterday'
},
{
text: '本周',
value: 'week'
},
{
text: '上周',
value: 'weeklast'
},
{
text: '本月',
value: 'month'
},
{
text: '上月',
value: 'monthlast'
},
{
text: '指定日期',
value: 'auto'
}
];
const TABLIST = [
{name:"企业微信",type:"WECHAT"},
{name:"会员运营",type:"OPERATE"},
{name:"会员健康",type:"GJJK"},
{name:"会员服务",type:"SERVICE"},
];
const CARD_MENU = [
{title:"会员报表中心",author:"howcode",img:"https://s1.ax1x.com/2023/03/31/ppRp4iV.jpg",url:"/myPackageA/pages/main/index"},
{title:"智慧教育报表中心",author:"howcode",img:"https://s1.ax1x.com/2023/03/31/ppRp5GT.jpg",url:"/myPackageA/pages/school/index"},
{title:"差旅报表中心",author:"秋云",img:"https://s1.ax1x.com/2023/03/31/ppRpfI0.jpg",url:""},
{title:"运动报表中心",author:"howcode",img:"https://s1.ax1x.com/2023/03/31/ppRpWaq.jpg",url:"/myPackageA/pages/sport/index"},
{title:"财务报表中心",author:"howcode",img:"https://s1.ax1x.com/2023/03/31/ppRpozF.jpg",url:"/myPackageA/pages/finance/index"},
]
export default {
COLOR,
TIMEARRAY,
TABLIST,
RESPOND,
ISCANVAS2D,
CARD_MENU
}

@ -0,0 +1,68 @@
{
"expend":{
"categories": [
"1月",
"2月",
"2月",
"4月",
"5月"
],
"series": [
{
"name": "支出情况",
"data": [1201,2501.5,985,1760,2013.85],
"type": "line",
"style": "curve",
"color": "#4ECDB6",
"unit":""
}
],
"yAxis":[
{"calibration":true,"position":"left","title":"单位/元","titleFontSize":12,"unit":"","tofix":0,"min":0,"disableGrid":true}
]
},
"income":{
"categories": [
"1月",
"2月",
"2月",
"4月",
"5月"
],
"series": [
{
"name": "收入情况",
"data": [1601,1840.5,1900,1760,1500.85],
"type": "line",
"style": "curve",
"color": "#4ECDB6",
"unit":""
}
],
"yAxis":[
{"calibration":true,"position":"left","title":"单位/元","titleFontSize":12,"unit":"","tofix":0,"min":0,"disableGrid":true}
]
},
"remaining":{
"categories": [
"1月",
"2月",
"2月",
"4月",
"5月"
],
"series": [
{
"name": "结余情况",
"data": [815,712.5,378,450,600.85],
"type": "line",
"style": "curve",
"color": "#4ECDB6",
"unit":""
}
],
"yAxis":[
{"calibration":true,"position":"left","title":"单位/元","titleFontSize":12,"unit":"","tofix":0,"min":0,"disableGrid":true}
]
}
}

@ -0,0 +1,33 @@
{
"series": [
{
"data":[
{
"name": "住房相关",
"value": 3200,
"color":"#4DCCB3"
},
{
"name": "食品酒水",
"value": 1020,
"color":"#5A77EC"
},
{
"name": "娱乐休闲",
"value": 500,
"color":"#4E94EC"
},
{
"name": "交流通讯",
"value": 214.5,
"color":"#4FD4EB"
},
{
"name": "其他",
"value": 320.13,
"color":"#B5ED21"
}
]
}
]
}

@ -0,0 +1,26 @@
[
{
"name":"课题研究",
"num":500,
"width":"",
"background":"#FFBE68"
},
{
"name":"论文发布",
"num":300,
"width":"",
"background":"#0FEBE1"
},
{
"name":"实践研究",
"num":455,
"width":"",
"background":"#BF8DFC"
},
{
"name":"评教",
"num":601,
"width":"",
"background":"#FF859C"
}
]

@ -0,0 +1,28 @@
{
"series": [
{
"data": [
{
"name": "本科",
"value": 168,
"color": "#FFBF31"
},
{
"name": "大专",
"value": 144,
"color": "#3CEFC4"
},
{
"name": "博士",
"value": 123,
"color": "#FFA9B3"
},
{
"name": "硕士",
"value": 96,
"color": "#3CBBFF"
}
]
}
]
}

@ -0,0 +1,27 @@
{
"categories":["语文","数学","英语","物理","化学","生物"],
"series":[
{
"name":"一班",
"area":[123.45,234,192.5,245],
"color":"#1890ff",
"data":[90,110,165,195,187,172],
"index":0,
"legendShape":"circle",
"pointShape":"",
"show": true,
"type": "radar"
},
{
"name":"二班",
"area":[192.5,234,261.55,245],
"color":"#2fc25b",
"data":[190,210,105,35,27,102],
"index":0,
"legendShape":"circle",
"pointShape":"",
"show": true,
"type": "radar"
}
]
}

@ -0,0 +1,29 @@
{
"categories": [
"1",
"2",
"2",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12"
],
"series": [
{
"name": "图书借阅人数",
"data": [6,8,9,8.2,7.5,9,10.3,8,12,6.2,7.2,4.5],
"type": "line",
"style": "curve",
"color": "#A800FB",
"unit":""
}
],
"yAxis":[
{"calibration":true,"position":"left","title":"单位/千","titleFontSize":12,"unit":"","tofix":0,"min":0,"max":20,"disableGrid":true}
]
}

@ -0,0 +1,80 @@
{
"series": [{
"name": "激活放松",
"color": "#FDEC9F",
"data": [
["17:24", 75],
["17:26", 83],
["17:28", 88],
["17:30", 92]
]
},
{
"name": "动态热身",
"color": "#FBCD2B",
"data": [
["17:30", 92],
["17:32", 96],
["17:34", 94],
["17:36", 93.5],
["17:38", 94.6],
["17:40", 98]
]
},
{
"name": "糖分消耗",
"color": "#FC9E83",
"data": [
["17:40", 98],
["17:42", 100],
["17:44", 104],
["17:46", 113],
["17:48", 142]
]
},
{
"name": "脂肪燃烧",
"color": "#EF6DCF",
"data": [
["17:48", 142],
["17:50", 130],
["17:52", 134],
["17:54", 150],
["17:56", 148],
["17:58", 142],
["18:00", 132],
["18:02", 136],
["18:04", 136.5]
]
},
{
"name": "心肺训练",
"color": "#BC38E5",
"data": [
["18:04", 136.5],
["18:06", 140],
["18:08", 135],
["18:10", 130],
["18:12", 124],
["18:14", 120],
["18:16", 118],
["18:18", 116.5],
["18:20", 112]
]
}, {
"name": "极限锻炼",
"color": "#8908FA",
"data": [
["18:20", 112],
["18:22", 123],
["18:24", 130],
["18:26", 138],
["18:28", 116],
["18:30", 123],
["18:32", 128],
["18:34", 126],
["18:36", 137]
]
}
]
}

@ -0,0 +1,38 @@
{
"series": [
{
"data": [
{
"name": "激活放松",
"value": 5,
"color": "#FDEC9F"
},
{
"name": "动态热身",
"value": 13,
"color": "#FBCD2B"
},
{
"name": "糖分消耗",
"value": 8,
"color": "#FC9E83"
},
{
"name": "脂肪燃烧",
"value": 24,
"color": "#EF6DCF"
},
{
"name": "心肺训练",
"value": 7,
"color": "#BC38E5"
},
{
"name": "极限锻炼",
"value": 16,
"color": "#8908FA"
}
]
}
]
}

@ -0,0 +1,22 @@
{
"categories": [
"1",
"2",
"3",
"4",
"5"
],
"series": [
{
"name": "公里配速",
"data": [
5.09,
6.18,
6.38,
7.15,
9.05
],
"color":"#FFD597"
}
]
}

@ -0,0 +1,174 @@
{
"series": [
{
"name": "速度",
"color": "#1C9862",
"index":0,
"data": [
[
"17:24",
0
],
[
"17:26",
1
],
[
"17:28",
1.2
],
[
"17:30",
1.6
],
[
"17:32",
1.8
],
[
"17:34",
2
],
[
"17:36",
4
],
[
"17:38",
6.5
],
[
"17:40",
10
],
[
"17:42",
13.4
],
[
"17:44",
13
],
[
"17:46",
12.6
],
[
"17:48",
12.2
],
[
"17:50",
14
],
[
"17:52",
16.8
],
[
"17:54",
20
],
[
"17:56",
25
],
[
"17:58",
23
],
[
"18:00",
16
]
]
},
{
"name": "心率",
"index":1,
"color": "#FBCD2B",
"data": [
[
"17:24",
72
],
[
"17:26",
73
],
[
"17:28",
73.5
],
[
"17:30",
74
],
[
"17:32",
76.5
],
[
"17:34",
78
],
[
"17:36",
80
],
[
"17:38",
76.3
],
[
"17:40",
75
],
[
"17:42",
86
],
[
"17:44",
84
],
[
"17:46",
90
],
[
"17:48",
100
],
[
"17:50",
112
],
[
"17:52",
125
],
[
"17:54",
117
],
[
"17:56",
110
],
[
"17:58",
108
],
[
"18:00",
104
]
]
}
],
"yAxis":[
{"calibration":true,"position":"left","title":"","titleFontSize":12,"unit":"","tofix":0,"min":0,"max":25,"disableGrid":true},
{"calibration":true,"position":"right","title":"","titleFontSize":12,"unit":"","tofix":0,"min":0,"disableGrid":true}
]
}

@ -0,0 +1,21 @@
[
{
"expect": "",
"now": "",
"name": "时间进度",
"value": "60.12"
},
{
"expect": "30000",
"now": "36000",
"dataType": "1",
"name": "会员拉新",
"value": "120"
},
{
"expect": "",
"now": "",
"name": "扫码渗透率",
"value": "35"
}
]

@ -0,0 +1,34 @@
[
{
"kind":1,
"background":["#B678FD","#4A64F9"],
"content":[
{"text":"","value":"1800","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"日均新增目标","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"}
]
},
{
"kind":1,
"background":["#B678FD","#4A64F9"],
"content":[
{"text":"","value":"1960","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"当日新增会员","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"}
]
},
{
"kind":1,
"background":["#B678FD","#4A64F9"],
"content":[
{"text":"","value":"36050","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"本月新增会员","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"}
]
},
{
"kind":1,
"background":["#B678FD","#4A64F9"],
"content":[
{"text":"","value":"3%","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"日均环比","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"}
]
}
]

@ -0,0 +1,74 @@
{
"categories": [
"1月11",
"1月12",
"1月11",
"1月14",
"1月15"
],
"series": [{
"name": "新增会员数",
"data": [{
"value": 5,
"color": "#24ABFD"
},
{
"value": -3,
"color": "#24ABFD"
},
{
"value": 3.5,
"color": "#24ABFD"
},
{
"value": 10,
"color": "#24ABFD"
},
{
"value": 2.8,
"color": "#24ABFD"
}
],
"type": "column",
"color": "#24ABFD",
"unit": "",
"textNoShow": true
},
{
"name": "当日达成率",
"data": [
101,
91,
97,
131,
109
],
"type": "line",
"addPoint": true,
"color": "#DF297D",
"unit": "%",
"index": 1
},
{
"name": "日均达成率",
"data": [
102,
92,
96,
115,
105
],
"type": "line",
"color": "#24ABFD",
"unit": "%",
"index": 1
}
],
"yAxis": [{
"max": 20,
"min": 0
}, {
"max": 200,
"min": 0
}]
}

@ -0,0 +1,26 @@
[
{
"kind":1,
"background":["#B678FD","#4A64F9"],
"content":[
{"text":"","value":"42%","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"当日扫码率","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"}
]
},
{
"kind":1,
"background":["#B678FD","#4A64F9"],
"content":[
{"text":"","value":"37%","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"累计扫码率","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"}
]
},
{
"kind":2,
"background":["#B678FD","#4A64F9"],
"content":[
{"text":"环比增长","value":"3.2%","colortext":"#fff","colorvalue":"#fff","size":"24rpx"},
{"text":"同比增长","value":"1.1%","colortext":"#fff","colorvalue":"#fff","size":"24rpx"}
]
}
]

@ -0,0 +1,57 @@
{
"categories": [
"1月11",
"1月12",
"1月13",
"1月14",
"1月15"
],
"series": [{
"name": "当天扫码率",
"data": [
39,
34,
36,
45,
38
],
"type": "line",
"addPoint": true,
"color": "#24ABFD",
"unit": "%"
},
{
"name": "累计扫码率",
"data": [
32,
30,
31,
37,
35
],
"type": "line",
"addPoint": true,
"color": "#DF297D",
"unit": "%"
},
{
"name": "目标扫码率",
"data": [
40,
40,
40,
40,
40
],
"type": "line",
"color": "#FF9900",
"textNoShow": true,
"unit": ""
}
],
"yAxis": [{
"max": 60,
"min": 0
}]
}

@ -0,0 +1,12 @@
[
{
"kind":3,
"background":["#B678FD","#4A64F9"],
"content":[
{"text":"","value":"38%","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"小程序购买活跃会员占比","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"同比","value":"2.5%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"环比","value":"3.2%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
}
]

@ -0,0 +1,89 @@
{
"categories": [
"1月11",
"1月12",
"1月11",
"1月14",
"1月15"
],
"series": [{
"name": "新增会员数",
"data": [{
"value": 5,
"color": "#24ABFD"
},
{
"value": -3,
"color": "#24ABFD"
},
{
"value": 3.5,
"color": "#24ABFD"
},
{
"value": 10,
"color": "#24ABFD"
},
{
"value": 2.8,
"color": "#24ABFD"
}
],
"type": "column",
"color": "#24ABFD",
"unit": "",
"textNoShow": true
},
{
"name": "当日达成率",
"data": [
101,
91,
97,
131,
109
],
"type": "line",
"addPoint": true,
"color": "#DF297D",
"unit": "%",
"index": 1
},
{
"name": "日均达成率",
"data": [
102,
92,
96,
115,
105
],
"type": "line",
"style": "curve",
"color": "#ff9900",
"unit": "%",
"index": 1
},
{
"name": "日均达成率",
"data": [
102,
92,
96,
115,
105
],
"type": "area",
"color": "#ff9900",
"unit": "%",
"index": 1
}
],
"yAxis": [{
"max": 20,
"min": 0
}, {
"max": 200,
"min": 0
}]
}

@ -0,0 +1,22 @@
[
{
"expect": "",
"now": "",
"name": "时间进度",
"value": "50.88"
},
{
"expect": "54800",
"now": "51000",
"dataType": "1",
"name": "新开会员",
"value": "93.07"
},
{
"expect": "30000",
"now": "25600",
"dataType": "1",
"name": "新增消费会员",
"value": "85.33"
}
]

@ -0,0 +1,35 @@
[
{
"kind":5,
"background":["#F77E89","#F7953B"],
"content":[
{"text":"扫一扫","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"","value":"63%","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"环比","value":"81.5%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"同比","value":"-81.3%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"平均参考水平","value":"85%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
},
{
"kind":5,
"background":["#F77E89","#F7953B"],
"content":[
{"text":"二维码识别","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"","value":"13%","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"环比","value":"2%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"同比","value":"-0.8%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"平均参考水平","value":"80%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
},
{
"kind":5,
"background":["#F77E89","#F7953B"],
"content":[
{"text":"最近使用","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"","value":"21%","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"环比","value":"1%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"同比","value":"-0.8%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"平均参考水平","value":"80%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
}
]

@ -0,0 +1,35 @@
[
{
"kind":5,
"background":["#F77E89","#F7953B"],
"content":[
{"text":"会员销售占比","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"","value":"80%","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"环比","value":"81.5%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"同比","value":"-81.3%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"平均参考水平","value":"85%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
},
{
"kind":5,
"background":["#F77E89","#F7953B"],
"content":[
{"text":"会员客流占比","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"","value":"79%","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"环比","value":"2%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"同比","value":"-0.8%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"平均参考水平","value":"80%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
},
{
"kind":5,
"background":["#F77E89","#F7953B"],
"content":[
{"text":"会员客单价","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"","value":"79元","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"环比","value":"1%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"同比","value":"-0.8%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"},
{"text":"平均参考水平","value":"80%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
}
]

@ -0,0 +1,61 @@
{
"categories": [
"1周",
"2周",
"3周",
"4周",
"5周"
],
"series": [{
"name": "同比增长率",
"data": [{
"value": 5,
"color": "#24ABFD"
},
{
"value": -3,
"color": "#24ABFD"
},
{
"value": 3.5,
"color": "#24ABFD"
},
{
"value": 10,
"color": "#24ABFD"
},
{
"value": 2.8,
"color": "#24ABFD"
}
],
"type": "column",
"color": "#24ABFD",
"index": 1,
"unit": "%"
},
{
"name": "消费金额",
"data": [
1850,
1660,
1760,
2360,
1970
],
"type": "line",
"addPoint": true,
"color": "#DF297D",
"unit": ""
}
],
"target": 1800,
"yAxis": [{
"max": 3000,
"min": 0
}, {
"max": 20,
"min": 0
}],
"targetAdd": "9%"
}

@ -0,0 +1,88 @@
{
"headers":[
{
"label": "最近活跃时间",
"key": "col1"
}, {
"label": "人数",
"key": "col2"
}, {
"label": "人数占比",
"key": "col3"
}, {
"label": "活跃会员环比",
"key": "col4"
}, {
"label": "活跃消费人数占比",
"key": "col5"
}
],
"contents":[
{
"col1": "0-30天",
"col2": "15350",
"col3": "45",
"col4": "9.5",
"col5": "29"
}, {
"col1": "30-60天",
"col2": "15350",
"col3": "13",
"col4": "-2.5",
"col5": "-25"
}, {
"col1": "60-90天",
"col2": "15371",
"col3": "15",
"col4": "-5.2",
"col5": "63"
}, {
"col1": "90-120天",
"col2": "12340",
"col3": "12",
"col4": "2.9",
"col5": "-12"
}, {
"col1": "120-180天",
"col2": "12360",
"col3": "17",
"col4": "3.5",
"col5": "11"
}
],
"sortCol":[
{
"key": "col1",
"isNumber": false
}, {
"key": "col2",
"isNumber": true
},
{
"key": "col3",
"isNumber": true
},
{
"key": "col4",
"isNumber": true
},
{
"key": "col5",
"isNumber": true
}
],
"computedCol":["col2","col3","col4","col5"],
"formatCol":[{
"key": "col3",
"template": "#col3#%",
"bottomComputedFormat": true
}, {
"key": "col4",
"template": "#col4#%",
"bottomComputedFormat": true
}, {
"key": "col5",
"template": "#col5#%",
"bottomComputedFormat": true
}]
}

@ -0,0 +1,25 @@
[{
"series": [{
"color": "#24ABFD",
"data": 0.18,
"index": 0,
"legendShape": "circle",
"name": "当前脱落率",
"pointShape": "circle",
"show": true,
"type": "arcbar"
}]
},
{
"series": [{
"color": "#F04864",
"data": 0.25,
"index": 0,
"legendShape": "circle",
"name": "脱落率警示线",
"pointShape": "circle",
"show": true,
"type": "arcbar"
}]
}
]

@ -0,0 +1,36 @@
{
"categories": [
"高血压",
"糖尿病",
"痛风",
"血脂",
"尿酸"
],
"series": [{
"name": "今周脱落率",
"data": [{
"value": 6,
"color": "#24ABFD"
},
{
"value": 3.2,
"color": "#24ABFD"
},
{
"value": 5.5,
"color": "#24ABFD"
},
{
"value": 8,
"color": "#24ABFD"
},
{
"value": 6,
"color": "#24ABFD"
}
],
"type": "column",
"color": "#24ABFD",
"unit": "%"
}]
}

@ -0,0 +1,26 @@
[{
"series": [{
"color": "#24ABFD",
"data": 0.75,
"index": 0,
"legendShape": "circle",
"name": "当前脱落率",
"pointShape": "circle",
"show": true,
"type": "arcbar"
}]
},
{
"series": [{
"color": "#F04864",
"data": 0.33,
"index": 0,
"legendShape": "circle",
"name": "脱落率警示线",
"pointShape": "circle",
"show": true,
"type": "arcbar"
}]
}
]

@ -0,0 +1,62 @@
[
{
"series": [{
"color": "#fff",
"data": 0.224,
"precent":"22.4%",
"index": 0,
"legendShape": "circle",
"name": "B2C销售额",
"pointShape": "circle",
"show": true,
"type": "arcbar",
"value":"12786",
"backgroundColor":"#00AEF9"
}]
},
{
"series": [{
"color": "#fff",
"data": 0.3717,
"precent":"37.17%",
"index": 0,
"legendShape": "circle",
"name": "B2C毛利率",
"pointShape": "circle",
"show": true,
"type": "arcbar",
"value":"1096",
"backgroundColor":"#F55676"
}]
},
{
"series": [{
"color": "#fff",
"data": 0.0017,
"precent":"0.17%",
"index": 0,
"legendShape": "circle",
"name": "O2O销售额",
"pointShape": "circle",
"show": true,
"type": "arcbar",
"value":"147604",
"backgroundColor":"#FAB215"
}]
},
{
"series": [{
"color": "#fff",
"data": 0.6321,
"precent":"63.21%",
"index": 0,
"legendShape": "circle",
"name": "O2O毛利率",
"pointShape": "circle",
"show": true,
"type": "arcbar",
"value":"173",
"backgroundColor":"#2EC693"
}]
}
]

@ -0,0 +1,29 @@
{
"series": [
{
"name": "任务栏最近使用",
"data": 500,
"color":"#2fc25b"
},
{
"name": "最近使用小程序列表",
"data": 623,
"color":"#facc14"
},
{
"name": "手机系统",
"data": 123,
"color":"#f04864"
},
{
"name": "任务栏我的小程序",
"data": 96,
"color":"#8543e0"
},
{
"name": "其他",
"data": 423,
"color":"#51c2d5"
}
]
}

@ -0,0 +1,36 @@
{
"categories": [
"周一", "周二", "周三", "周四", "周五",
"周六",
"周日"
],
"series": [
{
"name": "老会员", "data": [ 1850, 1660, 1760, 2360, 1560, 1970, 2570 ], "type": "line",
"style": "curve",
"addPoint": true, "color": "#DF297D",
"unit":""
},
{
"name": "新会员",
"data": [
450,
260,
360,
560,
460,
170,
570
],
"type": "line",
"style": "curve",
"addPoint": true,
"color": "#ff9900",
"unit":""
}
],
"yAxis":[
{"calibration":true,"position":"left","min":0,"max":3000,"title":"","titleFontSize":12,"unit":"万","tofix":0}
],
"targetAdd":"9%"
}

@ -0,0 +1,32 @@
[
{
"kind":4,
"background":["#0081ff","#1cbbb4"],
"content":[
{"text":"已评价数","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"","value":"161","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"增长","value":"","colortext":"#fff","colorvalue":"","size":"20rpx"},
{"text":"up","value":"325","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
},
{
"kind":4,
"background":["#0081ff","#1cbbb4"],
"content":[
{"text":"平均分","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"","value":"82","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"增长","value":"","colortext":"#fff","colorvalue":"","size":"20rpx"},
{"text":"up","value":"0.7","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
},
{
"kind":4,
"background":["#0081ff","#1cbbb4"],
"content":[
{"text":"好评率","value":"","colortext":"#fff","colorvalue":"","size":"24rpx"},
{"text":"","value":"161","colortext":"","colorvalue":"#fff","size":"44rpx"},
{"text":"增长","value":"","colortext":"#fff","colorvalue":"","size":"20rpx"},
{"text":"down","value":"1.2%","colortext":"#fff","colorvalue":"#fff","size":"20rpx"}
]
}
]

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save