Parcourir la source

新建移动端

余思翰 il y a 3 mois
Parent
révision
dcc70e1723
100 fichiers modifiés avec 13052 ajouts et 0 suppressions
  1. 34
    0
      oa-ui-app/App.vue
  2. 21
    0
      oa-ui-app/LICENSE
  3. 52
    0
      oa-ui-app/README.md
  4. 47
    0
      oa-ui-app/api/login.js
  5. 41
    0
      oa-ui-app/api/system/user.js
  6. 167
    0
      oa-ui-app/components/uni-section/uni-section.vue
  7. 26
    0
      oa-ui-app/config.js
  8. 17
    0
      oa-ui-app/main.js
  9. 69
    0
      oa-ui-app/manifest.json
  10. 97
    0
      oa-ui-app/pages.json
  11. 43
    0
      oa-ui-app/pages/common/textview/index.vue
  12. 34
    0
      oa-ui-app/pages/common/webview/index.vue
  13. 43
    0
      oa-ui-app/pages/index.vue
  14. 188
    0
      oa-ui-app/pages/login.vue
  15. 63
    0
      oa-ui-app/pages/mine/about/index.vue
  16. 631
    0
      oa-ui-app/pages/mine/avatar/index.vue
  17. 112
    0
      oa-ui-app/pages/mine/help/index.vue
  18. 198
    0
      oa-ui-app/pages/mine/index.vue
  19. 127
    0
      oa-ui-app/pages/mine/info/edit.vue
  20. 44
    0
      oa-ui-app/pages/mine/info/index.vue
  21. 85
    0
      oa-ui-app/pages/mine/pwd/index.vue
  22. 78
    0
      oa-ui-app/pages/mine/setting/index.vue
  23. 183
    0
      oa-ui-app/pages/work/index.vue
  24. 39
    0
      oa-ui-app/permission.js
  25. 60
    0
      oa-ui-app/plugins/auth.js
  26. 14
    0
      oa-ui-app/plugins/index.js
  27. 74
    0
      oa-ui-app/plugins/modal.js
  28. 30
    0
      oa-ui-app/plugins/tab.js
  29. BIN
      oa-ui-app/static/favicon.ico
  30. 90
    0
      oa-ui-app/static/font/iconfont.css
  31. BIN
      oa-ui-app/static/font/iconfont.ttf
  32. BIN
      oa-ui-app/static/images/banner/banner01.jpg
  33. BIN
      oa-ui-app/static/images/banner/banner02.jpg
  34. BIN
      oa-ui-app/static/images/banner/banner03.jpg
  35. BIN
      oa-ui-app/static/images/profile.jpg
  36. BIN
      oa-ui-app/static/images/tabbar/home.png
  37. BIN
      oa-ui-app/static/images/tabbar/home_.png
  38. BIN
      oa-ui-app/static/images/tabbar/mine.png
  39. BIN
      oa-ui-app/static/images/tabbar/mine_.png
  40. BIN
      oa-ui-app/static/images/tabbar/work.png
  41. BIN
      oa-ui-app/static/images/tabbar/work_.png
  42. 20
    0
      oa-ui-app/static/index.html
  43. BIN
      oa-ui-app/static/logo.png
  44. BIN
      oa-ui-app/static/logo200.png
  45. 3912
    0
      oa-ui-app/static/scss/colorui.css
  46. 90
    0
      oa-ui-app/static/scss/global.scss
  47. 6
    0
      oa-ui-app/static/scss/index.scss
  48. 8
    0
      oa-ui-app/store/getters.js
  49. 15
    0
      oa-ui-app/store/index.js
  50. 98
    0
      oa-ui-app/store/modules/user.js
  51. 64
    0
      oa-ui-app/uni.scss
  52. 31
    0
      oa-ui-app/uni_modules/uni-badge/changelog.md
  53. 268
    0
      oa-ui-app/uni_modules/uni-badge/components/uni-badge/uni-badge.vue
  54. 85
    0
      oa-ui-app/uni_modules/uni-badge/package.json
  55. 10
    0
      oa-ui-app/uni_modules/uni-badge/readme.md
  56. 6
    0
      oa-ui-app/uni_modules/uni-breadcrumb/changelog.md
  57. 121
    0
      oa-ui-app/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue
  58. 41
    0
      oa-ui-app/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue
  59. 88
    0
      oa-ui-app/uni_modules/uni-breadcrumb/package.json
  60. 66
    0
      oa-ui-app/uni_modules/uni-breadcrumb/readme.md
  61. 20
    0
      oa-ui-app/uni_modules/uni-calendar/changelog.md
  62. 546
    0
      oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/calendar.js
  63. 12
    0
      oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json
  64. 8
    0
      oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js
  65. 12
    0
      oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json
  66. 12
    0
      oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json
  67. 188
    0
      oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue
  68. 562
    0
      oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue
  69. 350
    0
      oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/util.js
  70. 85
    0
      oa-ui-app/uni_modules/uni-calendar/package.json
  71. 103
    0
      oa-ui-app/uni_modules/uni-calendar/readme.md
  72. 26
    0
      oa-ui-app/uni_modules/uni-card/changelog.md
  73. 270
    0
      oa-ui-app/uni_modules/uni-card/components/uni-card/uni-card.vue
  74. 90
    0
      oa-ui-app/uni_modules/uni-card/package.json
  75. 12
    0
      oa-ui-app/uni_modules/uni-card/readme.md
  76. 36
    0
      oa-ui-app/uni_modules/uni-collapse/changelog.md
  77. 402
    0
      oa-ui-app/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue
  78. 147
    0
      oa-ui-app/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue
  79. 89
    0
      oa-ui-app/uni_modules/uni-collapse/package.json
  80. 12
    0
      oa-ui-app/uni_modules/uni-collapse/readme.md
  81. 15
    0
      oa-ui-app/uni_modules/uni-combox/changelog.md
  82. 275
    0
      oa-ui-app/uni_modules/uni-combox/components/uni-combox/uni-combox.vue
  83. 90
    0
      oa-ui-app/uni_modules/uni-combox/package.json
  84. 11
    0
      oa-ui-app/uni_modules/uni-combox/readme.md
  85. 24
    0
      oa-ui-app/uni_modules/uni-countdown/changelog.md
  86. 6
    0
      oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json
  87. 8
    0
      oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/i18n/index.js
  88. 6
    0
      oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json
  89. 6
    0
      oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json
  90. 271
    0
      oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
  91. 86
    0
      oa-ui-app/uni_modules/uni-countdown/package.json
  92. 10
    0
      oa-ui-app/uni_modules/uni-countdown/readme.md
  93. 45
    0
      oa-ui-app/uni_modules/uni-data-checkbox/changelog.md
  94. 821
    0
      oa-ui-app/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
  95. 84
    0
      oa-ui-app/uni_modules/uni-data-checkbox/package.json
  96. 18
    0
      oa-ui-app/uni_modules/uni-data-checkbox/readme.md
  97. 66
    0
      oa-ui-app/uni_modules/uni-data-picker/changelog.md
  98. 45
    0
      oa-ui-app/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
  99. 547
    0
      oa-ui-app/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
  100. 0
    0
      oa-ui-app/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js

+ 34
- 0
oa-ui-app/App.vue Voir le fichier

@@ -0,0 +1,34 @@
1
+<script>
2
+  import config from './config'
3
+  import store from '@/store'
4
+  import { getToken } from '@/utils/auth'
5
+
6
+  export default {
7
+    onLaunch: function() {
8
+      this.initApp()
9
+    },
10
+    methods: {
11
+      // 初始化应用
12
+      initApp() {
13
+        // 初始化应用配置
14
+        this.initConfig()
15
+        // 检查用户登录状态
16
+        //#ifdef H5
17
+        this.checkLogin()
18
+        //#endif
19
+      },
20
+      initConfig() {
21
+        this.globalData.config = config
22
+      },
23
+      checkLogin() {
24
+        if (!getToken()) {
25
+          this.$tab.reLaunch('/pages/login') 
26
+        }
27
+      }
28
+    }
29
+  }
30
+</script>
31
+
32
+<style lang="scss">
33
+  @import '@/static/scss/index.scss'
34
+</style>

+ 21
- 0
oa-ui-app/LICENSE Voir le fichier

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

+ 52
- 0
oa-ui-app/README.md Voir le fichier

@@ -0,0 +1,52 @@
1
+<p align="center">
2
+	<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-43e3941654fa3054c9684bf53d1b1d356a1.png">
3
+</p>
4
+<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v1.1.0</h1>
5
+<h4 align="center">基于UniApp开发的轻量级移动端框架</h4>
6
+<p align="center">
7
+	<a href="https://gitee.com/y_project/RuoYi-App/stargazers"><img src="https://gitee.com/y_project/RuoYi-App/badge/star.svg?theme=dark"></a>
8
+	<a href="https://gitee.com/y_project/RuoYi-App"><img src="https://img.shields.io/badge/RuoYi-v1.1.0-brightgreen.svg"></a>
9
+	<a href="https://gitee.com/y_project/RuoYi-App/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
10
+</p>
11
+
12
+## 平台简介
13
+
14
+RuoYi App 移动解决方案,采用uniapp框架,一份代码多终端适配,同时支持APP、小程序、H5!实现了与[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)、[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)完美对接的移动解决方案!目前已经实现登录、我的、工作台、编辑资料、头像修改、密码修改、常见问题、关于我们等基础功能。
15
+
16
+* 配套后端代码仓库地址[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) 或 [RuoYi-Cloud](https://github.com/yangzongzhuan/RuoYi-Cloud) 版本。
17
+* 应用框架基于[uniapp](https://uniapp.dcloud.net.cn/),支持小程序、H5、Android和IOS。
18
+* 前端组件采用[uni-ui](https://github.com/dcloudio/uni-ui),全端兼容的高性能UI框架。
19
+* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
20
+* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
21
+
22
+
23
+## 技术文档
24
+
25
+- 官网网站:[http://ruoyi.vip](http://ruoyi.vip)
26
+- 文档地址:[http://doc.ruoyi.vip](http://doc.ruoyi.vip)
27
+- H5页体验:[http://h5.ruoyi.vip](http://h5.ruoyi.vip)
28
+- QQ交流群: ①133713780
29
+- 小程序体验
30
+
31
+<img src="https://oscimg.oschina.net/oscnet/up-26c76dc90b92acdbd9ac8cd5252f07c8ad9.jpg" alt="小程序演示"/>
32
+ 
33
+
34
+## 演示图
35
+
36
+<table>
37
+    <tr>
38
+        <td><img src="https://oscimg.oschina.net/oscnet/up-3ea20e447ac621a161e395fb53ccc683d84.png"/></td>
39
+        <td><img src="https://oscimg.oschina.net/oscnet/up-a6f23cf9a371a30165e135eff6d9ae89a9d.png"/></td>
40
+		<td><img src="https://oscimg.oschina.net/oscnet/up-ff5f62016bf6624c1ff27eee57499dccd44.png"/></td>
41
+    </tr>
42
+	<tr>
43
+        <td><img src="https://oscimg.oschina.net/oscnet/up-b9a582fdb26ec69d407fabd044d2c8494df.png"/></td>
44
+        <td><img src="https://oscimg.oschina.net/oscnet/up-96427ee08fca29d77934cfc8d1b1a637cef.png"/></td>
45
+		<td><img src="https://oscimg.oschina.net/oscnet/up-5fdadc582d24cccd7727030d397b63185a3.png"/></td>
46
+    </tr>
47
+	<tr>
48
+        <td><img src="https://oscimg.oschina.net/oscnet/up-0a36797b6bcc50c36d40c3c782665b89efc.png"/></td>
49
+        <td><img src="https://oscimg.oschina.net/oscnet/up-d77995cc00687cedd00d5ac7d68a07ea276.png"/></td>
50
+		<td><img src="https://oscimg.oschina.net/oscnet/up-fa8f5ab20becf59b4b38c1b92a9989e7109.png"/></td>
51
+    </tr>
52
+</table>

+ 47
- 0
oa-ui-app/api/login.js Voir le fichier

@@ -0,0 +1,47 @@
1
+import request from '@/utils/request'
2
+
3
+// 登录方法
4
+export function login(username, password, code, uuid) {
5
+  const data = {
6
+    username,
7
+    password,
8
+    code,
9
+    uuid
10
+  }
11
+  return request({
12
+    'url': '/login',
13
+    headers: {
14
+      isToken: false
15
+    },
16
+    'method': 'post',
17
+    'data': data
18
+  })
19
+}
20
+
21
+// 获取用户详细信息
22
+export function getInfo() {
23
+  return request({
24
+    'url': '/getInfo',
25
+    'method': 'get'
26
+  })
27
+}
28
+
29
+// 退出方法
30
+export function logout() {
31
+  return request({
32
+    'url': '/logout',
33
+    'method': 'post'
34
+  })
35
+}
36
+
37
+// 获取验证码
38
+export function getCodeImg() {
39
+  return request({
40
+    'url': '/captchaImage',
41
+    headers: {
42
+      isToken: false
43
+    },
44
+    method: 'get',
45
+    timeout: 20000
46
+  })
47
+}

+ 41
- 0
oa-ui-app/api/system/user.js Voir le fichier

@@ -0,0 +1,41 @@
1
+import upload from '@/utils/upload'
2
+import request from '@/utils/request'
3
+
4
+// 用户密码重置
5
+export function updateUserPwd(oldPassword, newPassword) {
6
+  const data = {
7
+    oldPassword,
8
+    newPassword
9
+  }
10
+  return request({
11
+    url: '/system/user/profile/updatePwd',
12
+    method: 'put',
13
+    params: data
14
+  })
15
+}
16
+
17
+// 查询用户个人信息
18
+export function getUserProfile() {
19
+  return request({
20
+    url: '/system/user/profile',
21
+    method: 'get'
22
+  })
23
+}
24
+
25
+// 修改用户个人信息
26
+export function updateUserProfile(data) {
27
+  return request({
28
+    url: '/system/user/profile',
29
+    method: 'put',
30
+    data: data
31
+  })
32
+}
33
+
34
+// 用户头像上传
35
+export function uploadAvatar(data) {
36
+  return upload({
37
+    url: '/system/user/profile/avatar',
38
+    name: data.name,
39
+    filePath: data.filePath
40
+  })
41
+}

+ 167
- 0
oa-ui-app/components/uni-section/uni-section.vue Voir le fichier

@@ -0,0 +1,167 @@
1
+<template>
2
+	<view class="uni-section">
3
+		<view class="uni-section-header" @click="onClick">
4
+				<view class="uni-section-header__decoration" v-if="type" :class="type" />
5
+        <slot v-else name="decoration"></slot>
6
+
7
+        <view class="uni-section-header__content">
8
+          <text :style="{'font-size':titleFontSize,'color':titleColor}" class="uni-section__content-title" :class="{'distraction':!subTitle}">{{ title }}</text>
9
+          <text v-if="subTitle" :style="{'font-size':subTitleFontSize,'color':subTitleColor}" class="uni-section-header__content-sub">{{ subTitle }}</text>
10
+        </view>
11
+
12
+        <view class="uni-section-header__slot-right">
13
+          <slot name="right"></slot>
14
+        </view>
15
+		</view>
16
+
17
+		<view class="uni-section-content" :style="{padding: _padding}">
18
+			<slot />
19
+		</view>
20
+	</view>
21
+</template>
22
+
23
+<script>
24
+
25
+	/**
26
+	 * Section 标题栏
27
+	 * @description 标题栏
28
+	 * @property {String} type = [line|circle|square] 标题装饰类型
29
+	 * 	@value line 竖线
30
+	 * 	@value circle 圆形
31
+	 * 	@value square 正方形
32
+	 * @property {String} title 主标题
33
+	 * @property {String} titleFontSize 主标题字体大小
34
+	 * @property {String} titleColor 主标题字体颜色
35
+	 * @property {String} subTitle 副标题
36
+	 * @property {String} subTitleFontSize 副标题字体大小
37
+	 * @property {String} subTitleColor 副标题字体颜色
38
+	 * @property {String} padding 默认插槽 padding
39
+	 */
40
+
41
+	export default {
42
+		name: 'UniSection',
43
+    emits:['click'],
44
+		props: {
45
+			type: {
46
+				type: String,
47
+				default: ''
48
+			},
49
+			title: {
50
+				type: String,
51
+				required: true,
52
+				default: ''
53
+			},
54
+      titleFontSize: {
55
+        type: String,
56
+        default: '14px'
57
+      },
58
+			titleColor:{
59
+				type: String,
60
+				default: '#333'
61
+			},
62
+			subTitle: {
63
+				type: String,
64
+				default: ''
65
+			},
66
+      subTitleFontSize: {
67
+        type: String,
68
+        default: '12px'
69
+      },
70
+      subTitleColor: {
71
+        type: String,
72
+        default: '#999'
73
+      },
74
+			padding: {
75
+				type: [Boolean, String],
76
+				default: false
77
+			}
78
+		},
79
+    computed:{
80
+      _padding(){
81
+        if(typeof this.padding === 'string'){
82
+          return this.padding
83
+        }
84
+
85
+        return this.padding?'10px':''
86
+      }
87
+    },
88
+		watch: {
89
+			title(newVal) {
90
+				if (uni.report && newVal !== '') {
91
+					uni.report('title', newVal)
92
+				}
93
+			}
94
+		},
95
+    methods: {
96
+			onClick() {
97
+				this.$emit('click')
98
+			}
99
+		}
100
+	}
101
+</script>
102
+<style lang="scss" >
103
+	$uni-primary: #2979ff !default;
104
+
105
+	.uni-section {
106
+		background-color: #fff;
107
+    .uni-section-header {
108
+      position: relative;
109
+      /* #ifndef APP-NVUE */
110
+      display: flex;
111
+      /* #endif */
112
+      flex-direction: row;
113
+      align-items: center;
114
+      padding: 12px 10px;
115
+      font-weight: normal;
116
+
117
+      &__decoration{
118
+        margin-right: 6px;
119
+        background-color: $uni-primary;
120
+        &.line {
121
+          width: 4px;
122
+          height: 12px;
123
+          border-radius: 10px;
124
+        }
125
+
126
+        &.circle {
127
+          width: 8px;
128
+          height: 8px;
129
+          border-top-right-radius: 50px;
130
+          border-top-left-radius: 50px;
131
+          border-bottom-left-radius: 50px;
132
+          border-bottom-right-radius: 50px;
133
+        }
134
+
135
+        &.square {
136
+          width: 8px;
137
+          height: 8px;
138
+        }
139
+      }
140
+
141
+      &__content {
142
+        /* #ifndef APP-NVUE */
143
+        display: flex;
144
+        /* #endif */
145
+        flex-direction: column;
146
+        flex: 1;
147
+        color: #333;
148
+
149
+        .distraction {
150
+          flex-direction: row;
151
+          align-items: center;
152
+        }
153
+        &-sub {
154
+          margin-top: 2px;
155
+        }
156
+      }
157
+
158
+      &__slot-right{
159
+        font-size: 14px;
160
+      }
161
+    }
162
+
163
+    .uni-section-content{
164
+      font-size: 14px;
165
+    }
166
+	}
167
+</style>

+ 26
- 0
oa-ui-app/config.js Voir le fichier

@@ -0,0 +1,26 @@
1
+// 应用全局配置
2
+module.exports = {
3
+  // baseUrl: 'https://vue.ruoyi.vip/prod-api',
4
+  baseUrl: 'http://localhost:8080',
5
+  // 应用信息
6
+  appInfo: {
7
+    // 应用名称
8
+    name: "cmc-oa-app",
9
+    // 应用版本
10
+    version: "1.1.0",
11
+    // 应用logo
12
+    logo: "/static/logo.png",
13
+    // 官方网站
14
+    site_url: "https://www.sccehui.com/",
15
+    // 政策协议
16
+    agreements: [{
17
+        title: "隐私政策",
18
+        url: "https://ruoyi.vip/protocol.html"
19
+      },
20
+      {
21
+        title: "用户服务协议",
22
+        url: "https://ruoyi.vip/protocol.html"
23
+      }
24
+    ]
25
+  }
26
+}

+ 17
- 0
oa-ui-app/main.js Voir le fichier

@@ -0,0 +1,17 @@
1
+import Vue from 'vue'
2
+import App from './App'
3
+import store from './store' // store
4
+import plugins from './plugins' // plugins
5
+import './permission' // permission
6
+Vue.use(plugins)
7
+
8
+Vue.config.productionTip = false
9
+Vue.prototype.$store = store
10
+
11
+App.mpType = 'app'
12
+
13
+const app = new Vue({
14
+  ...App
15
+})
16
+
17
+app.$mount()

+ 69
- 0
oa-ui-app/manifest.json Voir le fichier

@@ -0,0 +1,69 @@
1
+{
2
+    "name" : "CMC综合办公系统移动端",
3
+    "appid" : "__UNI__25A9D80",
4
+    "description" : "",
5
+    "versionName" : "1.1.0",
6
+    "versionCode" : "100",
7
+    "transformPx" : false,
8
+    "app-plus" : {
9
+        "usingComponents" : true,
10
+        "nvueCompiler" : "uni-app",
11
+        "splashscreen" : {
12
+            "alwaysShowBeforeRender" : true,
13
+            "waiting" : true,
14
+            "autoclose" : true,
15
+            "delay" : 0
16
+        },
17
+        "modules" : {},
18
+        "distribute" : {
19
+            "android" : {
20
+                "permissions" : [
21
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
22
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
23
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
24
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
25
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
26
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
27
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
28
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
29
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
30
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
31
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
32
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
33
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
34
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
35
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
36
+                ]
37
+            },
38
+            "ios" : {},
39
+            "sdkConfigs" : {}
40
+        }
41
+    },
42
+    "quickapp" : {},
43
+    "mp-weixin" : {
44
+        "appid" : "wxccd7e2a0911b3397",
45
+        "setting" : {
46
+            "urlCheck" : false,
47
+            "es6" : false,
48
+            "minified" : true,
49
+            "postcss" : true
50
+        },
51
+        "optimization" : {
52
+            "subPackages" : true
53
+        },
54
+        "usingComponents" : true
55
+    },
56
+    "vueVersion" : "2",
57
+    "h5" : {
58
+        "template" : "static/index.html",
59
+        "devServer" : {
60
+            "port" : 9090,
61
+            "https" : false
62
+        },
63
+        "title" : "RuoYi-App",
64
+        "router" : {
65
+            "mode" : "hash",
66
+            "base" : "./"
67
+        }
68
+    }
69
+}

+ 97
- 0
oa-ui-app/pages.json Voir le fichier

@@ -0,0 +1,97 @@
1
+{
2
+  "pages": [{
3
+    "path": "pages/login",
4
+    "style": {
5
+      "navigationBarTitleText": "登录"
6
+    }
7
+  }, {
8
+    "path": "pages/index",
9
+    "style": {
10
+      "navigationBarTitleText": "CMC综合办公系统移动端",
11
+      "navigationStyle": "custom"
12
+    }
13
+  }, {
14
+    "path": "pages/work/index",
15
+    "style": {
16
+      "navigationBarTitleText": "工作台"
17
+    }
18
+  }, {
19
+    "path": "pages/mine/index",
20
+    "style": {
21
+      "navigationBarTitleText": "我的"
22
+    }
23
+  }, {
24
+    "path": "pages/mine/avatar/index",
25
+    "style": {
26
+      "navigationBarTitleText": "修改头像"
27
+    }
28
+  }, {
29
+    "path": "pages/mine/info/index",
30
+    "style": {
31
+      "navigationBarTitleText": "个人信息"
32
+    }
33
+  }, {
34
+    "path": "pages/mine/info/edit",
35
+    "style": {
36
+      "navigationBarTitleText": "编辑资料"
37
+    }
38
+  }, {
39
+    "path": "pages/mine/pwd/index",
40
+    "style": {
41
+      "navigationBarTitleText": "修改密码"
42
+    }
43
+  }, {
44
+    "path": "pages/mine/setting/index",
45
+    "style": {
46
+      "navigationBarTitleText": "应用设置"
47
+    }
48
+  }, {
49
+    "path": "pages/mine/help/index",
50
+    "style": {
51
+      "navigationBarTitleText": "常见问题"
52
+    }
53
+  }, {
54
+    "path": "pages/mine/about/index",
55
+    "style": {
56
+      "navigationBarTitleText": "关于我们"
57
+    }
58
+  }, {
59
+    "path": "pages/common/webview/index",
60
+    "style": {
61
+      "navigationBarTitleText": "浏览网页"
62
+    }
63
+  }, {
64
+    "path": "pages/common/textview/index",
65
+    "style": {
66
+      "navigationBarTitleText": "浏览文本"
67
+    }
68
+  }],
69
+  "tabBar": {
70
+    "color": "#000000",
71
+    "selectedColor": "#000000",
72
+    "borderStyle": "white",
73
+    "backgroundColor": "#ffffff",
74
+    "list": [{
75
+        "pagePath": "pages/index",
76
+        "iconPath": "static/images/tabbar/home.png",
77
+        "selectedIconPath": "static/images/tabbar/home_.png",
78
+        "text": "首页"
79
+      }, {
80
+        "pagePath": "pages/work/index",
81
+        "iconPath": "static/images/tabbar/work.png",
82
+        "selectedIconPath": "static/images/tabbar/work_.png",
83
+        "text": "工作台"
84
+      }, {
85
+        "pagePath": "pages/mine/index",
86
+        "iconPath": "static/images/tabbar/mine.png",
87
+        "selectedIconPath": "static/images/tabbar/mine_.png",
88
+        "text": "我的"
89
+      }
90
+    ]
91
+  },
92
+  "globalStyle": {
93
+    "navigationBarTextStyle": "black",
94
+    "navigationBarTitleText": "RuoYi",
95
+    "navigationBarBackgroundColor": "#FFFFFF"
96
+  }
97
+}

+ 43
- 0
oa-ui-app/pages/common/textview/index.vue Voir le fichier

@@ -0,0 +1,43 @@
1
+<template>
2
+  <view>
3
+    <uni-card class="view-title" :title="title">
4
+      <text class="uni-body view-content">{{ content }}</text>
5
+    </uni-card>
6
+  </view>
7
+</template>
8
+
9
+<script>
10
+  export default {
11
+    data() {
12
+      return {
13
+        title: '',
14
+        content: ''
15
+      }
16
+    },
17
+    onLoad(options) {
18
+      this.title = options.title
19
+      this.content = options.content
20
+      uni.setNavigationBarTitle({
21
+        title: options.title
22
+      })
23
+    }
24
+  }
25
+</script>
26
+
27
+<style scoped>
28
+  page {
29
+    background-color: #ffffff;
30
+  }
31
+
32
+  .view-title {
33
+    font-weight: bold;
34
+  }
35
+
36
+  .view-content {
37
+    font-size: 26rpx;
38
+    padding: 12px 5px 0;
39
+    color: #333;
40
+    line-height: 24px;
41
+    font-weight: normal;
42
+  }
43
+</style>

+ 34
- 0
oa-ui-app/pages/common/webview/index.vue Voir le fichier

@@ -0,0 +1,34 @@
1
+<template>
2
+  <view v-if="params.url">
3
+    <web-view :webview-styles="webviewStyles" :src="`${params.url}`"></web-view>
4
+  </view>
5
+</template>
6
+
7
+<script>
8
+  export default {
9
+    data() {
10
+      return {
11
+        params: {},
12
+        webviewStyles: {
13
+          progress: {
14
+            color: "#FF3333"
15
+          }
16
+        }
17
+      }
18
+    },
19
+    props: {
20
+      src: {
21
+        type: [String],
22
+        default: null
23
+      }
24
+    },
25
+    onLoad(event) {
26
+      this.params = event
27
+      if (event.title) {
28
+        uni.setNavigationBarTitle({
29
+          title: event.title
30
+        })
31
+      }
32
+    }
33
+  }
34
+</script>

+ 43
- 0
oa-ui-app/pages/index.vue Voir le fichier

@@ -0,0 +1,43 @@
1
+<template>
2
+  <view class="content">
3
+    <image class="logo" src="@/static/logo.png"></image>
4
+    <view class="text-area">
5
+      <text class="title">Hello RuoYi</text>
6
+    </view>
7
+  </view>
8
+</template>
9
+
10
+<script>
11
+  export default {
12
+    onLoad: function() {
13
+    }
14
+  }
15
+</script>
16
+
17
+<style>
18
+  .content {
19
+    display: flex;
20
+    flex-direction: column;
21
+    align-items: center;
22
+    justify-content: center;
23
+  }
24
+
25
+  .logo {
26
+    height: 200rpx;
27
+    width: 200rpx;
28
+    margin-top: 200rpx;
29
+    margin-left: auto;
30
+    margin-right: auto;
31
+    margin-bottom: 50rpx;
32
+  }
33
+
34
+  .text-area {
35
+    display: flex;
36
+    justify-content: center;
37
+  }
38
+
39
+  .title {
40
+    font-size: 36rpx;
41
+    color: #8f8f94;
42
+  }
43
+</style>

+ 188
- 0
oa-ui-app/pages/login.vue Voir le fichier

@@ -0,0 +1,188 @@
1
+<template>
2
+  <view class="normal-login-container">
3
+    <view class="logo-content align-center justify-center flex">
4
+      <image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
5
+      </image>
6
+      <text class="title">CMC综合办公系统</text>
7
+    </view>
8
+    <view class="login-form-content">
9
+      <view class="input-item flex align-center">
10
+        <view class="iconfont icon-user icon"></view>
11
+        <input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" />
12
+      </view>
13
+      <view class="input-item flex align-center">
14
+        <view class="iconfont icon-password icon"></view>
15
+        <input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" />
16
+      </view>
17
+      <view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
18
+        <view class="iconfont icon-code icon"></view>
19
+        <input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" />
20
+        <view class="login-code"> 
21
+          <image :src="codeUrl" @click="getCode" class="login-code-img"></image>
22
+        </view  >
23
+      </view>
24
+      <view class="action-btn">
25
+        <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button>
26
+      </view>
27
+    </view>
28
+
29
+    <view class="xieyi text-center">
30
+      <text class="text-grey1">登录即代表同意</text>
31
+      <text @click="handleUserAgrement" class="text-blue">《用户协议》</text>
32
+      <text @click="handlePrivacy" class="text-blue">《隐私协议》</text>
33
+    </view>
34
+  </view>
35
+</template>
36
+
37
+<script>
38
+  import { getCodeImg } from '@/api/login'
39
+
40
+  export default {
41
+    data() {
42
+      return {
43
+        codeUrl: "",
44
+        captchaEnabled: true,
45
+        globalConfig: getApp().globalData.config,
46
+        loginForm: {
47
+          username: "admin",
48
+          password: "admin123",
49
+          code: "",
50
+          uuid: ''
51
+        }
52
+      }
53
+    },
54
+    created() {
55
+      this.getCode()
56
+    },
57
+    methods: {
58
+      // 隐私协议
59
+      handlePrivacy() {
60
+        let site = this.globalConfig.appInfo.agreements[0]
61
+        this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
62
+      },
63
+      // 用户协议
64
+      handleUserAgrement() {
65
+        let site = this.globalConfig.appInfo.agreements[1]
66
+        this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
67
+      },
68
+      // 获取图形验证码
69
+      getCode() {
70
+        getCodeImg().then(res => {
71
+          this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
72
+          if (this.captchaEnabled) {
73
+            this.codeUrl = 'data:image/gif;base64,' + res.img
74
+            this.loginForm.uuid = res.uuid
75
+          }
76
+        })
77
+      },
78
+      // 登录方法
79
+      async handleLogin() {
80
+        if (this.loginForm.username === "") {
81
+          this.$modal.msgError("请输入您的账号")
82
+        } else if (this.loginForm.password === "") {
83
+          this.$modal.msgError("请输入您的密码")
84
+        } else if (this.loginForm.code === "" && this.captchaEnabled) {
85
+          this.$modal.msgError("请输入验证码")
86
+        } else {
87
+          this.$modal.loading("登录中,请耐心等待...")
88
+          this.pwdLogin()
89
+        }
90
+      },
91
+      // 密码登录
92
+      async pwdLogin() {
93
+        this.$store.dispatch('Login', this.loginForm).then(() => {
94
+          this.$modal.closeLoading()
95
+          this.loginSuccess()
96
+        }).catch(() => {
97
+          if (this.captchaEnabled) {
98
+            this.getCode()
99
+          }
100
+        })
101
+      },
102
+      // 登录成功后,处理函数
103
+      loginSuccess(result) {
104
+        // 设置用户信息
105
+        this.$store.dispatch('GetInfo').then(res => {
106
+          this.$tab.reLaunch('/pages/index')
107
+        })
108
+      }
109
+    }
110
+  }
111
+</script>
112
+
113
+<style lang="scss">
114
+  page {
115
+    background-color: #ffffff;
116
+  }
117
+
118
+  .normal-login-container {
119
+    width: 100%;
120
+
121
+    .logo-content {
122
+      width: 100%;
123
+      font-size: 21px;
124
+      text-align: center;
125
+      padding-top: 15%;
126
+
127
+      image {
128
+        border-radius: 4px;
129
+      }
130
+
131
+      .title {
132
+        margin-left: 10px;
133
+      }
134
+    }
135
+
136
+    .login-form-content {
137
+      text-align: center;
138
+      margin: 20px auto;
139
+      margin-top: 15%;
140
+      width: 80%;
141
+
142
+      .input-item {
143
+        margin: 20px auto;
144
+        background-color: #f5f6f7;
145
+        height: 45px;
146
+        border-radius: 20px;
147
+
148
+        .icon {
149
+          font-size: 38rpx;
150
+          margin-left: 10px;
151
+          color: #999;
152
+        }
153
+
154
+        .input {
155
+          width: 100%;
156
+          font-size: 14px;
157
+          line-height: 20px;
158
+          text-align: left;
159
+          padding-left: 15px;
160
+        }
161
+
162
+      }
163
+
164
+      .login-btn {
165
+        margin-top: 40px;
166
+        height: 45px;
167
+      }
168
+
169
+      .xieyi {
170
+        color: #333;
171
+        margin-top: 20px;
172
+      }
173
+      
174
+      .login-code {
175
+        height: 38px;
176
+        float: right;
177
+      
178
+        .login-code-img {
179
+          height: 38px;
180
+          position: absolute;
181
+          margin-left: 10px;
182
+          width: 200rpx;
183
+        }
184
+      }
185
+    }
186
+  }
187
+
188
+</style>

+ 63
- 0
oa-ui-app/pages/mine/about/index.vue Voir le fichier

@@ -0,0 +1,63 @@
1
+<template>
2
+  <view class="about-container">
3
+    <view class="header-section text-center">
4
+      <image style="width: 150rpx;height: 150rpx;" src="/static/logo.png" mode="widthFix">
5
+      </image>
6
+      <uni-title type="h2" title="CMC综合办公移动端"></uni-title>
7
+    </view>
8
+
9
+    <view class="content-section">
10
+      <view class="menu-list">
11
+        <view class="list-cell list-cell-arrow">
12
+          <view class="menu-item-box">
13
+            <view>版本信息</view>
14
+            <view class="text-right">v{{version}}</view>
15
+          </view>
16
+        </view>
17
+        <view class="list-cell list-cell-arrow">
18
+          <view class="menu-item-box">
19
+            <view>公司网站</view>
20
+            <view class="text-right">
21
+              <uni-link :href="url" :text="url" showUnderLine="false"></uni-link>
22
+            </view>
23
+          </view>
24
+        </view>
25
+      </view>
26
+    </view>
27
+
28
+    <view class="copyright">
29
+      <view>Copyright &copy; 2025 cmc All Rights Reserved.</view>
30
+    </view>
31
+  </view>
32
+</template>
33
+
34
+<script>
35
+  export default {
36
+    data() {
37
+      return {
38
+        url: getApp().globalData.config.appInfo.site_url,
39
+        version: getApp().globalData.config.appInfo.version
40
+      }
41
+    }
42
+  }
43
+</script>
44
+
45
+<style lang="scss">
46
+  page {
47
+    background-color: #f8f8f8;
48
+  }
49
+
50
+  .copyright {
51
+    margin-top: 50rpx;
52
+    text-align: center;
53
+    line-height: 60rpx;
54
+    color: #999;
55
+  }
56
+
57
+  .header-section {
58
+    display: flex;
59
+    padding: 30rpx 0 0;
60
+    flex-direction: column;
61
+    align-items: center;
62
+  }
63
+</style>

+ 631
- 0
oa-ui-app/pages/mine/avatar/index.vue Voir le fichier

@@ -0,0 +1,631 @@
1
+<template>
2
+	<view class="container">
3
+		<view class="page-body uni-content-info">
4
+			<view class='cropper-content'>
5
+				<view v-if="isShowImg" class="uni-corpper" :style="'width:'+cropperInitW+'px;height:'+cropperInitH+'px;background:#000'">
6
+					<view class="uni-corpper-content" :style="'width:'+cropperW+'px;height:'+cropperH+'px;left:'+cropperL+'px;top:'+cropperT+'px'">
7
+						<image :src="imageSrc" :style="'width:'+cropperW+'px;height:'+cropperH+'px'"></image>
8
+						<view class="uni-corpper-crop-box" @touchstart.stop="contentStartMove" @touchmove.stop="contentMoveing" @touchend.stop="contentTouchEnd"
9
+						    :style="'left:'+cutL+'px;top:'+cutT+'px;right:'+cutR+'px;bottom:'+cutB+'px'">
10
+							<view class="uni-cropper-view-box">
11
+								<view class="uni-cropper-dashed-h"></view>
12
+								<view class="uni-cropper-dashed-v"></view>
13
+								<view class="uni-cropper-line-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
14
+								<view class="uni-cropper-line-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
15
+								<view class="uni-cropper-line-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
16
+								<view class="uni-cropper-line-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
17
+								<view class="uni-cropper-point point-t" data-drag="top" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
18
+								<view class="uni-cropper-point point-tr" data-drag="topTight"></view>
19
+								<view class="uni-cropper-point point-r" data-drag="right" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
20
+								<view class="uni-cropper-point point-rb" data-drag="rightBottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
21
+								<view class="uni-cropper-point point-b" data-drag="bottom" @touchstart.stop="dragStart" @touchmove.stop="dragMove" @touchend.stop="dragEnd"></view>
22
+								<view class="uni-cropper-point point-bl" data-drag="bottomLeft"></view>
23
+								<view class="uni-cropper-point point-l" data-drag="left" @touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
24
+								<view class="uni-cropper-point point-lt" data-drag="leftTop"></view>
25
+							</view>
26
+						</view>
27
+					</view>
28
+				</view>
29
+			</view>
30
+			<view class='cropper-config'>
31
+				<button type="primary reverse" @click="getImage" style='margin-top: 30rpx;'> 选择头像 </button>
32
+				<button type="warn" @click="getImageInfo" style='margin-top: 30rpx;'> 提交 </button>
33
+			</view>
34
+			<canvas canvas-id="myCanvas" :style="'position:absolute;border: 1px solid red; width:'+imageW+'px;height:'+imageH+'px;top:-9999px;left:-9999px;'"></canvas>
35
+		</view>
36
+	</view>
37
+</template>
38
+
39
+<script>
40
+  import config from '@/config'
41
+  import store from "@/store"
42
+  import { uploadAvatar } from "@/api/system/user"
43
+  
44
+  const baseUrl = config.baseUrl
45
+	let sysInfo = uni.getSystemInfoSync()
46
+	let SCREEN_WIDTH = sysInfo.screenWidth
47
+	let PAGE_X, // 手按下的x位置
48
+		PAGE_Y, // 手按下y的位置 
49
+		PR = sysInfo.pixelRatio, // dpi
50
+		T_PAGE_X, // 手移动的时候x的位置
51
+		T_PAGE_Y, // 手移动的时候Y的位置
52
+		CUT_L, // 初始化拖拽元素的left值
53
+		CUT_T, // 初始化拖拽元素的top值
54
+		CUT_R, // 初始化拖拽元素的
55
+		CUT_B, // 初始化拖拽元素的
56
+		CUT_W, // 初始化拖拽元素的宽度
57
+		CUT_H, //  初始化拖拽元素的高度
58
+		IMG_RATIO, // 图片比例
59
+		IMG_REAL_W, // 图片实际的宽度
60
+		IMG_REAL_H, // 图片实际的高度
61
+		DRAFG_MOVE_RATIO = 1, //移动时候的比例,
62
+		INIT_DRAG_POSITION = 100, // 初始化屏幕宽度和裁剪区域的宽度之差,用于设置初始化裁剪的宽度
63
+		DRAW_IMAGE_W = sysInfo.screenWidth // 设置生成的图片宽度
64
+
65
+	export default {
66
+		/**
67
+		 * 页面的初始数据
68
+		 */
69
+		data() {
70
+			return {
71
+				imageSrc: store.getters.avatar,
72
+				isShowImg: false,
73
+				// 初始化的宽高
74
+				cropperInitW: SCREEN_WIDTH,
75
+				cropperInitH: SCREEN_WIDTH,
76
+				// 动态的宽高
77
+				cropperW: SCREEN_WIDTH,
78
+				cropperH: SCREEN_WIDTH,
79
+				// 动态的left top值
80
+				cropperL: 0,
81
+				cropperT: 0,
82
+
83
+				transL: 0,
84
+				transT: 0,
85
+
86
+				// 图片缩放值
87
+				scaleP: 0,
88
+				imageW: 0,
89
+				imageH: 0,
90
+
91
+				// 裁剪框 宽高
92
+				cutL: 0,
93
+				cutT: 0,
94
+				cutB: SCREEN_WIDTH,
95
+				cutR: '100%',
96
+				qualityWidth: DRAW_IMAGE_W,
97
+				innerAspectRadio: DRAFG_MOVE_RATIO
98
+			}
99
+		},
100
+		/**
101
+		 * 生命周期函数--监听页面初次渲染完成
102
+		 */
103
+		onReady: function () {
104
+			this.loadImage()
105
+		},
106
+		methods: {
107
+			setData: function (obj) {
108
+				let that = this
109
+				Object.keys(obj).forEach(function (key) {
110
+					that.$set(that.$data, key, obj[key])
111
+				})
112
+			},
113
+			getImage: function () {
114
+				var _this = this
115
+				uni.chooseImage({
116
+					success: function (res) {
117
+						_this.setData({
118
+							imageSrc: res.tempFilePaths[0],
119
+						})
120
+						_this.loadImage()
121
+					},
122
+				})
123
+			},
124
+			loadImage: function () {
125
+				var _this = this
126
+
127
+				uni.getImageInfo({
128
+					src: _this.imageSrc,
129
+					success: function success(res) {
130
+						IMG_RATIO = 1 / 1
131
+						if (IMG_RATIO >= 1) {
132
+							IMG_REAL_W = SCREEN_WIDTH
133
+							IMG_REAL_H = SCREEN_WIDTH / IMG_RATIO
134
+						} else {
135
+							IMG_REAL_W = SCREEN_WIDTH * IMG_RATIO
136
+							IMG_REAL_H = SCREEN_WIDTH
137
+						}
138
+						let minRange = IMG_REAL_W > IMG_REAL_H ? IMG_REAL_W : IMG_REAL_H
139
+						INIT_DRAG_POSITION = minRange > INIT_DRAG_POSITION ? INIT_DRAG_POSITION : minRange
140
+						// 根据图片的宽高显示不同的效果   保证图片可以正常显示
141
+						if (IMG_RATIO >= 1) {
142
+							let cutT = Math.ceil((SCREEN_WIDTH / IMG_RATIO - (SCREEN_WIDTH / IMG_RATIO - INIT_DRAG_POSITION)) / 2)
143
+							let cutB = cutT
144
+							let cutL = Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH + INIT_DRAG_POSITION) / 2)
145
+							let cutR = cutL
146
+							_this.setData({
147
+								cropperW: SCREEN_WIDTH,
148
+								cropperH: SCREEN_WIDTH / IMG_RATIO,
149
+								// 初始化left right
150
+								cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
151
+								cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH / IMG_RATIO) / 2),
152
+								cutL: cutL,
153
+								cutT: cutT,
154
+								cutR: cutR,
155
+								cutB: cutB,
156
+								// 图片缩放值
157
+								imageW: IMG_REAL_W,
158
+								imageH: IMG_REAL_H,
159
+								scaleP: IMG_REAL_W / SCREEN_WIDTH,
160
+								qualityWidth: DRAW_IMAGE_W,
161
+								innerAspectRadio: IMG_RATIO
162
+							})
163
+						} else {
164
+							let cutL = Math.ceil((SCREEN_WIDTH * IMG_RATIO - (SCREEN_WIDTH * IMG_RATIO)) / 2)
165
+							let cutR = cutL
166
+							let cutT = Math.ceil((SCREEN_WIDTH - INIT_DRAG_POSITION) / 2)
167
+							let cutB = cutT
168
+							_this.setData({
169
+								cropperW: SCREEN_WIDTH * IMG_RATIO,
170
+								cropperH: SCREEN_WIDTH,
171
+								// 初始化left right
172
+								cropperL: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH * IMG_RATIO) / 2),
173
+								cropperT: Math.ceil((SCREEN_WIDTH - SCREEN_WIDTH) / 2),
174
+
175
+								cutL: cutL,
176
+								cutT: cutT,
177
+								cutR: cutR,
178
+								cutB: cutB,
179
+								// 图片缩放值
180
+								imageW: IMG_REAL_W,
181
+								imageH: IMG_REAL_H,
182
+								scaleP: IMG_REAL_W / SCREEN_WIDTH,
183
+								qualityWidth: DRAW_IMAGE_W,
184
+								innerAspectRadio: IMG_RATIO
185
+							})
186
+						}
187
+						_this.setData({
188
+							isShowImg: true
189
+						})
190
+						uni.hideLoading()
191
+					}
192
+				})
193
+			},
194
+			// 拖动时候触发的touchStart事件
195
+			contentStartMove(e) {
196
+				PAGE_X = e.touches[0].pageX
197
+				PAGE_Y = e.touches[0].pageY
198
+			},
199
+
200
+			// 拖动时候触发的touchMove事件
201
+			contentMoveing(e) {
202
+				var _this = this
203
+				var dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
204
+				var dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
205
+				// 左移
206
+				if (dragLengthX > 0) {
207
+					if (this.cutL - dragLengthX < 0) dragLengthX = this.cutL
208
+				} else {
209
+					if (this.cutR + dragLengthX < 0) dragLengthX = -this.cutR
210
+				}
211
+
212
+				if (dragLengthY > 0) {
213
+					if (this.cutT - dragLengthY < 0) dragLengthY = this.cutT
214
+				} else {
215
+					if (this.cutB + dragLengthY < 0) dragLengthY = -this.cutB
216
+				}
217
+				this.setData({
218
+					cutL: this.cutL - dragLengthX,
219
+					cutT: this.cutT - dragLengthY,
220
+					cutR: this.cutR + dragLengthX,
221
+					cutB: this.cutB + dragLengthY
222
+				})
223
+
224
+				PAGE_X = e.touches[0].pageX
225
+				PAGE_Y = e.touches[0].pageY
226
+			},
227
+
228
+			contentTouchEnd() {
229
+
230
+			},
231
+
232
+			// 获取图片
233
+			getImageInfo() {
234
+				var _this = this
235
+				uni.showLoading({
236
+					title: '图片生成中...',
237
+				})
238
+				// 将图片写入画布
239
+				const ctx = uni.createCanvasContext('myCanvas')
240
+				ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H)
241
+				ctx.draw(true, () => {
242
+					// 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
243
+					var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W
244
+					var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H
245
+					var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W
246
+					var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H
247
+					uni.canvasToTempFilePath({
248
+						x: canvasL,
249
+						y: canvasT,
250
+						width: canvasW,
251
+						height: canvasH,
252
+						destWidth: canvasW,
253
+						destHeight: canvasH,
254
+						quality: 0.5,
255
+						canvasId: 'myCanvas',
256
+						success: function (res) {
257
+							uni.hideLoading()
258
+							let data = {name: 'avatarfile', filePath: res.tempFilePath}
259
+							uploadAvatar(data).then(response => {
260
+								store.commit('SET_AVATAR', baseUrl + response.imgUrl)
261
+								uni.showToast({ title: "修改成功", icon: 'success' })
262
+								uni.navigateBack()
263
+							})
264
+						}
265
+					})
266
+				})
267
+			},
268
+			// 设置大小的时候触发的touchStart事件
269
+			dragStart(e) {
270
+				T_PAGE_X = e.touches[0].pageX
271
+				T_PAGE_Y = e.touches[0].pageY
272
+				CUT_L = this.cutL
273
+				CUT_R = this.cutR
274
+				CUT_B = this.cutB
275
+				CUT_T = this.cutT
276
+			},
277
+
278
+			// 设置大小的时候触发的touchMove事件
279
+			dragMove(e) {
280
+				var _this = this
281
+				var dragType = e.target.dataset.drag
282
+				switch (dragType) {
283
+					case 'right':
284
+						var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
285
+						if (CUT_R + dragLength < 0) dragLength = -CUT_R
286
+						this.setData({
287
+							cutR: CUT_R + dragLength
288
+						})
289
+						break
290
+					case 'left':
291
+						var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
292
+						if (CUT_L - dragLength < 0) dragLength = CUT_L
293
+						if ((CUT_L - dragLength) > (this.cropperW - this.cutR)) dragLength = CUT_L - (this.cropperW - this.cutR)
294
+						this.setData({
295
+							cutL: CUT_L - dragLength
296
+						})
297
+						break
298
+					case 'top':
299
+						var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
300
+						if (CUT_T - dragLength < 0) dragLength = CUT_T
301
+						if ((CUT_T - dragLength) > (this.cropperH - this.cutB)) dragLength = CUT_T - (this.cropperH - this.cutB)
302
+						this.setData({
303
+							cutT: CUT_T - dragLength
304
+						})
305
+						break
306
+					case 'bottom':
307
+						var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
308
+						if (CUT_B + dragLength < 0) dragLength = -CUT_B
309
+						this.setData({
310
+							cutB: CUT_B + dragLength
311
+						})
312
+						break
313
+					case 'rightBottom':
314
+						var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO
315
+						var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO
316
+
317
+						if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B
318
+						if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R
319
+						let cutB = CUT_B + dragLengthY
320
+						let cutR = CUT_R + dragLengthX
321
+
322
+						this.setData({
323
+							cutB: cutB,
324
+							cutR: cutR
325
+						})
326
+						break
327
+					default:
328
+						break
329
+				}
330
+			}
331
+		}
332
+	}
333
+</script>
334
+
335
+<style>
336
+	/* pages/uni-cropper/index.wxss */
337
+
338
+	.uni-content-info {
339
+		/* position: fixed;
340
+		top: 0;
341
+		left: 0;
342
+		right: 0;
343
+		bottom: 0;
344
+		display: block;
345
+		align-items: center;
346
+		flex-direction: column; */
347
+	}
348
+
349
+	.cropper-config {
350
+		padding: 20rpx 40rpx;
351
+	}
352
+
353
+	.cropper-content {
354
+		min-height: 750rpx;
355
+		width: 100%;
356
+	}
357
+
358
+	.uni-corpper {
359
+		position: relative;
360
+		overflow: hidden;
361
+		-webkit-user-select: none;
362
+		-moz-user-select: none;
363
+		-ms-user-select: none;
364
+		user-select: none;
365
+		-webkit-tap-highlight-color: transparent;
366
+		-webkit-touch-callout: none;
367
+		box-sizing: border-box;
368
+	}
369
+
370
+	.uni-corpper-content {
371
+		position: relative;
372
+	}
373
+
374
+	.uni-corpper-content image {
375
+		display: block;
376
+		width: 100%;
377
+		min-width: 0 !important;
378
+		max-width: none !important;
379
+		height: 100%;
380
+		min-height: 0 !important;
381
+		max-height: none !important;
382
+		image-orientation: 0deg !important;
383
+		margin: 0 auto;
384
+	}
385
+	/* 移动图片效果 */
386
+
387
+	.uni-cropper-drag-box {
388
+		position: absolute;
389
+		top: 0;
390
+		right: 0;
391
+		bottom: 0;
392
+		left: 0;
393
+		cursor: move;
394
+		background: rgba(0, 0, 0, 0.6);
395
+		z-index: 1;
396
+	}
397
+	/* 内部的信息 */
398
+
399
+	.uni-corpper-crop-box {
400
+		position: absolute;
401
+		background: rgba(255, 255, 255, 0.3);
402
+		z-index: 2;
403
+	}
404
+
405
+	.uni-corpper-crop-box .uni-cropper-view-box {
406
+		position: relative;
407
+		display: block;
408
+		width: 100%;
409
+		height: 100%;
410
+		overflow: visible;
411
+		outline: 1rpx solid #69f;
412
+		outline-color: rgba(102, 153, 255, .75)
413
+	}
414
+	/* 横向虚线 */
415
+
416
+	.uni-cropper-dashed-h {
417
+		position: absolute;
418
+		top: 33.33333333%;
419
+		left: 0;
420
+		width: 100%;
421
+		height: 33.33333333%;
422
+		border-top: 1rpx dashed rgba(255, 255, 255, 0.5);
423
+		border-bottom: 1rpx dashed rgba(255, 255, 255, 0.5);
424
+	}
425
+	/* 纵向虚线 */
426
+
427
+	.uni-cropper-dashed-v {
428
+		position: absolute;
429
+		left: 33.33333333%;
430
+		top: 0;
431
+		width: 33.33333333%;
432
+		height: 100%;
433
+		border-left: 1rpx dashed rgba(255, 255, 255, 0.5);
434
+		border-right: 1rpx dashed rgba(255, 255, 255, 0.5);
435
+	}
436
+	/* 四个方向的线  为了之后的拖动事件*/
437
+
438
+	.uni-cropper-line-t {
439
+		position: absolute;
440
+		display: block;
441
+		width: 100%;
442
+		background-color: #69f;
443
+		top: 0;
444
+		left: 0;
445
+		height: 1rpx;
446
+		opacity: 0.1;
447
+		cursor: n-resize;
448
+	}
449
+
450
+	.uni-cropper-line-t::before {
451
+		content: '';
452
+		position: absolute;
453
+		top: 50%;
454
+		right: 0rpx;
455
+		width: 100%;
456
+		-webkit-transform: translate3d(0, -50%, 0);
457
+		transform: translate3d(0, -50%, 0);
458
+		bottom: 0;
459
+		height: 41rpx;
460
+		background: transparent;
461
+		z-index: 11;
462
+	}
463
+
464
+	.uni-cropper-line-r {
465
+		position: absolute;
466
+		display: block;
467
+		background-color: #69f;
468
+		top: 0;
469
+		right: 0rpx;
470
+		width: 1rpx;
471
+		opacity: 0.1;
472
+		height: 100%;
473
+		cursor: e-resize;
474
+	}
475
+
476
+	.uni-cropper-line-r::before {
477
+		content: '';
478
+		position: absolute;
479
+		top: 0;
480
+		left: 50%;
481
+		width: 41rpx;
482
+		-webkit-transform: translate3d(-50%, 0, 0);
483
+		transform: translate3d(-50%, 0, 0);
484
+		bottom: 0;
485
+		height: 100%;
486
+		background: transparent;
487
+		z-index: 11;
488
+	}
489
+
490
+	.uni-cropper-line-b {
491
+		position: absolute;
492
+		display: block;
493
+		width: 100%;
494
+		background-color: #69f;
495
+		bottom: 0;
496
+		left: 0;
497
+		height: 1rpx;
498
+		opacity: 0.1;
499
+		cursor: s-resize;
500
+	}
501
+
502
+	.uni-cropper-line-b::before {
503
+		content: '';
504
+		position: absolute;
505
+		top: 50%;
506
+		right: 0rpx;
507
+		width: 100%;
508
+		-webkit-transform: translate3d(0, -50%, 0);
509
+		transform: translate3d(0, -50%, 0);
510
+		bottom: 0;
511
+		height: 41rpx;
512
+		background: transparent;
513
+		z-index: 11;
514
+	}
515
+
516
+	.uni-cropper-line-l {
517
+		position: absolute;
518
+		display: block;
519
+		background-color: #69f;
520
+		top: 0;
521
+		left: 0;
522
+		width: 1rpx;
523
+		opacity: 0.1;
524
+		height: 100%;
525
+		cursor: w-resize;
526
+	}
527
+
528
+	.uni-cropper-line-l::before {
529
+		content: '';
530
+		position: absolute;
531
+		top: 0;
532
+		left: 50%;
533
+		width: 41rpx;
534
+		-webkit-transform: translate3d(-50%, 0, 0);
535
+		transform: translate3d(-50%, 0, 0);
536
+		bottom: 0;
537
+		height: 100%;
538
+		background: transparent;
539
+		z-index: 11;
540
+	}
541
+
542
+	.uni-cropper-point {
543
+		width: 5rpx;
544
+		height: 5rpx;
545
+		background-color: #69f;
546
+		opacity: .75;
547
+		position: absolute;
548
+		z-index: 3;
549
+	}
550
+
551
+	.point-t {
552
+		top: -3rpx;
553
+		left: 50%;
554
+		margin-left: -3rpx;
555
+		cursor: n-resize;
556
+	}
557
+
558
+	.point-tr {
559
+		top: -3rpx;
560
+		left: 100%;
561
+		margin-left: -3rpx;
562
+		cursor: n-resize;
563
+	}
564
+
565
+	.point-r {
566
+		top: 50%;
567
+		left: 100%;
568
+		margin-left: -3rpx;
569
+		margin-top: -3rpx;
570
+		cursor: n-resize;
571
+	}
572
+
573
+	.point-rb {
574
+		left: 100%;
575
+		top: 100%;
576
+		-webkit-transform: translate3d(-50%, -50%, 0);
577
+		transform: translate3d(-50%, -50%, 0);
578
+		cursor: n-resize;
579
+		width: 36rpx;
580
+		height: 36rpx;
581
+		background-color: #69f;
582
+		position: absolute;
583
+		z-index: 1112;
584
+		opacity: 1;
585
+	}
586
+
587
+	.point-b {
588
+		left: 50%;
589
+		top: 100%;
590
+		margin-left: -3rpx;
591
+		margin-top: -3rpx;
592
+		cursor: n-resize;
593
+	}
594
+
595
+	.point-bl {
596
+		left: 0%;
597
+		top: 100%;
598
+		margin-left: -3rpx;
599
+		margin-top: -3rpx;
600
+		cursor: n-resize;
601
+	}
602
+
603
+	.point-l {
604
+		left: 0%;
605
+		top: 50%;
606
+		margin-left: -3rpx;
607
+		margin-top: -3rpx;
608
+		cursor: n-resize;
609
+	}
610
+
611
+	.point-lt {
612
+		left: 0%;
613
+		top: 0%;
614
+		margin-left: -3rpx;
615
+		margin-top: -3rpx;
616
+		cursor: n-resize;
617
+	}
618
+	/* 裁剪框预览内容 */
619
+
620
+	.uni-cropper-viewer {
621
+		position: relative;
622
+		width: 100%;
623
+		height: 100%;
624
+		overflow: hidden;
625
+	}
626
+
627
+	.uni-cropper-viewer image {
628
+		position: absolute;
629
+		z-index: 2;
630
+	}
631
+</style>

+ 112
- 0
oa-ui-app/pages/mine/help/index.vue Voir le fichier

@@ -0,0 +1,112 @@
1
+<template>
2
+  <view class="help-container">
3
+    <view v-for="(item, findex) in list" :key="findex" :title="item.title" class="list-title">
4
+      <view class="text-title">
5
+        <view :class="item.icon"></view>{{ item.title }}
6
+      </view>
7
+      <view class="childList">
8
+        <view v-for="(child, zindex) in item.childList" :key="zindex" class="question" hover-class="hover"
9
+          @click="handleText(child)">
10
+          <view class="text-item">{{ child.title }}</view>
11
+          <view class="line" v-if="zindex !== item.childList.length - 1"></view>
12
+        </view>
13
+      </view>
14
+    </view>
15
+  </view>
16
+</template>
17
+
18
+<script>
19
+  export default {
20
+    data() {
21
+      return {
22
+        list: [{
23
+            icon: 'iconfont icon-github',
24
+            title: '若依问题',
25
+            childList: [{
26
+              title: '若依开源吗?',
27
+              content: '开源'
28
+            }, {
29
+              title: '若依可以商用吗?',
30
+              content: '可以'
31
+            }, {
32
+              title: '若依官网地址多少?',
33
+              content: 'http://ruoyi.vip'
34
+            }, {
35
+              title: '若依文档地址多少?',
36
+              content: 'http://doc.ruoyi.vip'
37
+            }]
38
+          },
39
+          {
40
+            icon: 'iconfont icon-help',
41
+            title: '其他问题',
42
+            childList: [{
43
+              title: '如何退出登录?',
44
+              content: '请点击[我的] - [应用设置] - [退出登录]即可退出登录',
45
+            }, {
46
+              title: '如何修改用户头像?',
47
+              content: '请点击[我的] - [选择头像] - [点击提交]即可更换用户头像',
48
+            }, {
49
+              title: '如何修改登录密码?',
50
+              content: '请点击[我的] - [应用设置] - [修改密码]即可修改登录密码',
51
+            }]
52
+          }
53
+        ]
54
+      }
55
+    },
56
+    methods: {
57
+      handleText(item) {
58
+        this.$tab.navigateTo(`/pages/common/textview/index?title=${item.title}&content=${item.content}`)
59
+      }
60
+    }
61
+  }
62
+</script>
63
+
64
+<style lang="scss" scoped>
65
+  page {
66
+    background-color: #f8f8f8;
67
+  }
68
+
69
+  .help-container {
70
+    margin-bottom: 100rpx;
71
+    padding: 30rpx;
72
+  }
73
+
74
+  .list-title {
75
+    margin-bottom: 30rpx;
76
+  }
77
+
78
+  .childList {
79
+    background: #ffffff;
80
+    box-shadow: 0px 0px 10rpx rgba(193, 193, 193, 0.2);
81
+    border-radius: 16rpx;
82
+    margin-top: 10rpx;
83
+  }
84
+
85
+  .line {
86
+    width: 100%;
87
+    height: 1rpx;
88
+    background-color: #F5F5F5;
89
+  }
90
+
91
+  .text-title {
92
+    color: #303133;
93
+    font-size: 32rpx;
94
+    font-weight: bold;
95
+    margin-left: 10rpx;
96
+
97
+    .iconfont {
98
+      font-size: 16px;
99
+      margin-right: 10rpx;
100
+    }
101
+  }
102
+
103
+  .text-item {
104
+    font-size: 28rpx;
105
+    padding: 24rpx;
106
+  }
107
+
108
+  .question {
109
+    color: #606266;
110
+    font-size: 28rpx;
111
+  }
112
+</style>

+ 198
- 0
oa-ui-app/pages/mine/index.vue Voir le fichier

@@ -0,0 +1,198 @@
1
+<template>
2
+  <view class="mine-container" :style="{height: `${windowHeight}px`}">
3
+    <!--顶部个人信息栏-->
4
+    <view class="header-section">
5
+      <view class="flex padding justify-between">
6
+        <view class="flex align-center">
7
+          <view v-if="!avatar" class="cu-avatar xl round bg-white">
8
+            <view class="iconfont icon-people text-gray icon"></view>
9
+          </view>
10
+          <image v-if="avatar" @click="handleToAvatar" :src="avatar" class="cu-avatar xl round" mode="widthFix">
11
+          </image>
12
+          <view v-if="!name" @click="handleToLogin" class="login-tip">
13
+            点击登录
14
+          </view>
15
+          <view v-if="name" @click="handleToInfo" class="user-info">
16
+            <view class="u_title">
17
+              用户名:{{ name }}
18
+            </view>
19
+          </view>
20
+        </view>
21
+        <view @click="handleToInfo" class="flex align-center">
22
+          <text>个人信息</text>
23
+          <view class="iconfont icon-right"></view>
24
+        </view>
25
+      </view>
26
+    </view>
27
+
28
+    <view class="content-section">
29
+      <view class="mine-actions grid col-4 text-center">
30
+        <view class="action-item" @click="handleJiaoLiuQun">
31
+          <view class="iconfont icon-friendfill text-pink icon"></view>
32
+          <text class="text">交流群</text>
33
+        </view>
34
+        <view class="action-item" @click="handleBuilding">
35
+          <view class="iconfont icon-service text-blue icon"></view>
36
+          <text class="text">在线客服</text>
37
+        </view>
38
+        <view class="action-item" @click="handleBuilding">
39
+          <view class="iconfont icon-community text-mauve icon"></view>
40
+          <text class="text">反馈社区</text>
41
+        </view>
42
+        <view class="action-item" @click="handleBuilding">
43
+          <view class="iconfont icon-dianzan text-green icon"></view>
44
+          <text class="text">点赞我们</text>
45
+        </view>
46
+      </view>
47
+
48
+      <view class="menu-list">
49
+        <view class="list-cell list-cell-arrow" @click="handleToEditInfo">
50
+          <view class="menu-item-box">
51
+            <view class="iconfont icon-user menu-icon"></view>
52
+            <view>编辑资料</view>
53
+          </view>
54
+        </view>
55
+        <view class="list-cell list-cell-arrow" @click="handleHelp">
56
+          <view class="menu-item-box">
57
+            <view class="iconfont icon-help menu-icon"></view>
58
+            <view>常见问题</view>
59
+          </view>
60
+        </view>
61
+        <view class="list-cell list-cell-arrow" @click="handleAbout">
62
+          <view class="menu-item-box">
63
+            <view class="iconfont icon-aixin menu-icon"></view>
64
+            <view>关于我们</view>
65
+          </view>
66
+        </view>
67
+        <view class="list-cell list-cell-arrow" @click="handleToSetting">
68
+          <view class="menu-item-box">
69
+            <view class="iconfont icon-setting menu-icon"></view>
70
+            <view>应用设置</view>
71
+          </view>
72
+        </view>
73
+      </view>
74
+
75
+    </view>
76
+  </view>
77
+</template>
78
+
79
+<script>
80
+  import storage from '@/utils/storage'
81
+  
82
+  export default {
83
+    data() {
84
+      return {
85
+        name: this.$store.state.user.name,
86
+        version: getApp().globalData.config.appInfo.version
87
+      }
88
+    },
89
+    computed: {
90
+      avatar() {
91
+        return this.$store.state.user.avatar
92
+      },
93
+      windowHeight() {
94
+        return uni.getSystemInfoSync().windowHeight - 50
95
+      }
96
+    },
97
+    methods: {
98
+      handleToInfo() {
99
+        this.$tab.navigateTo('/pages/mine/info/index')
100
+      },
101
+      handleToEditInfo() {
102
+        this.$tab.navigateTo('/pages/mine/info/edit')
103
+      },
104
+      handleToSetting() {
105
+        this.$tab.navigateTo('/pages/mine/setting/index')
106
+      },
107
+      handleToLogin() {
108
+        this.$tab.reLaunch('/pages/login')
109
+      },
110
+      handleToAvatar() {
111
+        this.$tab.navigateTo('/pages/mine/avatar/index')
112
+      },
113
+      handleLogout() {
114
+        this.$modal.confirm('确定注销并退出系统吗?').then(() => {
115
+          this.$store.dispatch('LogOut').then(() => {
116
+            this.$tab.reLaunch('/pages/index')
117
+          })
118
+        })
119
+      },
120
+      handleHelp() {
121
+        this.$tab.navigateTo('/pages/mine/help/index')
122
+      },
123
+      handleAbout() {
124
+        this.$tab.navigateTo('/pages/mine/about/index')
125
+      },
126
+      handleJiaoLiuQun() {
127
+        this.$modal.showToast('QQ群:133713780')
128
+      },
129
+      handleBuilding() {
130
+        this.$modal.showToast('模块建设中~')
131
+      }
132
+    }
133
+  }
134
+</script>
135
+
136
+<style lang="scss">
137
+  page {
138
+    background-color: #f5f6f7;
139
+  }
140
+
141
+  .mine-container {
142
+    width: 100%;
143
+    height: 100%;
144
+
145
+
146
+    .header-section {
147
+      padding: 15px 15px 45px 15px;
148
+      background-color: #3c96f3;
149
+      color: white;
150
+
151
+      .login-tip {
152
+        font-size: 18px;
153
+        margin-left: 10px;
154
+      }
155
+
156
+      .cu-avatar {
157
+        border: 2px solid #eaeaea;
158
+
159
+        .icon {
160
+          font-size: 40px;
161
+        }
162
+      }
163
+
164
+      .user-info {
165
+        margin-left: 15px;
166
+
167
+        .u_title {
168
+          font-size: 18px;
169
+          line-height: 30px;
170
+        }
171
+      }
172
+    }
173
+
174
+    .content-section {
175
+      position: relative;
176
+      top: -50px;
177
+
178
+      .mine-actions {
179
+        margin: 15px 15px;
180
+        padding: 20px 0px;
181
+        border-radius: 8px;
182
+        background-color: white;
183
+
184
+        .action-item {
185
+          .icon {
186
+            font-size: 28px;
187
+          }
188
+
189
+          .text {
190
+            display: block;
191
+            font-size: 13px;
192
+            margin: 8px 0px;
193
+          }
194
+        }
195
+      }
196
+    }
197
+  }
198
+</style>

+ 127
- 0
oa-ui-app/pages/mine/info/edit.vue Voir le fichier

@@ -0,0 +1,127 @@
1
+<template>
2
+  <view class="container">
3
+    <view class="example">
4
+      <uni-forms ref="form" :model="user" labelWidth="80px">
5
+        <uni-forms-item label="用户昵称" name="nickName">
6
+          <uni-easyinput v-model="user.nickName" placeholder="请输入昵称" />
7
+        </uni-forms-item>
8
+        <uni-forms-item label="手机号码" name="phonenumber">
9
+          <uni-easyinput v-model="user.phonenumber" placeholder="请输入手机号码" />
10
+        </uni-forms-item>
11
+        <uni-forms-item label="邮箱" name="email">
12
+          <uni-easyinput v-model="user.email" placeholder="请输入邮箱" />
13
+        </uni-forms-item>
14
+        <uni-forms-item label="性别" name="sex" required>
15
+          <uni-data-checkbox v-model="user.sex" :localdata="sexs" />
16
+        </uni-forms-item>
17
+      </uni-forms>
18
+      <button type="primary" @click="submit">提交</button>
19
+    </view>
20
+  </view>
21
+</template>
22
+
23
+<script>
24
+  import { getUserProfile } from "@/api/system/user"
25
+  import { updateUserProfile } from "@/api/system/user"
26
+
27
+  export default {
28
+    data() {
29
+      return {
30
+        user: {
31
+          nickName: "",
32
+          phonenumber: "",
33
+          email: "",
34
+          sex: ""
35
+        },
36
+        sexs: [{
37
+          text: '男',
38
+          value: "0"
39
+        }, {
40
+          text: '女',
41
+          value: "1"
42
+        }],
43
+        rules: {
44
+          nickName: {
45
+            rules: [{
46
+              required: true,
47
+              errorMessage: '用户昵称不能为空'
48
+            }]
49
+          },
50
+          phonenumber: {
51
+            rules: [{
52
+              required: true,
53
+              errorMessage: '手机号码不能为空'
54
+            }, {
55
+              pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
56
+              errorMessage: '请输入正确的手机号码'
57
+            }]
58
+          },
59
+          email: {
60
+            rules: [{
61
+              required: true,
62
+              errorMessage: '邮箱地址不能为空'
63
+            }, {
64
+              format: 'email',
65
+              errorMessage: '请输入正确的邮箱地址'
66
+            }]
67
+          }
68
+        }
69
+      }
70
+    },
71
+    onLoad() {
72
+      this.getUser()
73
+    },
74
+    onReady() {
75
+      this.$refs.form.setRules(this.rules)
76
+    },
77
+    methods: {
78
+      getUser() {
79
+        getUserProfile().then(response => {
80
+          this.user = response.data
81
+        })
82
+      },
83
+      submit(ref) {
84
+        this.$refs.form.validate().then(res => {
85
+          updateUserProfile(this.user).then(response => {
86
+            this.$modal.msgSuccess("修改成功")
87
+          })
88
+        })
89
+      }
90
+    }
91
+  }
92
+</script>
93
+
94
+<style lang="scss">
95
+  page {
96
+    background-color: #ffffff;
97
+  }
98
+
99
+  .example {
100
+    padding: 15px;
101
+    background-color: #fff;
102
+  }
103
+
104
+  .segmented-control {
105
+    margin-bottom: 15px;
106
+  }
107
+
108
+  .button-group {
109
+    margin-top: 15px;
110
+    display: flex;
111
+    justify-content: space-around;
112
+  }
113
+
114
+  .form-item {
115
+    display: flex;
116
+    align-items: center;
117
+    flex: 1;
118
+  }
119
+
120
+  .button {
121
+    display: flex;
122
+    align-items: center;
123
+    height: 35px;
124
+    line-height: 35px;
125
+    margin-left: 10px;
126
+  }
127
+</style>

+ 44
- 0
oa-ui-app/pages/mine/info/index.vue Voir le fichier

@@ -0,0 +1,44 @@
1
+<template>
2
+  <view class="container">
3
+    <uni-list>
4
+      <uni-list-item showExtraIcon="true" :extraIcon="{type: 'person-filled'}" title="昵称" :rightText="user.nickName" />
5
+      <uni-list-item showExtraIcon="true" :extraIcon="{type: 'phone-filled'}" title="手机号码" :rightText="user.phonenumber" />
6
+      <uni-list-item showExtraIcon="true" :extraIcon="{type: 'email-filled'}" title="邮箱" :rightText="user.email" />
7
+      <uni-list-item showExtraIcon="true" :extraIcon="{type: 'auth-filled'}" title="岗位" :rightText="postGroup" />
8
+      <uni-list-item showExtraIcon="true" :extraIcon="{type: 'staff-filled'}" title="角色" :rightText="roleGroup" />
9
+      <uni-list-item showExtraIcon="true" :extraIcon="{type: 'calendar-filled'}" title="创建日期" :rightText="user.createTime" />
10
+    </uni-list>
11
+  </view>
12
+</template>
13
+
14
+<script>
15
+  import { getUserProfile } from "@/api/system/user"
16
+
17
+  export default {
18
+    data() {
19
+      return {
20
+        user: {},
21
+        roleGroup: "",
22
+        postGroup: ""
23
+      }
24
+    },
25
+    onLoad() {
26
+      this.getUser()
27
+    },
28
+    methods: {
29
+      getUser() {
30
+        getUserProfile().then(response => {
31
+          this.user = response.data
32
+          this.roleGroup = response.roleGroup
33
+          this.postGroup = response.postGroup
34
+        })
35
+      }
36
+    }
37
+  }
38
+</script>
39
+
40
+<style lang="scss">
41
+  page {
42
+    background-color: #ffffff;
43
+  }
44
+</style>

+ 85
- 0
oa-ui-app/pages/mine/pwd/index.vue Voir le fichier

@@ -0,0 +1,85 @@
1
+<template>
2
+  <view class="pwd-retrieve-container">
3
+    <uni-forms ref="form" :value="user" labelWidth="80px">
4
+      <uni-forms-item name="oldPassword" label="旧密码">
5
+        <uni-easyinput type="password" v-model="user.oldPassword" placeholder="请输入旧密码" />
6
+      </uni-forms-item>
7
+      <uni-forms-item name="newPassword" label="新密码">
8
+        <uni-easyinput type="password" v-model="user.newPassword" placeholder="请输入新密码" />
9
+      </uni-forms-item>
10
+      <uni-forms-item name="confirmPassword" label="确认密码">
11
+        <uni-easyinput type="password" v-model="user.confirmPassword" placeholder="请确认新密码" />
12
+      </uni-forms-item>
13
+      <button type="primary" @click="submit">提交</button>
14
+    </uni-forms>
15
+  </view>
16
+</template>
17
+
18
+<script>
19
+  import { updateUserPwd } from "@/api/system/user"
20
+
21
+  export default {
22
+    data() {
23
+      return {
24
+        user: {
25
+          oldPassword: undefined,
26
+          newPassword: undefined,
27
+          confirmPassword: undefined
28
+        },
29
+        rules: {
30
+          oldPassword: {
31
+            rules: [{
32
+              required: true,
33
+              errorMessage: '旧密码不能为空'
34
+            }]
35
+          },
36
+          newPassword: {
37
+            rules: [{
38
+                required: true,
39
+                errorMessage: '新密码不能为空',
40
+              },
41
+              {
42
+                minLength: 6,
43
+                maxLength: 20,
44
+                errorMessage: '长度在 6 到 20 个字符'
45
+              }
46
+            ]
47
+          },
48
+          confirmPassword: {
49
+            rules: [{
50
+                required: true,
51
+                errorMessage: '确认密码不能为空'
52
+              }, {
53
+                validateFunction: (rule, value, data) => data.newPassword === value,
54
+                errorMessage: '两次输入的密码不一致'
55
+              }
56
+            ]
57
+          }
58
+        }
59
+      }
60
+    },
61
+    onReady() {
62
+      this.$refs.form.setRules(this.rules)
63
+    },
64
+    methods: {
65
+      submit() {
66
+        this.$refs.form.validate().then(res => {
67
+          updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => {
68
+            this.$modal.msgSuccess("修改成功")
69
+          })
70
+        })
71
+      }
72
+    }
73
+  }
74
+</script>
75
+
76
+<style lang="scss">
77
+  page {
78
+    background-color: #ffffff;
79
+  }
80
+
81
+  .pwd-retrieve-container {
82
+    padding-top: 36rpx;
83
+    padding: 15px;
84
+  }
85
+</style>

+ 78
- 0
oa-ui-app/pages/mine/setting/index.vue Voir le fichier

@@ -0,0 +1,78 @@
1
+<template>
2
+  <view class="setting-container" :style="{height: `${windowHeight}px`}">
3
+    <view class="menu-list">
4
+      <view class="list-cell list-cell-arrow" @click="handleToPwd">
5
+        <view class="menu-item-box">
6
+          <view class="iconfont icon-password menu-icon"></view>
7
+          <view>修改密码</view>
8
+        </view>
9
+      </view>
10
+      <view class="list-cell list-cell-arrow" @click="handleToUpgrade">
11
+        <view class="menu-item-box">
12
+          <view class="iconfont icon-refresh menu-icon"></view>
13
+          <view>检查更新</view>
14
+        </view>
15
+      </view>
16
+      <view class="list-cell list-cell-arrow" @click="handleCleanTmp">
17
+        <view class="menu-item-box">
18
+          <view class="iconfont icon-clean menu-icon"></view>
19
+          <view>清理缓存</view>
20
+        </view>
21
+      </view>
22
+    </view>
23
+    <view class="cu-list menu">
24
+      <view class="cu-item item-box">
25
+        <view class="content text-center" @click="handleLogout">
26
+          <text class="text-black">退出登录</text>
27
+        </view>
28
+      </view>
29
+    </view>
30
+  </view>
31
+</template>
32
+
33
+<script>
34
+  export default {
35
+    data() {
36
+      return {
37
+        windowHeight: uni.getSystemInfoSync().windowHeight
38
+      }
39
+    },
40
+    methods: {
41
+      handleToPwd() {
42
+        this.$tab.navigateTo('/pages/mine/pwd/index')
43
+      },
44
+      handleToUpgrade() {
45
+        this.$modal.showToast('模块建设中~')
46
+      },
47
+      handleCleanTmp() {
48
+        this.$modal.showToast('模块建设中~')
49
+      },
50
+      handleLogout() {
51
+        this.$modal.confirm('确定注销并退出系统吗?').then(() => {
52
+          this.$store.dispatch('LogOut').then(() => {
53
+            this.$tab.reLaunch('/pages/index')
54
+          })
55
+        })
56
+      }
57
+    }
58
+  }
59
+</script>
60
+
61
+<style lang="scss" scoped>
62
+  .page {
63
+    background-color: #f8f8f8;
64
+  }
65
+
66
+  .item-box {
67
+    background-color: #FFFFFF;
68
+    margin: 30rpx;
69
+    display: flex;
70
+    flex-direction: row;
71
+    justify-content: center;
72
+    align-items: center;
73
+    padding: 10rpx;
74
+    border-radius: 8rpx;
75
+    color: #303133;
76
+    font-size: 32rpx;
77
+  }
78
+</style>

+ 183
- 0
oa-ui-app/pages/work/index.vue Voir le fichier

@@ -0,0 +1,183 @@
1
+<template>
2
+  <view class="work-container">
3
+    <!-- 轮播图 -->
4
+    <uni-swiper-dot class="uni-swiper-dot-box" :info="data" :current="current" field="content">
5
+      <swiper class="swiper-box" :current="swiperDotIndex" @change="changeSwiper">
6
+        <swiper-item v-for="(item, index) in data" :key="index">
7
+          <view class="swiper-item" @click="clickBannerItem(item)">
8
+            <image :src="item.image" mode="aspectFill" :draggable="false" />
9
+          </view>
10
+        </swiper-item>
11
+      </swiper>
12
+    </uni-swiper-dot>
13
+
14
+    <!-- 宫格组件 -->
15
+    <uni-section title="系统管理" type="line"></uni-section>
16
+    <view class="grid-body">
17
+      <uni-grid :column="4" :showBorder="false" @change="changeGrid">
18
+        <uni-grid-item>
19
+          <view class="grid-item-box">
20
+            <uni-icons type="person-filled" size="30"></uni-icons>
21
+            <text class="text">用户管理</text>
22
+          </view>
23
+        </uni-grid-item>
24
+        <uni-grid-item>
25
+          <view class="grid-item-box">
26
+            <uni-icons type="staff-filled" size="30"></uni-icons>
27
+            <text class="text">角色管理</text>
28
+          </view>
29
+        </uni-grid-item>
30
+        <uni-grid-item>
31
+          <view class="grid-item-box">
32
+            <uni-icons type="color" size="30"></uni-icons>
33
+            <text class="text">菜单管理</text>
34
+          </view>
35
+        </uni-grid-item>
36
+        <uni-grid-item>
37
+          <view class="grid-item-box">
38
+            <uni-icons type="settings-filled" size="30"></uni-icons>
39
+            <text class="text">部门管理</text>
40
+          </view>
41
+        </uni-grid-item>
42
+        <uni-grid-item>
43
+          <view class="grid-item-box">
44
+            <uni-icons type="heart-filled" size="30"></uni-icons>
45
+            <text class="text">岗位管理</text>
46
+          </view>
47
+        </uni-grid-item>
48
+        <uni-grid-item>
49
+          <view class="grid-item-box">
50
+            <uni-icons type="bars" size="30"></uni-icons>
51
+            <text class="text">字典管理</text>
52
+          </view>
53
+        </uni-grid-item>
54
+        <uni-grid-item>
55
+          <view class="grid-item-box">
56
+            <uni-icons type="gear-filled" size="30"></uni-icons>
57
+            <text class="text">参数设置</text>
58
+          </view>
59
+        </uni-grid-item>
60
+        <uni-grid-item>
61
+          <view class="grid-item-box">
62
+            <uni-icons type="chat-filled" size="30"></uni-icons>
63
+            <text class="text">通知公告</text>
64
+          </view>
65
+        </uni-grid-item>
66
+        <uni-grid-item>
67
+          <view class="grid-item-box">
68
+            <uni-icons type="wallet-filled" size="30"></uni-icons>
69
+            <text class="text">日志管理</text>
70
+          </view>
71
+        </uni-grid-item>
72
+      </uni-grid>
73
+    </view>
74
+  </view>
75
+</template>
76
+
77
+<script>
78
+  export default {
79
+    data() {
80
+      return {
81
+        current: 0,
82
+        swiperDotIndex: 0,
83
+        data: [{
84
+            image: '/static/images/banner/banner01.jpg'
85
+          },
86
+          {
87
+            image: '/static/images/banner/banner02.jpg'
88
+          },
89
+          {
90
+            image: '/static/images/banner/banner03.jpg'
91
+          }
92
+        ]
93
+      }
94
+    },
95
+    methods: {
96
+      clickBannerItem(item) {
97
+        console.info(item)
98
+      },
99
+      changeSwiper(e) {
100
+        this.current = e.detail.current
101
+      },
102
+      changeGrid(e) {
103
+        this.$modal.showToast('模块建设中~')
104
+      }
105
+    }
106
+  }
107
+</script>
108
+
109
+<style lang="scss">
110
+  /* #ifndef APP-NVUE */
111
+  page {
112
+    display: flex;
113
+    flex-direction: column;
114
+    box-sizing: border-box;
115
+    background-color: #fff;
116
+    min-height: 100%;
117
+    height: auto;
118
+  }
119
+
120
+  view {
121
+    font-size: 14px;
122
+    line-height: inherit;
123
+  }
124
+
125
+  /* #endif */
126
+
127
+  .text {
128
+    text-align: center;
129
+    font-size: 26rpx;
130
+    margin-top: 10rpx;
131
+  }
132
+
133
+  .grid-item-box {
134
+    flex: 1;
135
+    /* #ifndef APP-NVUE */
136
+    display: flex;
137
+    /* #endif */
138
+    flex-direction: column;
139
+    align-items: center;
140
+    justify-content: center;
141
+    padding: 15px 0;
142
+  }
143
+
144
+  .uni-margin-wrap {
145
+    width: 690rpx;
146
+    width: 100%;
147
+    ;
148
+  }
149
+
150
+  .swiper {
151
+    height: 300rpx;
152
+  }
153
+
154
+  .swiper-box {
155
+    height: 150px;
156
+  }
157
+
158
+  .swiper-item {
159
+    /* #ifndef APP-NVUE */
160
+    display: flex;
161
+    /* #endif */
162
+    flex-direction: column;
163
+    justify-content: center;
164
+    align-items: center;
165
+    color: #fff;
166
+    height: 300rpx;
167
+    line-height: 300rpx;
168
+  }
169
+
170
+  @media screen and (min-width: 500px) {
171
+    .uni-swiper-dot-box {
172
+      width: 400px;
173
+      /* #ifndef APP-NVUE */
174
+      margin: 0 auto;
175
+      /* #endif */
176
+      margin-top: 8px;
177
+    }
178
+
179
+    .image {
180
+      width: 100%;
181
+    }
182
+  }
183
+</style>

+ 39
- 0
oa-ui-app/permission.js Voir le fichier

@@ -0,0 +1,39 @@
1
+import { getToken } from '@/utils/auth'
2
+
3
+// 登录页面
4
+const loginPage = "/pages/login"
5
+  
6
+// 页面白名单
7
+const whiteList = [
8
+  '/pages/login', '/pages/common/webview/index'
9
+]
10
+
11
+// 检查地址白名单
12
+function checkWhite(url) {
13
+  const path = url.split('?')[0]
14
+  return whiteList.indexOf(path) !== -1
15
+}
16
+
17
+// 页面跳转验证拦截器
18
+let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]
19
+list.forEach(item => {
20
+  uni.addInterceptor(item, {
21
+    invoke(to) {
22
+      if (getToken()) {
23
+        if (to.url === loginPage) {
24
+          uni.reLaunch({ url: "/" })
25
+        }
26
+        return true
27
+      } else {
28
+        if (checkWhite(to.url)) {
29
+          return true
30
+        }
31
+        uni.reLaunch({ url: loginPage })
32
+        return false
33
+      }
34
+    },
35
+    fail(err) {
36
+      console.log(err)
37
+    }
38
+  })
39
+})

+ 60
- 0
oa-ui-app/plugins/auth.js Voir le fichier

@@ -0,0 +1,60 @@
1
+import store from '@/store'
2
+
3
+function authPermission(permission) {
4
+  const all_permission = "*:*:*"
5
+  const permissions = store.getters && store.getters.permissions
6
+  if (permission && permission.length > 0) {
7
+    return permissions.some(v => {
8
+      return all_permission === v || v === permission
9
+    })
10
+  } else {
11
+    return false
12
+  }
13
+}
14
+
15
+function authRole(role) {
16
+  const super_admin = "admin"
17
+  const roles = store.getters && store.getters.roles
18
+  if (role && role.length > 0) {
19
+    return roles.some(v => {
20
+      return super_admin === v || v === role
21
+    })
22
+  } else {
23
+    return false
24
+  }
25
+}
26
+
27
+export default {
28
+  // 验证用户是否具备某权限
29
+  hasPermi(permission) {
30
+    return authPermission(permission)
31
+  },
32
+  // 验证用户是否含有指定权限,只需包含其中一个
33
+  hasPermiOr(permissions) {
34
+    return permissions.some(item => {
35
+      return authPermission(item)
36
+    })
37
+  },
38
+  // 验证用户是否含有指定权限,必须全部拥有
39
+  hasPermiAnd(permissions) {
40
+    return permissions.every(item => {
41
+      return authPermission(item)
42
+    })
43
+  },
44
+  // 验证用户是否具备某角色
45
+  hasRole(role) {
46
+    return authRole(role)
47
+  },
48
+  // 验证用户是否含有指定角色,只需包含其中一个
49
+  hasRoleOr(roles) {
50
+    return roles.some(item => {
51
+      return authRole(item)
52
+    })
53
+  },
54
+  // 验证用户是否含有指定角色,必须全部拥有
55
+  hasRoleAnd(roles) {
56
+    return roles.every(item => {
57
+      return authRole(item)
58
+    })
59
+  }
60
+}

+ 14
- 0
oa-ui-app/plugins/index.js Voir le fichier

@@ -0,0 +1,14 @@
1
+import tab from './tab'
2
+import auth from './auth'
3
+import modal from './modal'
4
+
5
+export default {
6
+  install(Vue) {
7
+    // 页签操作
8
+    Vue.prototype.$tab = tab
9
+    // 认证对象
10
+    Vue.prototype.$auth = auth
11
+    // 模态框对象
12
+    Vue.prototype.$modal = modal
13
+  }
14
+}

+ 74
- 0
oa-ui-app/plugins/modal.js Voir le fichier

@@ -0,0 +1,74 @@
1
+export default {
2
+  // 消息提示
3
+  msg(content) {
4
+    uni.showToast({
5
+      title: content,
6
+      icon: 'none'
7
+    })
8
+  },
9
+  // 错误消息
10
+  msgError(content) {
11
+    uni.showToast({
12
+      title: content,
13
+      icon: 'error'
14
+    })
15
+  },
16
+  // 成功消息
17
+  msgSuccess(content) {
18
+    uni.showToast({
19
+      title: content,
20
+      icon: 'success'
21
+    })
22
+  },
23
+  // 隐藏消息
24
+  hideMsg(content) {
25
+    uni.hideToast()
26
+  },
27
+  // 弹出提示
28
+  alert(content) {
29
+    uni.showModal({
30
+      title: '提示',
31
+      content: content,
32
+      showCancel: false
33
+    })
34
+  },
35
+  // 确认窗体
36
+  confirm(content) {
37
+    return new Promise((resolve, reject) => {
38
+      uni.showModal({
39
+        title: '系统提示',
40
+        content: content,
41
+        cancelText: '取消',
42
+        confirmText: '确定',
43
+        success: function(res) {
44
+          if (res.confirm) {
45
+            resolve(res.confirm)
46
+          }
47
+        }
48
+      })
49
+    })
50
+  },
51
+  // 提示信息
52
+  showToast(option) {
53
+    if (typeof option === "object") {
54
+      uni.showToast(option)
55
+    } else {
56
+      uni.showToast({
57
+        title: option,
58
+        icon: "none",
59
+        duration: 2500
60
+      })
61
+    }
62
+  },
63
+  // 打开遮罩层
64
+  loading(content) {
65
+    uni.showLoading({
66
+      title: content,
67
+      icon: 'none'
68
+    })
69
+  },
70
+  // 关闭遮罩层
71
+  closeLoading() {
72
+    uni.hideLoading()
73
+  }
74
+}

+ 30
- 0
oa-ui-app/plugins/tab.js Voir le fichier

@@ -0,0 +1,30 @@
1
+export default {
2
+  // 关闭所有页面,打开到应用内的某个页面
3
+  reLaunch(url) {
4
+    return uni.reLaunch({
5
+      url: url
6
+    })
7
+  },
8
+  // 跳转到tabBar页面,并关闭其他所有非tabBar页面
9
+  switchTab(url) {
10
+    return uni.switchTab({
11
+      url: url
12
+    })
13
+  },
14
+  // 关闭当前页面,跳转到应用内的某个页面
15
+  redirectTo(url) {
16
+    return uni.redirectTo({
17
+      url: url
18
+    })
19
+  },
20
+  // 保留当前页面,跳转到应用内的某个页面
21
+  navigateTo(url) {
22
+    return uni.navigateTo({
23
+      url: url
24
+    })
25
+  },
26
+  // 关闭当前页面,返回上一页面或多级页面
27
+  navigateBack() {
28
+    return uni.navigateBack()
29
+  }
30
+}

BIN
oa-ui-app/static/favicon.ico Voir le fichier


+ 90
- 0
oa-ui-app/static/font/iconfont.css Voir le fichier

@@ -0,0 +1,90 @@
1
+@font-face {
2
+  font-family: "iconfont";
3
+  src: url('@/static/font/iconfont.ttf') format('truetype');
4
+}
5
+
6
+.iconfont {
7
+  font-family: "iconfont" !important;
8
+  font-size: 16px;
9
+  display: inline-block;
10
+  font-style: normal;
11
+  -webkit-font-smoothing: antialiased;
12
+  -moz-osx-font-smoothing: grayscale;
13
+}
14
+
15
+.icon-user:before {
16
+  content: "\e7ae";
17
+}
18
+
19
+.icon-password:before {
20
+  content: "\e8b2";
21
+}
22
+
23
+.icon-code:before {
24
+  content: "\e699";
25
+}
26
+
27
+.icon-setting:before {
28
+  content: "\e6cc";
29
+}
30
+
31
+.icon-share:before {
32
+  content: "\e739";
33
+}
34
+
35
+.icon-edit:before {
36
+  content: "\e60c";
37
+}
38
+
39
+.icon-version:before {
40
+  content: "\e63f";
41
+}
42
+
43
+.icon-service:before {
44
+  content: "\e6ff";
45
+}
46
+
47
+.icon-friendfill:before {
48
+  content: "\e726";
49
+}
50
+
51
+.icon-community:before {
52
+  content: "\e741";
53
+}
54
+
55
+.icon-people:before {
56
+  content: "\e736";
57
+}
58
+
59
+.icon-dianzan:before {
60
+  content: "\ec7f";
61
+}
62
+
63
+.icon-right:before {
64
+  content: "\e7eb";
65
+}
66
+
67
+.icon-logout:before {
68
+  content: "\e61d";
69
+}
70
+
71
+.icon-help:before {
72
+  content: "\e616";
73
+}
74
+
75
+.icon-github:before {
76
+  content: "\e628";
77
+}
78
+
79
+.icon-aixin:before {
80
+  content: "\e601";
81
+}
82
+
83
+.icon-clean:before {
84
+  content: "\e607";
85
+}
86
+
87
+.icon-refresh:before {
88
+  content: "\e604";
89
+}
90
+

BIN
oa-ui-app/static/font/iconfont.ttf Voir le fichier


BIN
oa-ui-app/static/images/banner/banner01.jpg Voir le fichier


BIN
oa-ui-app/static/images/banner/banner02.jpg Voir le fichier


BIN
oa-ui-app/static/images/banner/banner03.jpg Voir le fichier


BIN
oa-ui-app/static/images/profile.jpg Voir le fichier


BIN
oa-ui-app/static/images/tabbar/home.png Voir le fichier


BIN
oa-ui-app/static/images/tabbar/home_.png Voir le fichier


BIN
oa-ui-app/static/images/tabbar/mine.png Voir le fichier


BIN
oa-ui-app/static/images/tabbar/mine_.png Voir le fichier


BIN
oa-ui-app/static/images/tabbar/work.png Voir le fichier


BIN
oa-ui-app/static/images/tabbar/work_.png Voir le fichier


+ 20
- 0
oa-ui-app/static/index.html Voir le fichier

@@ -0,0 +1,20 @@
1
+<!DOCTYPE html>
2
+<html lang="zh-CN">
3
+	<head>
4
+		<meta charset="utf-8">
5
+		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6
+		  <meta name="renderer" content="webkit">
7
+		<title><%= htmlWebpackPlugin.options.title %></title>
8
+    <link rel="shortcut icon" type="image/x-icon" href="<%= BASE_URL %>static/logo.png">
9
+		<script>
10
+			var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
11
+			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' : '') + '" />')
12
+		</script>
13
+		<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
14
+	</head>
15
+	<body>
16
+		<noscript>
17
+			<strong>本站点必须要开启JavaScript才能运行.</strong>
18
+		</noscript>
19
+		<div id="app"></div>
20
+</html>

BIN
oa-ui-app/static/logo.png Voir le fichier


BIN
oa-ui-app/static/logo200.png Voir le fichier


+ 3912
- 0
oa-ui-app/static/scss/colorui.css
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


+ 90
- 0
oa-ui-app/static/scss/global.scss Voir le fichier

@@ -0,0 +1,90 @@
1
+.text-center {
2
+	text-align: center;
3
+}
4
+
5
+.font-13 {
6
+	font-size: 13px;
7
+}
8
+
9
+.font-12 {
10
+	font-size: 12px;
11
+}
12
+
13
+.font-11 {
14
+	font-size: 11px;
15
+}
16
+
17
+.text-grey1 {
18
+	color: #888;
19
+}
20
+.text-grey2 {
21
+	color: #aaa;
22
+}
23
+
24
+.list-cell-arrow::before {
25
+    content: ' ';
26
+    height: 10px;
27
+    width: 10px;
28
+    border-width: 2px 2px 0 0;
29
+    border-color: #c0c0c0;
30
+    border-style: solid;
31
+    -webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
32
+    transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
33
+    position: absolute;
34
+    top: 50%;
35
+    margin-top: -6px;
36
+    right: 30rpx;
37
+  }
38
+  
39
+  .list-cell {
40
+    position: relative;
41
+    width: 100%;
42
+    box-sizing: border-box;
43
+    background-color: #fff;
44
+    color: #333;
45
+    padding: 26rpx 30rpx;
46
+  }
47
+  
48
+  .list-cell:first-child {
49
+    border-radius: 8rpx 8rpx 0 0;
50
+  }
51
+  
52
+  .list-cell:last-child {
53
+    border-radius: 0 0 8rpx 8rpx;
54
+  }
55
+  
56
+  .list-cell::after {
57
+    content: '';
58
+    position: absolute;
59
+    border-bottom: 1px solid #eaeef1;
60
+    -webkit-transform: scaleY(0.5) translateZ(0);
61
+    transform: scaleY(0.5) translateZ(0);
62
+    transform-origin: 0 100%;
63
+    bottom: 0;
64
+    right: 0;
65
+    left: 0;
66
+    pointer-events: none;
67
+  }
68
+  
69
+  
70
+  .menu-list {
71
+    margin: 15px 15px;
72
+  
73
+    .menu-item-box {
74
+      width: 100%;
75
+      display: flex;
76
+      align-items: center;
77
+  
78
+      .menu-icon {
79
+        color: #007AFF;
80
+        font-size: 16px;
81
+        margin-right: 5px;
82
+      }
83
+      
84
+      .text-right {
85
+        margin-left: auto;
86
+        margin-right: 34rpx;
87
+        color: #999;
88
+      }
89
+    }
90
+  }

+ 6
- 0
oa-ui-app/static/scss/index.scss Voir le fichier

@@ -0,0 +1,6 @@
1
+// global
2
+@import "./global.scss";
3
+// color-ui
4
+@import "@/static/scss/colorui.css";
5
+// iconfont
6
+@import "@/static/font/iconfont.css";

+ 8
- 0
oa-ui-app/store/getters.js Voir le fichier

@@ -0,0 +1,8 @@
1
+const getters = {
2
+  token: state => state.user.token,
3
+  avatar: state => state.user.avatar,
4
+  name: state => state.user.name,
5
+  roles: state => state.user.roles,
6
+  permissions: state => state.user.permissions
7
+}
8
+export default getters

+ 15
- 0
oa-ui-app/store/index.js Voir le fichier

@@ -0,0 +1,15 @@
1
+import Vue from 'vue'
2
+import Vuex from 'vuex'
3
+import user from '@/store/modules/user'
4
+import getters from './getters'
5
+
6
+Vue.use(Vuex)
7
+
8
+const store = new Vuex.Store({
9
+  modules: {
10
+    user
11
+  },
12
+  getters
13
+})
14
+
15
+export default store

+ 98
- 0
oa-ui-app/store/modules/user.js Voir le fichier

@@ -0,0 +1,98 @@
1
+import config from '@/config'
2
+import storage from '@/utils/storage'
3
+import constant from '@/utils/constant'
4
+import { login, logout, getInfo } from '@/api/login'
5
+import { getToken, setToken, removeToken } from '@/utils/auth'
6
+
7
+const baseUrl = config.baseUrl
8
+
9
+const user = {
10
+  state: {
11
+    token: getToken(),
12
+    name: storage.get(constant.name),
13
+    avatar: storage.get(constant.avatar),
14
+    roles: storage.get(constant.roles),
15
+    permissions: storage.get(constant.permissions)
16
+  },
17
+
18
+  mutations: {
19
+    SET_TOKEN: (state, token) => {
20
+      state.token = token
21
+    },
22
+    SET_NAME: (state, name) => {
23
+      state.name = name
24
+      storage.set(constant.name, name)
25
+    },
26
+    SET_AVATAR: (state, avatar) => {
27
+      state.avatar = avatar
28
+      storage.set(constant.avatar, avatar)
29
+    },
30
+    SET_ROLES: (state, roles) => {
31
+      state.roles = roles
32
+      storage.set(constant.roles, roles)
33
+    },
34
+    SET_PERMISSIONS: (state, permissions) => {
35
+      state.permissions = permissions
36
+      storage.set(constant.permissions, permissions)
37
+    }
38
+  },
39
+
40
+  actions: {
41
+    // 登录
42
+    Login({ commit }, userInfo) {
43
+      const username = userInfo.username.trim()
44
+      const password = userInfo.password
45
+      const code = userInfo.code
46
+      const uuid = userInfo.uuid
47
+      return new Promise((resolve, reject) => {
48
+        login(username, password, code, uuid).then(res => {
49
+          setToken(res.token)
50
+          commit('SET_TOKEN', res.token)
51
+          resolve()
52
+        }).catch(error => {
53
+          reject(error)
54
+        })
55
+      })
56
+    },
57
+
58
+    // 获取用户信息
59
+    GetInfo({ commit, state }) {
60
+      return new Promise((resolve, reject) => {
61
+        getInfo().then(res => {
62
+          const user = res.user
63
+          const avatar = (user == null || user.avatar == "" || user.avatar == null) ? require("@/static/images/profile.jpg") : baseUrl + user.avatar
64
+          const username = (user == null || user.userName == "" || user.userName == null) ? "" : user.userName
65
+          if (res.roles && res.roles.length > 0) {
66
+            commit('SET_ROLES', res.roles)
67
+            commit('SET_PERMISSIONS', res.permissions)
68
+          } else {
69
+            commit('SET_ROLES', ['ROLE_DEFAULT'])
70
+          }
71
+          commit('SET_NAME', username)
72
+          commit('SET_AVATAR', avatar)
73
+          resolve(res)
74
+        }).catch(error => {
75
+          reject(error)
76
+        })
77
+      })
78
+    },
79
+
80
+    // 退出系统
81
+    LogOut({ commit, state }) {
82
+      return new Promise((resolve, reject) => {
83
+        logout(state.token).then(() => {
84
+          commit('SET_TOKEN', '')
85
+          commit('SET_ROLES', [])
86
+          commit('SET_PERMISSIONS', [])
87
+          removeToken()
88
+          storage.clean()
89
+          resolve()
90
+        }).catch(error => {
91
+          reject(error)
92
+        })
93
+      })
94
+    }
95
+  }
96
+}
97
+
98
+export default user

+ 64
- 0
oa-ui-app/uni.scss Voir le fichier

@@ -0,0 +1,64 @@
1
+/**
2
+ * uni-app内置的常用样式变量
3
+ */
4
+
5
+/* 行为相关颜色 */
6
+$uni-color-primary: #007aff;
7
+$uni-color-success: #4cd964;
8
+$uni-color-warning: #f0ad4e;
9
+$uni-color-error: #dd524d;
10
+
11
+/* 文字基本颜色 */
12
+$uni-text-color:#333;//基本色
13
+$uni-text-color-inverse:#fff;//反色
14
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
15
+$uni-text-color-placeholder: #808080;
16
+$uni-text-color-disable:#c0c0c0;
17
+
18
+/* 背景颜色 */
19
+$uni-bg-color:#ffffff;
20
+$uni-bg-color-grey:#f8f8f8;
21
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
22
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
23
+
24
+/* 边框颜色 */
25
+$uni-border-color:#e5e5e5;
26
+
27
+/* 尺寸变量 */
28
+
29
+/* 文字尺寸 */
30
+$uni-font-size-sm:12px;
31
+$uni-font-size-base:14px;
32
+$uni-font-size-lg:16px;
33
+
34
+/* 图片尺寸 */
35
+$uni-img-size-sm:20px;
36
+$uni-img-size-base:26px;
37
+$uni-img-size-lg:40px;
38
+
39
+/* Border Radius */
40
+$uni-border-radius-sm: 2px;
41
+$uni-border-radius-base: 3px;
42
+$uni-border-radius-lg: 6px;
43
+$uni-border-radius-circle: 50%;
44
+
45
+/* 水平间距 */
46
+$uni-spacing-row-sm: 5px;
47
+$uni-spacing-row-base: 10px;
48
+$uni-spacing-row-lg: 15px;
49
+
50
+/* 垂直间距 */
51
+$uni-spacing-col-sm: 4px;
52
+$uni-spacing-col-base: 8px;
53
+$uni-spacing-col-lg: 12px;
54
+
55
+/* 透明度 */
56
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
57
+
58
+/* 文章场景相关 */
59
+$uni-color-title: #2C405A; // 文章标题颜色
60
+$uni-font-size-title:20px;
61
+$uni-color-subtitle: #555555; // 二级标题颜色
62
+$uni-font-size-subtitle:26px;
63
+$uni-color-paragraph: #3F536E; // 文章段落颜色
64
+$uni-font-size-paragraph:15px;

+ 31
- 0
oa-ui-app/uni_modules/uni-badge/changelog.md Voir le fichier

@@ -0,0 +1,31 @@
1
+## 1.2.1(2022-09-05)
2
+- 修复 当 text 超过 max-num 时,badge 的宽度计算是根据 text 的长度计算,更改为 css 计算实际展示宽度,详见:[https://ask.dcloud.net.cn/question/150473](https://ask.dcloud.net.cn/question/150473)
3
+## 1.2.0(2021-11-19)
4
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
5
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-badge](https://uniapp.dcloud.io/component/uniui/uni-badge)
6
+## 1.1.7(2021-11-08)
7
+- 优化 升级ui
8
+- 修改 size 属性默认值调整为 small
9
+- 修改 type 属性,默认值调整为 error,info 替换 default
10
+## 1.1.6(2021-09-22)
11
+- 修复 在字节小程序上样式不生效的 bug
12
+## 1.1.5(2021-07-30)
13
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
14
+## 1.1.4(2021-07-29)
15
+- 修复 去掉 nvue 不支持css 的 align-self 属性,nvue 下不暂支持 absolute 属性
16
+## 1.1.3(2021-06-24)
17
+- 优化 示例项目
18
+## 1.1.1(2021-05-12)
19
+- 新增 组件示例地址
20
+## 1.1.0(2021-05-12)
21
+- 新增 uni-badge 的 absolute 属性,支持定位
22
+- 新增 uni-badge 的 offset 属性,支持定位偏移
23
+- 新增 uni-badge 的 is-dot 属性,支持仅显示有一个小点
24
+- 新增 uni-badge 的 max-num 属性,支持自定义封顶的数字值,超过 99 显示99+
25
+- 优化 uni-badge 属性 custom-style, 支持以对象形式自定义样式
26
+## 1.0.7(2021-05-07)
27
+- 修复 uni-badge 在 App 端,数字小于10时不是圆形的bug
28
+- 修复 uni-badge 在父元素不是 flex 布局时,宽度缩小的bug
29
+- 新增 uni-badge 属性 custom-style, 支持自定义样式
30
+## 1.0.6(2021-02-04)
31
+- 调整为uni_modules目录规范

+ 268
- 0
oa-ui-app/uni_modules/uni-badge/components/uni-badge/uni-badge.vue Voir le fichier

@@ -0,0 +1,268 @@
1
+<template>
2
+	<view class="uni-badge--x">
3
+		<slot />
4
+		<text v-if="text" :class="classNames" :style="[positionStyle, customStyle, dotStyle]"
5
+			class="uni-badge" @click="onClick()">{{displayValue}}</text>
6
+	</view>
7
+</template>
8
+
9
+<script>
10
+	/**
11
+	 * Badge 数字角标
12
+	 * @description 数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景
13
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=21
14
+	 * @property {String} text 角标内容
15
+	 * @property {String} size = [normal|small] 角标内容
16
+	 * @property {String} type = [info|primary|success|warning|error] 颜色类型
17
+	 * 	@value info 灰色
18
+	 * 	@value primary 蓝色
19
+	 * 	@value success 绿色
20
+	 * 	@value warning 黄色
21
+	 * 	@value error 红色
22
+	 * @property {String} inverted = [true|false] 是否无需背景颜色
23
+	 * @property {Number} maxNum 展示封顶的数字值,超过 99 显示 99+
24
+	 * @property {String} absolute = [rightTop|rightBottom|leftBottom|leftTop] 开启绝对定位, 角标将定位到其包裹的标签的四角上		
25
+	 * 	@value rightTop 右上
26
+	 * 	@value rightBottom 右下
27
+	 * 	@value leftTop 左上
28
+	 * 	@value leftBottom 左下
29
+	 * @property {Array[number]} offset	距定位角中心点的偏移量,只有存在 absolute 属性时有效,例如:[-10, -10] 表示向外偏移 10px,[10, 10] 表示向 absolute 指定的内偏移 10px
30
+	 * @property {String} isDot = [true|false] 是否显示为一个小点
31
+	 * @event {Function} click 点击 Badge 触发事件
32
+	 * @example <uni-badge text="1"></uni-badge>
33
+	 */
34
+
35
+	export default {
36
+		name: 'UniBadge',
37
+		emits: ['click'],
38
+		props: {
39
+			type: {
40
+				type: String,
41
+				default: 'error'
42
+			},
43
+			inverted: {
44
+				type: Boolean,
45
+				default: false
46
+			},
47
+			isDot: {
48
+				type: Boolean,
49
+				default: false
50
+			},
51
+			maxNum: {
52
+				type: Number,
53
+				default: 99
54
+			},
55
+			absolute: {
56
+				type: String,
57
+				default: ''
58
+			},
59
+			offset: {
60
+				type: Array,
61
+				default () {
62
+					return [0, 0]
63
+				}
64
+			},
65
+			text: {
66
+				type: [String, Number],
67
+				default: ''
68
+			},
69
+			size: {
70
+				type: String,
71
+				default: 'small'
72
+			},
73
+			customStyle: {
74
+				type: Object,
75
+				default () {
76
+					return {}
77
+				}
78
+			}
79
+		},
80
+		data() {
81
+			return {};
82
+		},
83
+		computed: {
84
+			width() {
85
+				return String(this.text).length * 8 + 12
86
+			},
87
+			classNames() {
88
+				const {
89
+					inverted,
90
+					type,
91
+					size,
92
+					absolute
93
+				} = this
94
+				return [
95
+					inverted ? 'uni-badge--' + type + '-inverted' : '',
96
+					'uni-badge--' + type,
97
+					'uni-badge--' + size,
98
+					absolute ? 'uni-badge--absolute' : ''
99
+				].join(' ')
100
+			},
101
+			positionStyle() {
102
+				if (!this.absolute) return {}
103
+				let w = this.width / 2,
104
+					h = 10
105
+				if (this.isDot) {
106
+					w = 5
107
+					h = 5
108
+				}
109
+				const x = `${- w  + this.offset[0]}px`
110
+				const y = `${- h + this.offset[1]}px`
111
+
112
+				const whiteList = {
113
+					rightTop: {
114
+						right: x,
115
+						top: y
116
+					},
117
+					rightBottom: {
118
+						right: x,
119
+						bottom: y
120
+					},
121
+					leftBottom: {
122
+						left: x,
123
+						bottom: y
124
+					},
125
+					leftTop: {
126
+						left: x,
127
+						top: y
128
+					}
129
+				}
130
+				const match = whiteList[this.absolute]
131
+				return match ? match : whiteList['rightTop']
132
+			},
133
+			dotStyle() {
134
+				if (!this.isDot) return {}
135
+				return {
136
+					width: '10px',
137
+					minWidth: '0',
138
+					height: '10px',
139
+					padding: '0',
140
+					borderRadius: '10px'
141
+				}
142
+			},
143
+			displayValue() {
144
+				const {
145
+					isDot,
146
+					text,
147
+					maxNum
148
+				} = this
149
+				return isDot ? '' : (Number(text) > maxNum ? `${maxNum}+` : text)
150
+			}
151
+		},
152
+		methods: {
153
+			onClick() {
154
+				this.$emit('click');
155
+			}
156
+		}
157
+	};
158
+</script>
159
+
160
+<style lang="scss" >
161
+	$uni-primary: #2979ff !default;
162
+	$uni-success: #4cd964 !default;
163
+	$uni-warning: #f0ad4e !default;
164
+	$uni-error: #dd524d !default;
165
+	$uni-info: #909399 !default;
166
+
167
+
168
+	$bage-size: 12px;
169
+	$bage-small: scale(0.8);
170
+
171
+	.uni-badge--x {
172
+		/* #ifdef APP-NVUE */
173
+		// align-self: flex-start;
174
+		/* #endif */
175
+		/* #ifndef APP-NVUE */
176
+		display: inline-block;
177
+		/* #endif */
178
+		position: relative;
179
+	}
180
+
181
+	.uni-badge--absolute {
182
+		position: absolute;
183
+	}
184
+
185
+	.uni-badge--small {
186
+		transform: $bage-small;
187
+		transform-origin: center center;
188
+	}
189
+
190
+	.uni-badge {
191
+		/* #ifndef APP-NVUE */
192
+		display: flex;
193
+		overflow: hidden;
194
+		box-sizing: border-box;
195
+		/* #endif */
196
+		justify-content: center;
197
+		flex-direction: row;
198
+		height: 20px;
199
+		min-width: 20px;
200
+		padding: 0 4px;
201
+		line-height: 18px;
202
+		color: #fff;
203
+		border-radius: 100px;
204
+		background-color: $uni-info;
205
+		background-color: transparent;
206
+		border: 1px solid #fff;
207
+		text-align: center;
208
+		font-family: 'Helvetica Neue', Helvetica, sans-serif;
209
+		font-feature-settings: "tnum";
210
+		font-size: $bage-size;
211
+		/* #ifdef H5 */
212
+		z-index: 999;
213
+		cursor: pointer;
214
+		/* #endif */
215
+
216
+		&--info {
217
+			color: #fff;
218
+			background-color: $uni-info;
219
+		}
220
+
221
+		&--primary {
222
+			background-color: $uni-primary;
223
+		}
224
+
225
+		&--success {
226
+			background-color: $uni-success;
227
+		}
228
+
229
+		&--warning {
230
+			background-color: $uni-warning;
231
+		}
232
+
233
+		&--error {
234
+			background-color: $uni-error;
235
+		}
236
+
237
+		&--inverted {
238
+			padding: 0 5px 0 0;
239
+			color: $uni-info;
240
+		}
241
+
242
+		&--info-inverted {
243
+			color: $uni-info;
244
+			background-color: transparent;
245
+		}
246
+
247
+		&--primary-inverted {
248
+			color: $uni-primary;
249
+			background-color: transparent;
250
+		}
251
+
252
+		&--success-inverted {
253
+			color: $uni-success;
254
+			background-color: transparent;
255
+		}
256
+
257
+		&--warning-inverted {
258
+			color: $uni-warning;
259
+			background-color: transparent;
260
+		}
261
+
262
+		&--error-inverted {
263
+			color: $uni-error;
264
+			background-color: transparent;
265
+		}
266
+
267
+	}
268
+</style>

+ 85
- 0
oa-ui-app/uni_modules/uni-badge/package.json Voir le fichier

@@ -0,0 +1,85 @@
1
+{
2
+  "id": "uni-badge",
3
+  "displayName": "uni-badge 数字角标",
4
+  "version": "1.2.1",
5
+  "description": "数字角标(徽章)组件,在元素周围展示消息提醒,一般用于列表、九宫格、按钮等地方。",
6
+  "keywords": [
7
+    "",
8
+    "badge",
9
+    "uni-ui",
10
+    "uniui",
11
+    "数字角标",
12
+    "徽章"
13
+],
14
+  "repository": "https://github.com/dcloudio/uni-ui",
15
+  "engines": {
16
+    "HBuilderX": ""
17
+  },
18
+  "directories": {
19
+    "example": "../../temps/example_temps"
20
+  },
21
+"dcloudext": {
22
+    "sale": {
23
+      "regular": {
24
+        "price": "0.00"
25
+      },
26
+      "sourcecode": {
27
+        "price": "0.00"
28
+      }
29
+    },
30
+    "contact": {
31
+      "qq": ""
32
+    },
33
+    "declaration": {
34
+      "ads": "无",
35
+      "data": "无",
36
+      "permissions": "无"
37
+    },
38
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
39
+    "type": "component-vue"
40
+  },
41
+  "uni_modules": {
42
+    "dependencies": ["uni-scss"],
43
+    "encrypt": [],
44
+    "platforms": {
45
+      "cloud": {
46
+        "tcb": "y",
47
+        "aliyun": "y"
48
+      },
49
+      "client": {
50
+        "App": {
51
+          "app-vue": "y",
52
+          "app-nvue": "y"
53
+        },
54
+        "H5-mobile": {
55
+          "Safari": "y",
56
+          "Android Browser": "y",
57
+          "微信浏览器(Android)": "y",
58
+          "QQ浏览器(Android)": "y"
59
+        },
60
+        "H5-pc": {
61
+          "Chrome": "y",
62
+          "IE": "y",
63
+          "Edge": "y",
64
+          "Firefox": "y",
65
+          "Safari": "y"
66
+        },
67
+        "小程序": {
68
+          "微信": "y",
69
+          "阿里": "y",
70
+          "百度": "y",
71
+          "字节跳动": "y",
72
+          "QQ": "y"
73
+        },
74
+        "快应用": {
75
+          "华为": "y",
76
+          "联盟": "y"
77
+        },
78
+        "Vue": {
79
+            "vue2": "y",
80
+            "vue3": "y"
81
+        }
82
+      }
83
+    }
84
+  }
85
+}

+ 10
- 0
oa-ui-app/uni_modules/uni-badge/readme.md Voir le fichier

@@ -0,0 +1,10 @@
1
+## Badge 数字角标
2
+> **组件名:uni-badge**
3
+> 代码块: `uBadge`
4
+
5
+数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景,
6
+
7
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-badge)
8
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
9
+
10
+

+ 6
- 0
oa-ui-app/uni_modules/uni-breadcrumb/changelog.md Voir le fichier

@@ -0,0 +1,6 @@
1
+## 0.1.2(2022-06-08)
2
+- 修复 微信小程序 separator 不显示问题
3
+## 0.1.1(2022-06-02)
4
+- 新增 支持 uni.scss 修改颜色
5
+## 0.1.0(2022-04-21)
6
+- 初始化

+ 121
- 0
oa-ui-app/uni_modules/uni-breadcrumb/components/uni-breadcrumb-item/uni-breadcrumb-item.vue Voir le fichier

@@ -0,0 +1,121 @@
1
+<template>
2
+	<view class="uni-breadcrumb-item">
3
+		<view :class="{
4
+			'uni-breadcrumb-item--slot': true,
5
+			'uni-breadcrumb-item--slot-link': to && currentPage !== to
6
+			}" @click="navTo">
7
+			<slot />
8
+		</view>
9
+		<i v-if="separatorClass" class="uni-breadcrumb-item--separator" :class="separatorClass" />
10
+		<text v-else class="uni-breadcrumb-item--separator">{{ separator }}</text>
11
+	</view>
12
+</template>
13
+<script>
14
+	/**
15
+	 * BreadcrumbItem 面包屑导航子组件
16
+	 * @property {String/Object} to 路由跳转页面路径/对象
17
+	 * @property {Boolean} replace 在使用 to 进行路由跳转时,启用 replace 将不会向 history 添加新记录(仅 h5 支持)
18
+	 */
19
+	export default {
20
+		data() {
21
+			return {
22
+				currentPage: ""
23
+			}
24
+		},
25
+		options: {
26
+			virtualHost: true
27
+		},
28
+		props: {
29
+			to: {
30
+				type: String,
31
+				default: ''
32
+			},
33
+			replace:{
34
+				type: Boolean,
35
+				default: false
36
+			}
37
+		},
38
+		inject: {
39
+			uniBreadcrumb: {
40
+				from: "uniBreadcrumb",
41
+				default: null
42
+			}
43
+		},
44
+		created(){
45
+			const pages = getCurrentPages()
46
+			const page = pages[pages.length-1]
47
+
48
+			if(page){
49
+				this.currentPage = `/${page.route}`
50
+			}
51
+		},
52
+		computed: {
53
+			separator() {
54
+				return this.uniBreadcrumb.separator
55
+			},
56
+			separatorClass() {
57
+				return this.uniBreadcrumb.separatorClass
58
+			}
59
+		},
60
+		methods: {
61
+			navTo() {
62
+				const { to } = this
63
+
64
+				if (!to || this.currentPage === to){
65
+					return
66
+				}
67
+
68
+				if(this.replace){
69
+					uni.redirectTo({
70
+						url:to
71
+					})
72
+				}else{
73
+					uni.navigateTo({
74
+						url:to
75
+					})
76
+				}
77
+			}
78
+		}
79
+	}
80
+</script>
81
+<style lang="scss">
82
+	$uni-primary: #2979ff !default;
83
+	$uni-base-color: #6a6a6a !default;
84
+	$uni-main-color: #3a3a3a !default;
85
+	.uni-breadcrumb-item {
86
+		display: flex;
87
+		align-items: center;
88
+		white-space: nowrap;
89
+		font-size: 14px;
90
+
91
+		&--slot {
92
+			color: $uni-base-color;
93
+			padding: 0 10px;
94
+
95
+			&-link {
96
+				color: $uni-main-color;
97
+				font-weight: bold;
98
+				/* #ifndef APP-NVUE */
99
+				cursor: pointer;
100
+				/* #endif */
101
+
102
+				&:hover {
103
+					color: $uni-primary;
104
+				}
105
+			}
106
+		}
107
+
108
+		&--separator {
109
+			font-size: 12px;
110
+			color: $uni-base-color;
111
+		}
112
+
113
+		&:first-child &--slot {
114
+			padding-left: 0;
115
+		}
116
+		
117
+		&:last-child &--separator {
118
+			display: none;
119
+		}
120
+	}
121
+</style>

+ 41
- 0
oa-ui-app/uni_modules/uni-breadcrumb/components/uni-breadcrumb/uni-breadcrumb.vue Voir le fichier

@@ -0,0 +1,41 @@
1
+<template>
2
+	<view class="uni-breadcrumb">
3
+		<slot />
4
+	</view>
5
+</template>
6
+<script>
7
+	/**
8
+	 * Breadcrumb 面包屑导航父组件
9
+	 * @description 显示当前页面的路径,快速返回之前的任意页面
10
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
11
+	 * @property {String} separator 分隔符,默认为斜杠'/'
12
+	 * @property {String} separatorClass 图标分隔符 class
13
+	 */
14
+	export default {
15
+		options: {
16
+			virtualHost: true
17
+		},
18
+		props: {
19
+			separator: {
20
+				type: String,
21
+				default: '/'
22
+			},
23
+			separatorClass: {
24
+				type: String,
25
+				default: ''
26
+			}
27
+		},
28
+
29
+		provide() {
30
+			return {
31
+				uniBreadcrumb: this
32
+			}
33
+		}
34
+
35
+	}
36
+</script>
37
+<style lang="scss">
38
+	.uni-breadcrumb {
39
+		display: flex;
40
+	}
41
+</style>

+ 88
- 0
oa-ui-app/uni_modules/uni-breadcrumb/package.json Voir le fichier

@@ -0,0 +1,88 @@
1
+{
2
+  "id": "uni-breadcrumb",
3
+  "displayName": "uni-breadcrumb 面包屑",
4
+  "version": "0.1.2",
5
+  "description": "Breadcrumb  面包屑",
6
+  "keywords": [
7
+    "uni-breadcrumb",
8
+    "breadcrumb",
9
+    "uni-ui",
10
+    "面包屑导航",
11
+    "面包屑"
12
+],
13
+  "repository": "",
14
+  "engines": {
15
+    "HBuilderX": "^3.1.0"
16
+  },
17
+  "directories": {
18
+    "example": "../../temps/example_temps"
19
+  },
20
+  "dcloudext": {
21
+    "category": [
22
+        "前端组件",
23
+        "通用组件"
24
+    ],
25
+    "sale": {
26
+      "regular": {
27
+        "price": "0.00"
28
+      },
29
+      "sourcecode": {
30
+        "price": "0.00"
31
+      }
32
+    },
33
+    "contact": {
34
+      "qq": ""
35
+    },
36
+    "declaration": {
37
+      "ads": "无",
38
+      "data": "无",
39
+      "permissions": "无"
40
+    },
41
+    "npmurl": ""
42
+  },
43
+  "uni_modules": {
44
+    "dependencies": [],
45
+    "encrypt": [],
46
+    "platforms": {
47
+      "cloud": {
48
+        "tcb": "y",
49
+        "aliyun": "y"
50
+      },
51
+      "client": {
52
+        "Vue": {
53
+          "vue2": "y",
54
+          "vue3": "y"
55
+        },
56
+        "App": {
57
+          "app-vue": "y",
58
+          "app-nvue": "n"
59
+        },
60
+        "H5-mobile": {
61
+          "Safari": "y",
62
+          "Android Browser": "y",
63
+          "微信浏览器(Android)": "y",
64
+          "QQ浏览器(Android)": "y"
65
+        },
66
+        "H5-pc": {
67
+          "Chrome": "y",
68
+          "IE": "y",
69
+          "Edge": "y",
70
+          "Firefox": "y",
71
+          "Safari": "y"
72
+        },
73
+        "小程序": {
74
+          "微信": "y",
75
+          "阿里": "u",
76
+          "百度": "u",
77
+          "字节跳动": "u",
78
+        "QQ": "u",
79
+        "京东": "u"
80
+        },
81
+        "快应用": {
82
+          "华为": "u",
83
+          "联盟": "u"
84
+        }
85
+      }
86
+    }
87
+  }
88
+}

+ 66
- 0
oa-ui-app/uni_modules/uni-breadcrumb/readme.md Voir le fichier

@@ -0,0 +1,66 @@
1
+
2
+## breadcrumb 面包屑导航
3
+> **组件名:uni-breadcrumb**
4
+> 代码块: `ubreadcrumb`
5
+
6
+显示当前页面的路径,快速返回之前的任意页面。
7
+
8
+### 安装方式
9
+
10
+本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
11
+
12
+如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
13
+
14
+### 基本用法
15
+
16
+在 ``template`` 中使用组件
17
+
18
+```html
19
+<uni-breadcrumb separator="/">
20
+	<uni-breadcrumb-item v-for="(route,index) in routes" :key="index" :to="route.to">{{route.name}}</uni-breadcrumb-item>
21
+</uni-breadcrumb>
22
+```
23
+
24
+```js
25
+export default {
26
+		name: "uni-stat-breadcrumb",
27
+		data() {
28
+			return {
29
+				routes: [{
30
+					to: '/A',
31
+					name: 'A页面'
32
+				}, {
33
+					to: '/B',
34
+					name: 'B页面'
35
+				}, {
36
+					to: '/C',
37
+					name: 'C页面'
38
+				}]
39
+			};
40
+		}
41
+	}
42
+```
43
+
44
+
45
+## API
46
+
47
+### Breadcrumb Props
48
+
49
+|属性名			|类型	|默认值	|说明				|
50
+|:-:			|:-:	|:-:	|:-:				|
51
+|separator		|String	|斜杠'/' |分隔符				|
52
+|separatorClass	|String	|		|图标分隔符 class	    |
53
+
54
+### Breadcrumb Item Props
55
+
56
+|属性名	|类型			|默认值	|说明																			|
57
+|:-:	|:-:			|:-:	|:-:																			|
58
+|to		|String     	|		|路由跳转页面路径           														|
59
+|replace|Boolean		|		|在使用 to 进行路由跳转时,启用 replace 将不会向 history 添加新记录(仅 h5 支持)         |
60
+
61
+
62
+
63
+
64
+## 组件示例
65
+
66
+点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/breadcrumb/breadcrumb](https://hellouniapp.dcloud.net.cn/pages/extUI/breadcrumb/breadcrumb)

+ 20
- 0
oa-ui-app/uni_modules/uni-calendar/changelog.md Voir le fichier

@@ -0,0 +1,20 @@
1
+## 1.4.7(2022-09-16)
2
+- 可以使用 uni-scss 控制主题色
3
+## 1.4.6(2022-09-08)
4
+- fix: 表头年月切换,导致改变当前日期为选择月1号,且未触发change事件
5
+## 1.4.5(2022-02-25)
6
+- 修复 条件编译 nvue 不支持的 css 样式
7
+## 1.4.4(2022-02-25)
8
+- 修复 条件编译 nvue 不支持的 css 样式
9
+## 1.4.3(2021-09-22)
10
+- 修复 startDate、 endDate 属性失效的 bug
11
+## 1.4.2(2021-08-24)
12
+- 新增 支持国际化
13
+## 1.4.1(2021-08-05)
14
+- 修复 弹出层被 tabbar 遮盖 bug
15
+## 1.4.0(2021-07-30)
16
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
17
+## 1.3.16(2021-05-12)
18
+- 新增 组件示例地址
19
+## 1.3.15(2021-02-04)
20
+- 调整为uni_modules目录规范 

+ 546
- 0
oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/calendar.js Voir le fichier

@@ -0,0 +1,546 @@
1
+/**
2
+* @1900-2100区间内的公历、农历互转
3
+* @charset UTF-8
4
+* @github  https://github.com/jjonline/calendar.js
5
+* @Author  Jea杨(JJonline@JJonline.Cn)
6
+* @Time    2014-7-21
7
+* @Time    2016-8-13 Fixed 2033hex、Attribution Annals
8
+* @Time    2016-9-25 Fixed lunar LeapMonth Param Bug
9
+* @Time    2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
10
+* @Version 1.0.3
11
+* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
12
+* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
13
+*/
14
+/* eslint-disable */
15
+var calendar = {
16
+
17
+  /**
18
+      * 农历1900-2100的润大小信息表
19
+      * @Array Of Property
20
+      * @return Hex
21
+      */
22
+  lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
23
+    0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
24
+    0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
25
+    0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
26
+    0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
27
+    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
28
+    0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
29
+    0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
30
+    0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
31
+    0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
32
+    0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
33
+    0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
34
+    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
35
+    0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
36
+    0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
37
+    /** Add By JJonline@JJonline.Cn**/
38
+    0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
39
+    0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
40
+    0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
41
+    0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
42
+    0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
43
+    0x0d520], // 2100
44
+
45
+  /**
46
+      * 公历每个月份的天数普通表
47
+      * @Array Of Property
48
+      * @return Number
49
+      */
50
+  solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
51
+
52
+  /**
53
+      * 天干地支之天干速查表
54
+      * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
55
+      * @return Cn string
56
+      */
57
+  Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
58
+
59
+  /**
60
+      * 天干地支之地支速查表
61
+      * @Array Of Property
62
+      * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
63
+      * @return Cn string
64
+      */
65
+  Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
66
+
67
+  /**
68
+      * 天干地支之地支速查表<=>生肖
69
+      * @Array Of Property
70
+      * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
71
+      * @return Cn string
72
+      */
73
+  Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
74
+
75
+  /**
76
+      * 24节气速查表
77
+      * @Array Of Property
78
+      * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
79
+      * @return Cn string
80
+      */
81
+  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'],
82
+
83
+  /**
84
+      * 1900-2100各年的24节气日期速查表
85
+      * @Array Of Property
86
+      * @return 0x string For splice
87
+      */
88
+  sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
89
+    '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
90
+    '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
91
+    '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
92
+    'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
93
+    '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
94
+    '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
95
+    '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
96
+    '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
97
+    '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
98
+    '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
99
+    '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
100
+    '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
101
+    '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
102
+    '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
103
+    '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
104
+    '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
105
+    '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
106
+    '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
107
+    '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
108
+    '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
109
+    '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
110
+    '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
111
+    '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
112
+    '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
113
+    '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
114
+    '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
115
+    '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
116
+    '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
117
+    '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
118
+    '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
119
+    '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
120
+    '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
121
+    '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
122
+    '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
123
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
124
+    '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
125
+    '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
126
+    '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
127
+    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
128
+    '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
129
+    '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
130
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
131
+    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
132
+    '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
133
+    '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
134
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
135
+    '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
136
+    '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
137
+    '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
138
+    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
139
+    '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
140
+    '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
141
+    '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
142
+    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
143
+    '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
144
+    '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
145
+    '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
146
+    '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
147
+    '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
148
+    '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
149
+    '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
150
+    '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
151
+    '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
152
+    '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
153
+    '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
154
+    '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
155
+
156
+  /**
157
+      * 数字转中文速查表
158
+      * @Array Of Property
159
+      * @trans ['日','一','二','三','四','五','六','七','八','九','十']
160
+      * @return Cn string
161
+      */
162
+  nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
163
+
164
+  /**
165
+      * 日期转农历称呼速查表
166
+      * @Array Of Property
167
+      * @trans ['初','十','廿','卅']
168
+      * @return Cn string
169
+      */
170
+  nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
171
+
172
+  /**
173
+      * 月份转农历称呼速查表
174
+      * @Array Of Property
175
+      * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
176
+      * @return Cn string
177
+      */
178
+  nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
179
+
180
+  /**
181
+      * 返回农历y年一整年的总天数
182
+      * @param lunar Year
183
+      * @return Number
184
+      * @eg:var count = calendar.lYearDays(1987) ;//count=387
185
+      */
186
+  lYearDays: function (y) {
187
+    var i; var sum = 348
188
+    for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
189
+    return (sum + this.leapDays(y))
190
+  },
191
+
192
+  /**
193
+      * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
194
+      * @param lunar Year
195
+      * @return Number (0-12)
196
+      * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
197
+      */
198
+  leapMonth: function (y) { // 闰字编码 \u95f0
199
+    return (this.lunarInfo[y - 1900] & 0xf)
200
+  },
201
+
202
+  /**
203
+      * 返回农历y年闰月的天数 若该年没有闰月则返回0
204
+      * @param lunar Year
205
+      * @return Number (0、29、30)
206
+      * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
207
+      */
208
+  leapDays: function (y) {
209
+    if (this.leapMonth(y)) {
210
+      return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
211
+    }
212
+    return (0)
213
+  },
214
+
215
+  /**
216
+      * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
217
+      * @param lunar Year
218
+      * @return Number (-1、29、30)
219
+      * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
220
+      */
221
+  monthDays: function (y, m) {
222
+    if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
223
+    return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
224
+  },
225
+
226
+  /**
227
+      * 返回公历(!)y年m月的天数
228
+      * @param solar Year
229
+      * @return Number (-1、28、29、30、31)
230
+      * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
231
+      */
232
+  solarDays: function (y, m) {
233
+    if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
234
+    var ms = m - 1
235
+    if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
236
+      return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
237
+    } else {
238
+      return (this.solarMonth[ms])
239
+    }
240
+  },
241
+
242
+  /**
243
+     * 农历年份转换为干支纪年
244
+     * @param  lYear 农历年的年份数
245
+     * @return Cn string
246
+     */
247
+  toGanZhiYear: function (lYear) {
248
+    var ganKey = (lYear - 3) % 10
249
+    var zhiKey = (lYear - 3) % 12
250
+    if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
251
+    if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
252
+    return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
253
+  },
254
+
255
+  /**
256
+     * 公历月、日判断所属星座
257
+     * @param  cMonth [description]
258
+     * @param  cDay [description]
259
+     * @return Cn string
260
+     */
261
+  toAstro: function (cMonth, cDay) {
262
+    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'
263
+    var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
264
+    return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
265
+  },
266
+
267
+  /**
268
+      * 传入offset偏移量返回干支
269
+      * @param offset 相对甲子的偏移量
270
+      * @return Cn string
271
+      */
272
+  toGanZhi: function (offset) {
273
+    return this.Gan[offset % 10] + this.Zhi[offset % 12]
274
+  },
275
+
276
+  /**
277
+      * 传入公历(!)y年获得该年第n个节气的公历日期
278
+      * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
279
+      * @return day Number
280
+      * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
281
+      */
282
+  getTerm: function (y, n) {
283
+    if (y < 1900 || y > 2100) { return -1 }
284
+    if (n < 1 || n > 24) { return -1 }
285
+    var _table = this.sTermInfo[y - 1900]
286
+    var _info = [
287
+      parseInt('0x' + _table.substr(0, 5)).toString(),
288
+      parseInt('0x' + _table.substr(5, 5)).toString(),
289
+      parseInt('0x' + _table.substr(10, 5)).toString(),
290
+      parseInt('0x' + _table.substr(15, 5)).toString(),
291
+      parseInt('0x' + _table.substr(20, 5)).toString(),
292
+      parseInt('0x' + _table.substr(25, 5)).toString()
293
+    ]
294
+    var _calday = [
295
+      _info[0].substr(0, 1),
296
+      _info[0].substr(1, 2),
297
+      _info[0].substr(3, 1),
298
+      _info[0].substr(4, 2),
299
+
300
+      _info[1].substr(0, 1),
301
+      _info[1].substr(1, 2),
302
+      _info[1].substr(3, 1),
303
+      _info[1].substr(4, 2),
304
+
305
+      _info[2].substr(0, 1),
306
+      _info[2].substr(1, 2),
307
+      _info[2].substr(3, 1),
308
+      _info[2].substr(4, 2),
309
+
310
+      _info[3].substr(0, 1),
311
+      _info[3].substr(1, 2),
312
+      _info[3].substr(3, 1),
313
+      _info[3].substr(4, 2),
314
+
315
+      _info[4].substr(0, 1),
316
+      _info[4].substr(1, 2),
317
+      _info[4].substr(3, 1),
318
+      _info[4].substr(4, 2),
319
+
320
+      _info[5].substr(0, 1),
321
+      _info[5].substr(1, 2),
322
+      _info[5].substr(3, 1),
323
+      _info[5].substr(4, 2)
324
+    ]
325
+    return parseInt(_calday[n - 1])
326
+  },
327
+
328
+  /**
329
+      * 传入农历数字月份返回汉语通俗表示法
330
+      * @param lunar month
331
+      * @return Cn string
332
+      * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
333
+      */
334
+  toChinaMonth: function (m) { // 月 => \u6708
335
+    if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
336
+    var s = this.nStr3[m - 1]
337
+    s += '\u6708'// 加上月字
338
+    return s
339
+  },
340
+
341
+  /**
342
+      * 传入农历日期数字返回汉字表示法
343
+      * @param lunar day
344
+      * @return Cn string
345
+      * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
346
+      */
347
+  toChinaDay: function (d) { // 日 => \u65e5
348
+    var s
349
+    switch (d) {
350
+      case 10:
351
+        s = '\u521d\u5341'; break
352
+      case 20:
353
+        s = '\u4e8c\u5341'; break
354
+        break
355
+      case 30:
356
+        s = '\u4e09\u5341'; break
357
+        break
358
+      default :
359
+        s = this.nStr2[Math.floor(d / 10)]
360
+        s += this.nStr1[d % 10]
361
+    }
362
+    return (s)
363
+  },
364
+
365
+  /**
366
+      * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
367
+      * @param y year
368
+      * @return Cn string
369
+      * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
370
+      */
371
+  getAnimal: function (y) {
372
+    return this.Animals[(y - 4) % 12]
373
+  },
374
+
375
+  /**
376
+      * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
377
+      * @param y  solar year
378
+      * @param m  solar month
379
+      * @param d  solar day
380
+      * @return JSON object
381
+      * @eg:console.log(calendar.solar2lunar(1987,11,01));
382
+      */
383
+  solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
384
+    // 年份限定、上限
385
+    if (y < 1900 || y > 2100) {
386
+      return -1// undefined转换为数字变为NaN
387
+    }
388
+    // 公历传参最下限
389
+    if (y == 1900 && m == 1 && d < 31) {
390
+      return -1
391
+    }
392
+    // 未传参  获得当天
393
+    if (!y) {
394
+      var objDate = new Date()
395
+    } else {
396
+      var objDate = new Date(y, parseInt(m) - 1, d)
397
+    }
398
+    var i; var leap = 0; var temp = 0
399
+    // 修正ymd参数
400
+    var y = objDate.getFullYear()
401
+    var m = objDate.getMonth() + 1
402
+    var d = objDate.getDate()
403
+    var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
404
+    for (i = 1900; i < 2101 && offset > 0; i++) {
405
+      temp = this.lYearDays(i)
406
+      offset -= temp
407
+    }
408
+    if (offset < 0) {
409
+      offset += temp; i--
410
+    }
411
+
412
+    // 是否今天
413
+    var isTodayObj = new Date()
414
+    var isToday = false
415
+    if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
416
+      isToday = true
417
+    }
418
+    // 星期几
419
+    var nWeek = objDate.getDay()
420
+    var cWeek = this.nStr1[nWeek]
421
+    // 数字表示周几顺应天朝周一开始的惯例
422
+    if (nWeek == 0) {
423
+      nWeek = 7
424
+    }
425
+    // 农历年
426
+    var year = i
427
+    var leap = this.leapMonth(i) // 闰哪个月
428
+    var isLeap = false
429
+
430
+    // 效验闰月
431
+    for (i = 1; i < 13 && offset > 0; i++) {
432
+      // 闰月
433
+      if (leap > 0 && i == (leap + 1) && isLeap == false) {
434
+        --i
435
+        isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
436
+      } else {
437
+        temp = this.monthDays(year, i)// 计算农历普通月天数
438
+      }
439
+      // 解除闰月
440
+      if (isLeap == true && i == (leap + 1)) { isLeap = false }
441
+      offset -= temp
442
+    }
443
+    // 闰月导致数组下标重叠取反
444
+    if (offset == 0 && leap > 0 && i == leap + 1) {
445
+      if (isLeap) {
446
+        isLeap = false
447
+      } else {
448
+        isLeap = true; --i
449
+      }
450
+    }
451
+    if (offset < 0) {
452
+      offset += temp; --i
453
+    }
454
+    // 农历月
455
+    var month = i
456
+    // 农历日
457
+    var day = offset + 1
458
+    // 天干地支处理
459
+    var sm = m - 1
460
+    var gzY = this.toGanZhiYear(year)
461
+
462
+    // 当月的两个节气
463
+    // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
464
+    var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
465
+    var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
466
+
467
+    // 依据12节气修正干支月
468
+    var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
469
+    if (d >= firstNode) {
470
+      gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
471
+    }
472
+
473
+    // 传入的日期的节气与否
474
+    var isTerm = false
475
+    var Term = null
476
+    if (firstNode == d) {
477
+      isTerm = true
478
+      Term = this.solarTerm[m * 2 - 2]
479
+    }
480
+    if (secondNode == d) {
481
+      isTerm = true
482
+      Term = this.solarTerm[m * 2 - 1]
483
+    }
484
+    // 日柱 当月一日与 1900/1/1 相差天数
485
+    var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
486
+    var gzD = this.toGanZhi(dayCyclical + d - 1)
487
+    // 该日期所属的星座
488
+    var astro = this.toAstro(m, d)
489
+
490
+    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 }
491
+  },
492
+
493
+  /**
494
+      * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
495
+      * @param y  lunar year
496
+      * @param m  lunar month
497
+      * @param d  lunar day
498
+      * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
499
+      * @return JSON object
500
+      * @eg:console.log(calendar.lunar2solar(1987,9,10));
501
+      */
502
+  lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
503
+    var isLeapMonth = !!isLeapMonth
504
+    var leapOffset = 0
505
+    var leapMonth = this.leapMonth(y)
506
+    var leapDay = this.leapDays(y)
507
+    if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
508
+    if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
509
+    var day = this.monthDays(y, m)
510
+    var _day = day
511
+    // bugFix 2016-9-25
512
+    // if month is leap, _day use leapDays method
513
+    if (isLeapMonth) {
514
+      _day = this.leapDays(y, m)
515
+    }
516
+    if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
517
+
518
+    // 计算农历的时间差
519
+    var offset = 0
520
+    for (var i = 1900; i < y; i++) {
521
+      offset += this.lYearDays(i)
522
+    }
523
+    var leap = 0; var isAdd = false
524
+    for (var i = 1; i < m; i++) {
525
+      leap = this.leapMonth(y)
526
+      if (!isAdd) { // 处理闰月
527
+        if (leap <= i && leap > 0) {
528
+          offset += this.leapDays(y); isAdd = true
529
+        }
530
+      }
531
+      offset += this.monthDays(y, i)
532
+    }
533
+    // 转换闰月农历 需补充该年闰月的前一个月的时差
534
+    if (isLeapMonth) { offset += day }
535
+    // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
536
+    var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
537
+    var calObj = new Date((offset + d - 31) * 86400000 + stmap)
538
+    var cY = calObj.getUTCFullYear()
539
+    var cM = calObj.getUTCMonth() + 1
540
+    var cD = calObj.getUTCDate()
541
+
542
+    return this.solar2lunar(cY, cM, cD)
543
+  }
544
+}
545
+
546
+export default calendar

+ 12
- 0
oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json Voir le fichier

@@ -0,0 +1,12 @@
1
+{
2
+	"uni-calender.ok": "ok",
3
+	"uni-calender.cancel": "cancel",
4
+	"uni-calender.today": "today",
5
+	"uni-calender.MON": "MON",
6
+	"uni-calender.TUE": "TUE",
7
+	"uni-calender.WED": "WED",
8
+	"uni-calender.THU": "THU",
9
+	"uni-calender.FRI": "FRI",
10
+	"uni-calender.SAT": "SAT",
11
+	"uni-calender.SUN": "SUN"
12
+}

+ 8
- 0
oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js Voir le fichier

@@ -0,0 +1,8 @@
1
+import en from './en.json'
2
+import zhHans from './zh-Hans.json'
3
+import zhHant from './zh-Hant.json'
4
+export default {
5
+	en,
6
+	'zh-Hans': zhHans,
7
+	'zh-Hant': zhHant
8
+}

+ 12
- 0
oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json Voir le fichier

@@ -0,0 +1,12 @@
1
+{
2
+	"uni-calender.ok": "确定",
3
+	"uni-calender.cancel": "取消",
4
+	"uni-calender.today": "今日",
5
+	"uni-calender.SUN": "日",
6
+	"uni-calender.MON": "一",
7
+	"uni-calender.TUE": "二",
8
+	"uni-calender.WED": "三",
9
+	"uni-calender.THU": "四",
10
+	"uni-calender.FRI": "五",
11
+	"uni-calender.SAT": "六"
12
+}

+ 12
- 0
oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json Voir le fichier

@@ -0,0 +1,12 @@
1
+{
2
+	"uni-calender.ok": "確定",
3
+	"uni-calender.cancel": "取消",
4
+	"uni-calender.today": "今日",
5
+	"uni-calender.SUN": "日",
6
+	"uni-calender.MON": "一",
7
+	"uni-calender.TUE": "二",
8
+	"uni-calender.WED": "三",
9
+	"uni-calender.THU": "四",
10
+	"uni-calender.FRI": "五",
11
+	"uni-calender.SAT": "六"
12
+}

+ 188
- 0
oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue Voir le fichier

@@ -0,0 +1,188 @@
1
+<template>
2
+	<view class="uni-calendar-item__weeks-box" :class="{
3
+		'uni-calendar-item--disable':weeks.disable,
4
+		'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
5
+		'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
6
+		'uni-calendar-item--before-checked':weeks.beforeMultiple,
7
+		'uni-calendar-item--multiple': weeks.multiple,
8
+		'uni-calendar-item--after-checked':weeks.afterMultiple,
9
+		}"
10
+	 @click="choiceDate(weeks)">
11
+		<view class="uni-calendar-item__weeks-box-item">
12
+			<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
13
+			<text class="uni-calendar-item__weeks-box-text" :class="{
14
+				'uni-calendar-item--isDay-text': weeks.isDay,
15
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
16
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
17
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
18
+				'uni-calendar-item--multiple': weeks.multiple,
19
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
20
+				'uni-calendar-item--disable':weeks.disable,
21
+				}">{{weeks.date}}</text>
22
+			<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
23
+				'uni-calendar-item--isDay-text':weeks.isDay,
24
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
25
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
26
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
27
+				'uni-calendar-item--multiple': weeks.multiple,
28
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
29
+				}">{{todayText}}</text>
30
+			<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
31
+				'uni-calendar-item--isDay-text':weeks.isDay,
32
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
33
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
34
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
35
+				'uni-calendar-item--multiple': weeks.multiple,
36
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
37
+				'uni-calendar-item--disable':weeks.disable,
38
+				}">{{weeks.isDay ? todayText : (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
39
+			<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
40
+				'uni-calendar-item--extra':weeks.extraInfo.info,
41
+				'uni-calendar-item--isDay-text':weeks.isDay,
42
+				'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
43
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
44
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
45
+				'uni-calendar-item--multiple': weeks.multiple,
46
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
47
+				'uni-calendar-item--disable':weeks.disable,
48
+				}">{{weeks.extraInfo.info}}</text>
49
+		</view>
50
+	</view>
51
+</template>
52
+
53
+<script>
54
+	import {
55
+	initVueI18n
56
+	} from '@dcloudio/uni-i18n'
57
+	import messages from './i18n/index.js'
58
+	const {	t	} = initVueI18n(messages)
59
+	export default {
60
+		emits:['change'],
61
+		props: {
62
+			weeks: {
63
+				type: Object,
64
+				default () {
65
+					return {}
66
+				}
67
+			},
68
+			calendar: {
69
+				type: Object,
70
+				default: () => {
71
+					return {}
72
+				}
73
+			},
74
+			selected: {
75
+				type: Array,
76
+				default: () => {
77
+					return []
78
+				}
79
+			},
80
+			lunar: {
81
+				type: Boolean,
82
+				default: false
83
+			}
84
+		},
85
+		computed: {
86
+			todayText() {
87
+				return t("uni-calender.today")
88
+			},
89
+		},
90
+		methods: {
91
+			choiceDate(weeks) {
92
+				this.$emit('change', weeks)
93
+			}
94
+		}
95
+	}
96
+</script>
97
+
98
+<style lang="scss" scoped>
99
+	$uni-font-size-base:14px;
100
+	$uni-text-color:#333;
101
+	$uni-font-size-sm:12px;
102
+	$uni-color-error: #e43d33;
103
+	$uni-opacity-disabled: 0.3;
104
+	$uni-text-color-disable:#c0c0c0;
105
+	$uni-primary: #2979ff !default;
106
+	.uni-calendar-item__weeks-box {
107
+		flex: 1;
108
+		/* #ifndef APP-NVUE */
109
+		display: flex;
110
+		/* #endif */
111
+		flex-direction: column;
112
+		justify-content: center;
113
+		align-items: center;
114
+	}
115
+
116
+	.uni-calendar-item__weeks-box-text {
117
+		font-size: $uni-font-size-base;
118
+		color: $uni-text-color;
119
+	}
120
+
121
+	.uni-calendar-item__weeks-lunar-text {
122
+		font-size: $uni-font-size-sm;
123
+		color: $uni-text-color;
124
+	}
125
+
126
+	.uni-calendar-item__weeks-box-item {
127
+		position: relative;
128
+		/* #ifndef APP-NVUE */
129
+		display: flex;
130
+		/* #endif */
131
+		flex-direction: column;
132
+		justify-content: center;
133
+		align-items: center;
134
+		width: 100rpx;
135
+		height: 100rpx;
136
+	}
137
+
138
+	.uni-calendar-item__weeks-box-circle {
139
+		position: absolute;
140
+		top: 5px;
141
+		right: 5px;
142
+		width: 8px;
143
+		height: 8px;
144
+		border-radius: 8px;
145
+		background-color: $uni-color-error;
146
+
147
+	}
148
+
149
+	.uni-calendar-item--disable {
150
+		background-color: rgba(249, 249, 249, $uni-opacity-disabled);
151
+		color: $uni-text-color-disable;
152
+	}
153
+
154
+	.uni-calendar-item--isDay-text {
155
+		color: $uni-primary;
156
+	}
157
+
158
+	.uni-calendar-item--isDay {
159
+		background-color: $uni-primary;
160
+		opacity: 0.8;
161
+		color: #fff;
162
+	}
163
+
164
+	.uni-calendar-item--extra {
165
+		color: $uni-color-error;
166
+		opacity: 0.8;
167
+	}
168
+
169
+	.uni-calendar-item--checked {
170
+		background-color: $uni-primary;
171
+		color: #fff;
172
+		opacity: 0.8;
173
+	}
174
+
175
+	.uni-calendar-item--multiple {
176
+		background-color: $uni-primary;
177
+		color: #fff;
178
+		opacity: 0.8;
179
+	}
180
+	.uni-calendar-item--before-checked {
181
+		background-color: #ff5a5f;
182
+		color: #fff;
183
+	}
184
+	.uni-calendar-item--after-checked {
185
+		background-color: #ff5a5f;
186
+		color: #fff;
187
+	}
188
+</style>

+ 562
- 0
oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue Voir le fichier

@@ -0,0 +1,562 @@
1
+<template>
2
+	<view class="uni-calendar">
3
+		<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
4
+		<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
5
+			<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
6
+				<view class="uni-calendar__header-btn-box" @click="close">
7
+					<text class="uni-calendar__header-text uni-calendar--fixed-width">{{cancelText}}</text>
8
+				</view>
9
+				<view class="uni-calendar__header-btn-box" @click="confirm">
10
+					<text class="uni-calendar__header-text uni-calendar--fixed-width">{{okText}}</text>
11
+				</view>
12
+			</view>
13
+			<view class="uni-calendar__header">
14
+				<view class="uni-calendar__header-btn-box" @click.stop="pre">
15
+					<view class="uni-calendar__header-btn uni-calendar--left"></view>
16
+				</view>
17
+				<picker mode="date" :value="date" fields="month" @change="bindDateChange">
18
+					<text class="uni-calendar__header-text">{{ (nowDate.year||'') +' / '+( nowDate.month||'')}}</text>
19
+				</picker>
20
+				<view class="uni-calendar__header-btn-box" @click.stop="next">
21
+					<view class="uni-calendar__header-btn uni-calendar--right"></view>
22
+				</view>
23
+				<text class="uni-calendar__backtoday" @click="backtoday">{{todayText}}</text>
24
+
25
+			</view>
26
+			<view class="uni-calendar__box">
27
+				<view v-if="showMonth" class="uni-calendar__box-bg">
28
+					<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
29
+				</view>
30
+				<view class="uni-calendar__weeks">
31
+					<view class="uni-calendar__weeks-day">
32
+						<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
33
+					</view>
34
+					<view class="uni-calendar__weeks-day">
35
+						<text class="uni-calendar__weeks-day-text">{{monText}}</text>
36
+					</view>
37
+					<view class="uni-calendar__weeks-day">
38
+						<text class="uni-calendar__weeks-day-text">{{TUEText}}</text>
39
+					</view>
40
+					<view class="uni-calendar__weeks-day">
41
+						<text class="uni-calendar__weeks-day-text">{{WEDText}}</text>
42
+					</view>
43
+					<view class="uni-calendar__weeks-day">
44
+						<text class="uni-calendar__weeks-day-text">{{THUText}}</text>
45
+					</view>
46
+					<view class="uni-calendar__weeks-day">
47
+						<text class="uni-calendar__weeks-day-text">{{FRIText}}</text>
48
+					</view>
49
+					<view class="uni-calendar__weeks-day">
50
+						<text class="uni-calendar__weeks-day-text">{{SATText}}</text>
51
+					</view>
52
+				</view>
53
+				<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
54
+					<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
55
+						<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></calendar-item>
56
+					</view>
57
+				</view>
58
+			</view>
59
+		</view>
60
+	</view>
61
+</template>
62
+
63
+<script>
64
+	import Calendar from './util.js';
65
+	import calendarItem from './uni-calendar-item.vue'
66
+	import {
67
+	initVueI18n
68
+	} from '@dcloudio/uni-i18n'
69
+	import messages from './i18n/index.js'
70
+	const {	t	} = initVueI18n(messages)
71
+	/**
72
+	 * Calendar 日历
73
+	 * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
74
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=56
75
+	 * @property {String} date 自定义当前时间,默认为今天
76
+	 * @property {Boolean} lunar 显示农历
77
+	 * @property {String} startDate 日期选择范围-开始日期
78
+	 * @property {String} endDate 日期选择范围-结束日期
79
+	 * @property {Boolean} range 范围选择
80
+	 * @property {Boolean} insert = [true|false] 插入模式,默认为false
81
+	 * 	@value true 弹窗模式
82
+	 * 	@value false 插入模式
83
+	 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
84
+	 * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
85
+	 * @property {Boolean} showMonth 是否选择月份为背景
86
+	 * @event {Function} change 日期改变,`insert :ture` 时生效
87
+	 * @event {Function} confirm 确认选择`insert :false` 时生效
88
+	 * @event {Function} monthSwitch 切换月份时触发
89
+	 * @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
90
+	 */
91
+	export default {
92
+		components: {
93
+			calendarItem
94
+		},
95
+		emits:['close','confirm','change','monthSwitch'],
96
+		props: {
97
+			date: {
98
+				type: String,
99
+				default: ''
100
+			},
101
+			selected: {
102
+				type: Array,
103
+				default () {
104
+					return []
105
+				}
106
+			},
107
+			lunar: {
108
+				type: Boolean,
109
+				default: false
110
+			},
111
+			startDate: {
112
+				type: String,
113
+				default: ''
114
+			},
115
+			endDate: {
116
+				type: String,
117
+				default: ''
118
+			},
119
+			range: {
120
+				type: Boolean,
121
+				default: false
122
+			},
123
+			insert: {
124
+				type: Boolean,
125
+				default: true
126
+			},
127
+			showMonth: {
128
+				type: Boolean,
129
+				default: true
130
+			},
131
+			clearDate: {
132
+				type: Boolean,
133
+				default: true
134
+			}
135
+		},
136
+		data() {
137
+			return {
138
+				show: false,
139
+				weeks: [],
140
+				calendar: {},
141
+				nowDate: '',
142
+				aniMaskShow: false
143
+			}
144
+		},
145
+		computed:{
146
+			/**
147
+			 * for i18n
148
+			 */
149
+
150
+			okText() {
151
+				return t("uni-calender.ok")
152
+			},
153
+			cancelText() {
154
+				return t("uni-calender.cancel")
155
+			},
156
+			todayText() {
157
+				return t("uni-calender.today")
158
+			},
159
+			monText() {
160
+				return t("uni-calender.MON")
161
+			},
162
+			TUEText() {
163
+				return t("uni-calender.TUE")
164
+			},
165
+			WEDText() {
166
+				return t("uni-calender.WED")
167
+			},
168
+			THUText() {
169
+				return t("uni-calender.THU")
170
+			},
171
+			FRIText() {
172
+				return t("uni-calender.FRI")
173
+			},
174
+			SATText() {
175
+				return t("uni-calender.SAT")
176
+			},
177
+			SUNText() {
178
+				return t("uni-calender.SUN")
179
+			},
180
+		},
181
+		watch: {
182
+			date(newVal) {
183
+				// this.cale.setDate(newVal)
184
+				this.init(newVal)
185
+			},
186
+			startDate(val){
187
+				this.cale.resetSatrtDate(val)
188
+				this.cale.setDate(this.nowDate.fullDate)
189
+				this.weeks = this.cale.weeks
190
+			},
191
+			endDate(val){
192
+				this.cale.resetEndDate(val)
193
+				this.cale.setDate(this.nowDate.fullDate)
194
+				this.weeks = this.cale.weeks
195
+			},
196
+			selected(newVal) {
197
+				this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
198
+				this.weeks = this.cale.weeks
199
+			}
200
+		},
201
+		created() {
202
+			// 获取日历方法实例
203
+			this.cale = new Calendar({
204
+				// date: new Date(),
205
+				selected: this.selected,
206
+				startDate: this.startDate,
207
+				endDate: this.endDate,
208
+				range: this.range,
209
+			})
210
+			// 选中某一天
211
+			// this.cale.setDate(this.date)
212
+			this.init(this.date)
213
+			// this.setDay
214
+		},
215
+		methods: {
216
+			// 取消穿透
217
+			clean() {},
218
+			bindDateChange(e) {
219
+				const value = e.detail.value + '-1'
220
+				console.log(this.cale.getDate(value));
221
+				this.setDate(value)
222
+			},
223
+			/**
224
+			 * 初始化日期显示
225
+			 * @param {Object} date
226
+			 */
227
+			init(date) {
228
+				this.cale.setDate(date)
229
+				this.weeks = this.cale.weeks
230
+				this.nowDate = this.calendar = this.cale.getInfo(date)
231
+			},
232
+			/**
233
+			 * 打开日历弹窗
234
+			 */
235
+			open() {
236
+				// 弹窗模式并且清理数据
237
+				if (this.clearDate && !this.insert) {
238
+					this.cale.cleanMultipleStatus()
239
+					// this.cale.setDate(this.date)
240
+					this.init(this.date)
241
+				}
242
+				this.show = true
243
+				this.$nextTick(() => {
244
+					setTimeout(() => {
245
+						this.aniMaskShow = true
246
+					}, 50)
247
+				})
248
+			},
249
+			/**
250
+			 * 关闭日历弹窗
251
+			 */
252
+			close() {
253
+				this.aniMaskShow = false
254
+				this.$nextTick(() => {
255
+					setTimeout(() => {
256
+						this.show = false
257
+						this.$emit('close')
258
+					}, 300)
259
+				})
260
+			},
261
+			/**
262
+			 * 确认按钮
263
+			 */
264
+			confirm() {
265
+				this.setEmit('confirm')
266
+				this.close()
267
+			},
268
+			/**
269
+			 * 变化触发
270
+			 */
271
+			change() {
272
+				if (!this.insert) return
273
+				this.setEmit('change')
274
+			},
275
+			/**
276
+			 * 选择月份触发
277
+			 */
278
+			monthSwitch() {
279
+				let {
280
+					year,
281
+					month
282
+				} = this.nowDate
283
+				this.$emit('monthSwitch', {
284
+					year,
285
+					month: Number(month)
286
+				})
287
+			},
288
+			/**
289
+			 * 派发事件
290
+			 * @param {Object} name
291
+			 */
292
+			setEmit(name) {
293
+				let {
294
+					year,
295
+					month,
296
+					date,
297
+					fullDate,
298
+					lunar,
299
+					extraInfo
300
+				} = this.calendar
301
+				this.$emit(name, {
302
+					range: this.cale.multipleStatus,
303
+					year,
304
+					month,
305
+					date,
306
+					fulldate: fullDate,
307
+					lunar,
308
+					extraInfo: extraInfo || {}
309
+				})
310
+			},
311
+			/**
312
+			 * 选择天触发
313
+			 * @param {Object} weeks
314
+			 */
315
+			choiceDate(weeks) {
316
+				if (weeks.disable) return
317
+				this.calendar = weeks
318
+				// 设置多选
319
+				this.cale.setMultiple(this.calendar.fullDate)
320
+				this.weeks = this.cale.weeks
321
+				this.change()
322
+			},
323
+			/**
324
+			 * 回到今天
325
+			 */
326
+			backtoday() {
327
+				console.log(this.cale.getDate(new Date()).fullDate);
328
+				let date = this.cale.getDate(new Date()).fullDate
329
+				// this.cale.setDate(date)
330
+				this.init(date)
331
+				this.change()
332
+			},
333
+			/**
334
+			 * 上个月
335
+			 */
336
+			pre() {
337
+				const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
338
+				this.setDate(preDate)
339
+				this.monthSwitch()
340
+
341
+			},
342
+			/**
343
+			 * 下个月
344
+			 */
345
+			next() {
346
+				const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
347
+				this.setDate(nextDate)
348
+				this.monthSwitch()
349
+			},
350
+			/**
351
+			 * 设置日期
352
+			 * @param {Object} date
353
+			 */
354
+			setDate(date) {
355
+				this.cale.setDate(date)
356
+				this.weeks = this.cale.weeks
357
+				this.nowDate = this.cale.getInfo(date)
358
+			}
359
+		}
360
+	}
361
+</script>
362
+
363
+<style lang="scss" scoped>
364
+	$uni-bg-color-mask: rgba($color: #000000, $alpha: 0.4);
365
+	$uni-border-color: #EDEDED;
366
+	$uni-text-color: #333;
367
+	$uni-bg-color-hover:#f1f1f1;
368
+	$uni-font-size-base:14px;
369
+	$uni-text-color-placeholder: #808080;
370
+	$uni-color-subtitle: #555555;
371
+	$uni-text-color-grey:#999;
372
+	.uni-calendar {
373
+		/* #ifndef APP-NVUE */
374
+		display: flex;
375
+		/* #endif */
376
+		flex-direction: column;
377
+	}
378
+
379
+	.uni-calendar__mask {
380
+		position: fixed;
381
+		bottom: 0;
382
+		top: 0;
383
+		left: 0;
384
+		right: 0;
385
+		background-color: $uni-bg-color-mask;
386
+		transition-property: opacity;
387
+		transition-duration: 0.3s;
388
+		opacity: 0;
389
+		/* #ifndef APP-NVUE */
390
+		z-index: 99;
391
+		/* #endif */
392
+	}
393
+
394
+	.uni-calendar--mask-show {
395
+		opacity: 1
396
+	}
397
+
398
+	.uni-calendar--fixed {
399
+		position: fixed;
400
+		/* #ifdef APP-NVUE */
401
+		bottom: 0;
402
+		/* #endif */
403
+		left: 0;
404
+		right: 0;
405
+		transition-property: transform;
406
+		transition-duration: 0.3s;
407
+		transform: translateY(460px);
408
+		/* #ifndef APP-NVUE */
409
+		bottom: calc(var(--window-bottom));
410
+		z-index: 99;
411
+		/* #endif */
412
+	}
413
+
414
+	.uni-calendar--ani-show {
415
+		transform: translateY(0);
416
+	}
417
+
418
+	.uni-calendar__content {
419
+		background-color: #fff;
420
+	}
421
+
422
+	.uni-calendar__header {
423
+		position: relative;
424
+		/* #ifndef APP-NVUE */
425
+		display: flex;
426
+		/* #endif */
427
+		flex-direction: row;
428
+		justify-content: center;
429
+		align-items: center;
430
+		height: 50px;
431
+		border-bottom-color: $uni-border-color;
432
+		border-bottom-style: solid;
433
+		border-bottom-width: 1px;
434
+	}
435
+
436
+	.uni-calendar--fixed-top {
437
+		/* #ifndef APP-NVUE */
438
+		display: flex;
439
+		/* #endif */
440
+		flex-direction: row;
441
+		justify-content: space-between;
442
+		border-top-color: $uni-border-color;
443
+		border-top-style: solid;
444
+		border-top-width: 1px;
445
+	}
446
+
447
+	.uni-calendar--fixed-width {
448
+		width: 50px;
449
+		// padding: 0 15px;
450
+	}
451
+
452
+	.uni-calendar__backtoday {
453
+		position: absolute;
454
+		right: 0;
455
+		top: 25rpx;
456
+		padding: 0 5px;
457
+		padding-left: 10px;
458
+		height: 25px;
459
+		line-height: 25px;
460
+		font-size: 12px;
461
+		border-top-left-radius: 25px;
462
+		border-bottom-left-radius: 25px;
463
+		color: $uni-text-color;
464
+		background-color: $uni-bg-color-hover;
465
+	}
466
+
467
+	.uni-calendar__header-text {
468
+		text-align: center;
469
+		width: 100px;
470
+		font-size: $uni-font-size-base;
471
+		color: $uni-text-color;
472
+	}
473
+
474
+	.uni-calendar__header-btn-box {
475
+		/* #ifndef APP-NVUE */
476
+		display: flex;
477
+		/* #endif */
478
+		flex-direction: row;
479
+		align-items: center;
480
+		justify-content: center;
481
+		width: 50px;
482
+		height: 50px;
483
+	}
484
+
485
+	.uni-calendar__header-btn {
486
+		width: 10px;
487
+		height: 10px;
488
+		border-left-color: $uni-text-color-placeholder;
489
+		border-left-style: solid;
490
+		border-left-width: 2px;
491
+		border-top-color: $uni-color-subtitle;
492
+		border-top-style: solid;
493
+		border-top-width: 2px;
494
+	}
495
+
496
+	.uni-calendar--left {
497
+		transform: rotate(-45deg);
498
+	}
499
+
500
+	.uni-calendar--right {
501
+		transform: rotate(135deg);
502
+	}
503
+
504
+
505
+	.uni-calendar__weeks {
506
+		position: relative;
507
+		/* #ifndef APP-NVUE */
508
+		display: flex;
509
+		/* #endif */
510
+		flex-direction: row;
511
+	}
512
+
513
+	.uni-calendar__weeks-item {
514
+		flex: 1;
515
+	}
516
+
517
+	.uni-calendar__weeks-day {
518
+		flex: 1;
519
+		/* #ifndef APP-NVUE */
520
+		display: flex;
521
+		/* #endif */
522
+		flex-direction: column;
523
+		justify-content: center;
524
+		align-items: center;
525
+		height: 45px;
526
+		border-bottom-color: #F5F5F5;
527
+		border-bottom-style: solid;
528
+		border-bottom-width: 1px;
529
+	}
530
+
531
+	.uni-calendar__weeks-day-text {
532
+		font-size: 14px;
533
+	}
534
+
535
+	.uni-calendar__box {
536
+		position: relative;
537
+	}
538
+
539
+	.uni-calendar__box-bg {
540
+		/* #ifndef APP-NVUE */
541
+		display: flex;
542
+		/* #endif */
543
+		justify-content: center;
544
+		align-items: center;
545
+		position: absolute;
546
+		top: 0;
547
+		left: 0;
548
+		right: 0;
549
+		bottom: 0;
550
+	}
551
+
552
+	.uni-calendar__box-bg-text {
553
+		font-size: 200px;
554
+		font-weight: bold;
555
+		color: $uni-text-color-grey;
556
+		opacity: 0.1;
557
+		text-align: center;
558
+		/* #ifndef APP-NVUE */
559
+		line-height: 1;
560
+		/* #endif */
561
+	}
562
+</style>

+ 350
- 0
oa-ui-app/uni_modules/uni-calendar/components/uni-calendar/util.js Voir le fichier

@@ -0,0 +1,350 @@
1
+import CALENDAR from './calendar.js'
2
+
3
+class Calendar {
4
+	constructor({
5
+		date,
6
+		selected,
7
+		startDate,
8
+		endDate,
9
+		range
10
+	} = {}) {
11
+		// 当前日期
12
+		this.date = this.getDate(new Date()) // 当前初入日期
13
+		// 打点信息
14
+		this.selected = selected || [];
15
+		// 范围开始
16
+		this.startDate = startDate
17
+		// 范围结束
18
+		this.endDate = endDate
19
+		this.range = range
20
+		// 多选状态
21
+		this.cleanMultipleStatus()
22
+		// 每周日期
23
+		this.weeks = {}
24
+		// this._getWeek(this.date.fullDate)
25
+	}
26
+	/**
27
+	 * 设置日期
28
+	 * @param {Object} date
29
+	 */
30
+	setDate(date) {
31
+		this.selectDate = this.getDate(date)
32
+		this._getWeek(this.selectDate.fullDate)
33
+	}
34
+
35
+	/**
36
+	 * 清理多选状态
37
+	 */
38
+	cleanMultipleStatus() {
39
+		this.multipleStatus = {
40
+			before: '',
41
+			after: '',
42
+			data: []
43
+		}
44
+	}
45
+
46
+	/**
47
+	 * 重置开始日期
48
+	 */
49
+	resetSatrtDate(startDate) {
50
+		// 范围开始
51
+		this.startDate = startDate
52
+
53
+	}
54
+
55
+	/**
56
+	 * 重置结束日期
57
+	 */
58
+	resetEndDate(endDate) {
59
+		// 范围结束
60
+		this.endDate = endDate
61
+	}
62
+
63
+	/**
64
+	 * 获取任意时间
65
+	 */
66
+	getDate(date, AddDayCount = 0, str = 'day') {
67
+		if (!date) {
68
+			date = new Date()
69
+		}
70
+		if (typeof date !== 'object') {
71
+			date = date.replace(/-/g, '/')
72
+		}
73
+		const dd = new Date(date)
74
+		switch (str) {
75
+			case 'day':
76
+				dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
77
+				break
78
+			case 'month':
79
+				if (dd.getDate() === 31) {
80
+					dd.setDate(dd.getDate() + AddDayCount)
81
+				} else {
82
+					dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
83
+				}
84
+				break
85
+			case 'year':
86
+				dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
87
+				break
88
+		}
89
+		const y = dd.getFullYear()
90
+		const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
91
+		const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
92
+		return {
93
+			fullDate: y + '-' + m + '-' + d,
94
+			year: y,
95
+			month: m,
96
+			date: d,
97
+			day: dd.getDay()
98
+		}
99
+	}
100
+
101
+
102
+	/**
103
+	 * 获取上月剩余天数
104
+	 */
105
+	_getLastMonthDays(firstDay, full) {
106
+		let dateArr = []
107
+		for (let i = firstDay; i > 0; i--) {
108
+			const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
109
+			dateArr.push({
110
+				date: beforeDate,
111
+				month: full.month - 1,
112
+				lunar: this.getlunar(full.year, full.month - 1, beforeDate),
113
+				disable: true
114
+			})
115
+		}
116
+		return dateArr
117
+	}
118
+	/**
119
+	 * 获取本月天数
120
+	 */
121
+	_currentMonthDys(dateData, full) {
122
+		let dateArr = []
123
+		let fullDate = this.date.fullDate
124
+		for (let i = 1; i <= dateData; i++) {
125
+			let nowDate = full.year + '-' + (full.month < 10 ?
126
+				full.month : full.month) + '-' + (i < 10 ?
127
+				'0' + i : i)
128
+			// 是否今天
129
+			let isDay = fullDate === nowDate
130
+			// 获取打点信息
131
+			let info = this.selected && this.selected.find((item) => {
132
+				if (this.dateEqual(nowDate, item.date)) {
133
+					return item
134
+				}
135
+			})
136
+
137
+			// 日期禁用
138
+			let disableBefore = true
139
+			let disableAfter = true
140
+			if (this.startDate) {
141
+				// let dateCompBefore = this.dateCompare(this.startDate, fullDate)
142
+				// disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
143
+				disableBefore = this.dateCompare(this.startDate, nowDate)
144
+			}
145
+
146
+			if (this.endDate) {
147
+				// let dateCompAfter = this.dateCompare(fullDate, this.endDate)
148
+				// disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
149
+				disableAfter = this.dateCompare(nowDate, this.endDate)
150
+			}
151
+			let multiples = this.multipleStatus.data
152
+			let checked = false
153
+			let multiplesStatus = -1
154
+			if (this.range) {
155
+				if (multiples) {
156
+					multiplesStatus = multiples.findIndex((item) => {
157
+						return this.dateEqual(item, nowDate)
158
+					})
159
+				}
160
+				if (multiplesStatus !== -1) {
161
+					checked = true
162
+				}
163
+			}
164
+			let data = {
165
+				fullDate: nowDate,
166
+				year: full.year,
167
+				date: i,
168
+				multiple: this.range ? checked : false,
169
+				beforeMultiple: this.dateEqual(this.multipleStatus.before, nowDate),
170
+				afterMultiple: this.dateEqual(this.multipleStatus.after, nowDate),
171
+				month: full.month,
172
+				lunar: this.getlunar(full.year, full.month, i),
173
+				disable: !(disableBefore && disableAfter),
174
+				isDay
175
+			}
176
+			if (info) {
177
+				data.extraInfo = info
178
+			}
179
+
180
+			dateArr.push(data)
181
+		}
182
+		return dateArr
183
+	}
184
+	/**
185
+	 * 获取下月天数
186
+	 */
187
+	_getNextMonthDays(surplus, full) {
188
+		let dateArr = []
189
+		for (let i = 1; i < surplus + 1; i++) {
190
+			dateArr.push({
191
+				date: i,
192
+				month: Number(full.month) + 1,
193
+				lunar: this.getlunar(full.year, Number(full.month) + 1, i),
194
+				disable: true
195
+			})
196
+		}
197
+		return dateArr
198
+	}
199
+
200
+	/**
201
+	 * 获取当前日期详情
202
+	 * @param {Object} date
203
+	 */
204
+	getInfo(date) {
205
+		if (!date) {
206
+			date = new Date()
207
+		}
208
+		const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
209
+		return dateInfo
210
+	}
211
+
212
+	/**
213
+	 * 比较时间大小
214
+	 */
215
+	dateCompare(startDate, endDate) {
216
+		// 计算截止时间
217
+		startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
218
+		// 计算详细项的截止时间
219
+		endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
220
+		if (startDate <= endDate) {
221
+			return true
222
+		} else {
223
+			return false
224
+		}
225
+	}
226
+
227
+	/**
228
+	 * 比较时间是否相等
229
+	 */
230
+	dateEqual(before, after) {
231
+		// 计算截止时间
232
+		before = new Date(before.replace('-', '/').replace('-', '/'))
233
+		// 计算详细项的截止时间
234
+		after = new Date(after.replace('-', '/').replace('-', '/'))
235
+		if (before.getTime() - after.getTime() === 0) {
236
+			return true
237
+		} else {
238
+			return false
239
+		}
240
+	}
241
+
242
+
243
+	/**
244
+	 * 获取日期范围内所有日期
245
+	 * @param {Object} begin
246
+	 * @param {Object} end
247
+	 */
248
+	geDateAll(begin, end) {
249
+		var arr = []
250
+		var ab = begin.split('-')
251
+		var ae = end.split('-')
252
+		var db = new Date()
253
+		db.setFullYear(ab[0], ab[1] - 1, ab[2])
254
+		var de = new Date()
255
+		de.setFullYear(ae[0], ae[1] - 1, ae[2])
256
+		var unixDb = db.getTime() - 24 * 60 * 60 * 1000
257
+		var unixDe = de.getTime() - 24 * 60 * 60 * 1000
258
+		for (var k = unixDb; k <= unixDe;) {
259
+			k = k + 24 * 60 * 60 * 1000
260
+			arr.push(this.getDate(new Date(parseInt(k))).fullDate)
261
+		}
262
+		return arr
263
+	}
264
+	/**
265
+	 * 计算阴历日期显示
266
+	 */
267
+	getlunar(year, month, date) {
268
+		return CALENDAR.solar2lunar(year, month, date)
269
+	}
270
+	/**
271
+	 * 设置打点
272
+	 */
273
+	setSelectInfo(data, value) {
274
+		this.selected = value
275
+		this._getWeek(data)
276
+	}
277
+
278
+	/**
279
+	 *  获取多选状态
280
+	 */
281
+	setMultiple(fullDate) {
282
+		let {
283
+			before,
284
+			after
285
+		} = this.multipleStatus
286
+
287
+		if (!this.range) return
288
+		if (before && after) {
289
+			this.multipleStatus.before = ''
290
+			this.multipleStatus.after = ''
291
+			this.multipleStatus.data = []
292
+		} else {
293
+			if (!before) {
294
+				this.multipleStatus.before = fullDate
295
+			} else {
296
+				this.multipleStatus.after = fullDate
297
+				if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
298
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
299
+				} else {
300
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
301
+				}
302
+			}
303
+		}
304
+		this._getWeek(fullDate)
305
+	}
306
+
307
+	/**
308
+	 * 获取每周数据
309
+	 * @param {Object} dateData
310
+	 */
311
+	_getWeek(dateData) {
312
+		const {
313
+			year,
314
+			month
315
+		} = this.getDate(dateData)
316
+		let firstDay = new Date(year, month - 1, 1).getDay()
317
+		let currentDay = new Date(year, month, 0).getDate()
318
+		let dates = {
319
+			lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
320
+			currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
321
+			nextMonthDays: [], // 下个月开始几天
322
+			weeks: []
323
+		}
324
+		let canlender = []
325
+		const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
326
+		dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
327
+		canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
328
+		let weeks = {}
329
+		// 拼接数组  上个月开始几天 + 本月天数+ 下个月开始几天
330
+		for (let i = 0; i < canlender.length; i++) {
331
+			if (i % 7 === 0) {
332
+				weeks[parseInt(i / 7)] = new Array(7)
333
+			}
334
+			weeks[parseInt(i / 7)][i % 7] = canlender[i]
335
+		}
336
+		this.canlender = canlender
337
+		this.weeks = weeks
338
+	}
339
+
340
+	//静态方法
341
+	// static init(date) {
342
+	// 	if (!this.instance) {
343
+	// 		this.instance = new Calendar(date);
344
+	// 	}
345
+	// 	return this.instance;
346
+	// }
347
+}
348
+
349
+
350
+export default Calendar

+ 85
- 0
oa-ui-app/uni_modules/uni-calendar/package.json Voir le fichier

@@ -0,0 +1,85 @@
1
+{
2
+  "id": "uni-calendar",
3
+  "displayName": "uni-calendar 日历",
4
+  "version": "1.4.7",
5
+  "description": "日历组件",
6
+  "keywords": [
7
+    "uni-ui",
8
+    "uniui",
9
+    "日历",
10
+    "",
11
+    "打卡",
12
+    "日历选择"
13
+],
14
+  "repository": "https://github.com/dcloudio/uni-ui",
15
+  "engines": {
16
+    "HBuilderX": ""
17
+  },
18
+  "directories": {
19
+    "example": "../../temps/example_temps"
20
+  },
21
+"dcloudext": {
22
+    "sale": {
23
+      "regular": {
24
+        "price": "0.00"
25
+      },
26
+      "sourcecode": {
27
+        "price": "0.00"
28
+      }
29
+    },
30
+    "contact": {
31
+      "qq": ""
32
+    },
33
+    "declaration": {
34
+      "ads": "无",
35
+      "data": "无",
36
+      "permissions": "无"
37
+    },
38
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
39
+    "type": "component-vue"
40
+  },
41
+  "uni_modules": {
42
+    "dependencies": [],
43
+    "encrypt": [],
44
+    "platforms": {
45
+      "cloud": {
46
+        "tcb": "y",
47
+        "aliyun": "y"
48
+      },
49
+      "client": {
50
+        "App": {
51
+          "app-vue": "y",
52
+          "app-nvue": "y"
53
+        },
54
+        "H5-mobile": {
55
+          "Safari": "y",
56
+          "Android Browser": "y",
57
+          "微信浏览器(Android)": "y",
58
+          "QQ浏览器(Android)": "y"
59
+        },
60
+        "H5-pc": {
61
+          "Chrome": "y",
62
+          "IE": "y",
63
+          "Edge": "y",
64
+          "Firefox": "y",
65
+          "Safari": "y"
66
+        },
67
+        "小程序": {
68
+          "微信": "y",
69
+          "阿里": "y",
70
+          "百度": "y",
71
+          "字节跳动": "y",
72
+          "QQ": "y"
73
+        },
74
+        "快应用": {
75
+          "华为": "u",
76
+          "联盟": "u"
77
+        },
78
+        "Vue": {
79
+            "vue2": "y",
80
+            "vue3": "y"
81
+        }
82
+      }
83
+    }
84
+  }
85
+}

+ 103
- 0
oa-ui-app/uni_modules/uni-calendar/readme.md Voir le fichier

@@ -0,0 +1,103 @@
1
+
2
+
3
+## Calendar 日历
4
+> **组件名:uni-calendar**
5
+> 代码块: `uCalendar`
6
+
7
+
8
+日历组件
9
+
10
+> **注意事项**
11
+> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
12
+> - 本组件农历转换使用的js是 [@1900-2100区间内的公历、农历互转](https://github.com/jjonline/calendar.js)  
13
+> - 仅支持自定义组件模式
14
+> - `date`属性传入的应该是一个 String ,如: 2019-06-27 ,而不是 new Date()
15
+> - 通过 `insert` 属性来确定当前的事件是 @change 还是 @confirm 。理应合并为一个事件,但是为了区分模式,现使用两个事件,这里需要注意
16
+> - 弹窗模式下无法阻止后面的元素滚动,如有需要阻止,请在弹窗弹出后,手动设置滚动元素为不可滚动
17
+
18
+
19
+### 安装方式
20
+
21
+本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
22
+
23
+如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
24
+
25
+### 基本用法
26
+
27
+在 ``template`` 中使用组件
28
+
29
+```html
30
+<view>
31
+	<uni-calendar 
32
+	:insert="true"
33
+	:lunar="true" 
34
+	:start-date="'2019-3-2'"
35
+	:end-date="'2019-5-20'"
36
+	@change="change"
37
+	 />
38
+</view>
39
+```
40
+
41
+### 通过方法打开日历
42
+
43
+需要设置 `insert` 为 `false`
44
+
45
+```html
46
+<view>
47
+	<uni-calendar 
48
+	ref="calendar"
49
+	:insert="false"
50
+	@confirm="confirm"
51
+	 />
52
+	 <button @click="open">打开日历</button>
53
+</view>
54
+```
55
+
56
+```javascript
57
+
58
+export default {
59
+	data() {
60
+		return {};
61
+	},
62
+	methods: {
63
+		open(){
64
+			this.$refs.calendar.open();
65
+		},
66
+		confirm(e) {
67
+			console.log(e);
68
+		}
69
+	}
70
+};
71
+
72
+```
73
+
74
+
75
+## API
76
+
77
+### Calendar Props
78
+
79
+|  属性名	|    类型	| 默认值| 说明																													|
80
+| 		| 																													|
81
+| date		| String	|-		| 自定义当前时间,默认为今天																							|
82
+| lunar		| Boolean	| false	| 显示农历																												|
83
+| startDate	| String	|-		| 日期选择范围-开始日期																									|
84
+| endDate	| String	|-		| 日期选择范围-结束日期																									|
85
+| range		| Boolean	| false	| 范围选择																												|
86
+| insert	| Boolean	| false	| 插入模式,可选值,ture:插入模式;false:弹窗模式;默认为插入模式														|
87
+|clearDate	|Boolean	|true	|弹窗模式是否清空上次选择内容	|
88
+| selected	| Array		|-		| 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]	|
89
+|showMonth	| Boolean	| true	| 是否显示月份为背景																									|
90
+
91
+### Calendar Events
92
+
93
+|  事件名		| 说明								|返回值|
94
+| 								|		| 									|
95
+| open	| 弹出日历组件,`insert :false` 时生效|- 	|
96
+
97
+
98
+
99
+
100
+
101
+## 组件示例
102
+
103
+点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar](https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar)

+ 26
- 0
oa-ui-app/uni_modules/uni-card/changelog.md Voir le fichier

@@ -0,0 +1,26 @@
1
+## 1.3.1(2021-12-20)
2
+- 修复 在vue页面下略缩图显示不正常的bug
3
+## 1.3.0(2021-11-19)
4
+- 重构插槽的用法 ,header 替换为 title 
5
+- 新增 actions 插槽
6
+- 新增 cover 封面图属性和插槽
7
+- 新增 padding 内容默认内边距离
8
+- 新增 margin 卡片默认外边距离
9
+- 新增 spacing 卡片默认内边距
10
+- 新增 shadow 卡片阴影属性
11
+- 取消 mode 属性,可使用组合插槽代替
12
+- 取消 note 属性 ,使用actions插槽代替
13
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
14
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-card](https://uniapp.dcloud.io/component/uniui/uni-card)
15
+## 1.2.1(2021-07-30)
16
+- 优化 vue3下事件警告的问题
17
+## 1.2.0(2021-07-13)
18
+- 组件兼容 vue3,如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
19
+## 1.1.8(2021-07-01)
20
+- 优化 图文卡片无图片加载时,提供占位图标
21
+- 新增 header 插槽,自定义卡片头部( 图文卡片 mode="style" 时,不支持)
22
+- 修复 thumbnail 不存在仍然占位的 bug
23
+## 1.1.7(2021-05-12)
24
+- 新增 组件示例地址
25
+## 1.1.6(2021-02-04)
26
+- 调整为uni_modules目录规范

+ 270
- 0
oa-ui-app/uni_modules/uni-card/components/uni-card/uni-card.vue Voir le fichier

@@ -0,0 +1,270 @@
1
+<template>
2
+	<view class="uni-card" :class="{ 'uni-card--full': isFull, 'uni-card--shadow': isShadow,'uni-card--border':border}"
3
+		:style="{'margin':isFull?0:margin,'padding':spacing,'box-shadow':isShadow?shadow:''}">
4
+		<!-- 封面 -->
5
+		<slot name="cover">
6
+			<view v-if="cover" class="uni-card__cover">
7
+				<image class="uni-card__cover-image" mode="widthFix" @click="onClick('cover')" :src="cover"></image>
8
+			</view>
9
+		</slot>
10
+		<slot name="title">
11
+			<view v-if="title || extra" class="uni-card__header">
12
+				<!-- 卡片标题 -->
13
+				<view class="uni-card__header-box" @click="onClick('title')">
14
+					<view v-if="thumbnail" class="uni-card__header-avatar">
15
+						<image class="uni-card__header-avatar-image" :src="thumbnail" mode="aspectFit" />
16
+					</view>
17
+					<view class="uni-card__header-content">
18
+						<text class="uni-card__header-content-title uni-ellipsis">{{ title }}</text>
19
+						<text v-if="title&&subTitle"
20
+							class="uni-card__header-content-subtitle uni-ellipsis">{{ subTitle }}</text>
21
+					</view>
22
+				</view>
23
+				<view class="uni-card__header-extra" @click="onClick('extra')">
24
+					<text class="uni-card__header-extra-text">{{ extra }}</text>
25
+				</view>
26
+			</view>
27
+		</slot>
28
+		<!-- 卡片内容 -->
29
+		<view class="uni-card__content" :style="{padding:padding}" @click="onClick('content')">
30
+			<slot></slot>
31
+		</view>
32
+		<view class="uni-card__actions" @click="onClick('actions')">
33
+			<slot name="actions"></slot>
34
+		</view>
35
+	</view>
36
+</template>
37
+
38
+<script>
39
+	/**
40
+	 * Card 卡片
41
+	 * @description 卡片视图组件
42
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=22
43
+	 * @property {String} title 标题文字
44
+	 * @property {String} subTitle 副标题
45
+	 * @property {Number} padding 内容内边距
46
+	 * @property {Number} margin 卡片外边距
47
+	 * @property {Number} spacing 卡片内边距
48
+	 * @property {String} extra 标题额外信息
49
+	 * @property {String} cover 封面图(本地路径需要引入)
50
+	 * @property {String} thumbnail 标题左侧缩略图
51
+	 * @property {Boolean} is-full = [true | false] 卡片内容是否通栏,为 true 时将去除padding值
52
+	 * @property {Boolean} is-shadow = [true | false] 卡片内容是否开启阴影
53
+	 * @property {String} shadow 卡片阴影
54
+	 * @property {Boolean} border 卡片边框
55
+	 * @event {Function} click 点击 Card 触发事件
56
+	 */
57
+	export default {
58
+		name: 'UniCard',
59
+		emits: ['click'],
60
+		props: {
61
+			title: {
62
+				type: String,
63
+				default: ''
64
+			},
65
+			subTitle: {
66
+				type: String,
67
+				default: ''
68
+			},
69
+			padding: {
70
+				type: String,
71
+				default: '10px'
72
+			},
73
+			margin: {
74
+				type: String,
75
+				default: '15px'
76
+			},
77
+			spacing: {
78
+				type: String,
79
+				default: '0 10px'
80
+			},
81
+			extra: {
82
+				type: String,
83
+				default: ''
84
+			},
85
+			cover: {
86
+				type: String,
87
+				default: ''
88
+			},
89
+			thumbnail: {
90
+				type: String,
91
+				default: ''
92
+			},
93
+			isFull: {
94
+				// 内容区域是否通栏
95
+				type: Boolean,
96
+				default: false
97
+			},
98
+			isShadow: {
99
+				// 是否开启阴影
100
+				type: Boolean,
101
+				default: true
102
+			},
103
+			shadow: {
104
+				type: String,
105
+				default: '0px 0px 3px 1px rgba(0, 0, 0, 0.08)'
106
+			},
107
+			border: {
108
+				type: Boolean,
109
+				default: true
110
+			}
111
+		},
112
+		methods: {
113
+			onClick(type) {
114
+				this.$emit('click', type)
115
+			}
116
+		}
117
+	}
118
+</script>
119
+
120
+<style lang="scss">
121
+	$uni-border-3: #EBEEF5 !default;
122
+	$uni-shadow-base:0 0px 6px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
123
+	$uni-main-color: #3a3a3a !default;
124
+	$uni-base-color: #6a6a6a !default;
125
+	$uni-secondary-color: #909399 !default;
126
+	$uni-spacing-sm: 8px !default;
127
+	$uni-border-color:$uni-border-3;
128
+	$uni-shadow: $uni-shadow-base;
129
+	$uni-card-title: 15px;
130
+	$uni-cart-title-color:$uni-main-color;
131
+	$uni-card-subtitle: 12px;
132
+	$uni-cart-subtitle-color:$uni-secondary-color;
133
+	$uni-card-spacing: 10px;
134
+	$uni-card-content-color: $uni-base-color;
135
+
136
+	.uni-card {
137
+		margin: $uni-card-spacing;
138
+		padding: 0 $uni-spacing-sm;
139
+		border-radius: 4px;
140
+		overflow: hidden;
141
+		font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
142
+		background-color: #fff;
143
+		flex: 1;
144
+
145
+		.uni-card__cover {
146
+			position: relative;
147
+			margin-top: $uni-card-spacing;
148
+			flex-direction: row;
149
+			overflow: hidden;
150
+			border-radius: 4px;
151
+			.uni-card__cover-image {
152
+				flex: 1;
153
+				// width: 100%;
154
+				/* #ifndef APP-PLUS */
155
+				vertical-align: middle;
156
+				/* #endif */
157
+			}
158
+		}
159
+
160
+		.uni-card__header {
161
+			display: flex;
162
+			border-bottom: 1px $uni-border-color solid;
163
+			flex-direction: row;
164
+			align-items: center;
165
+			padding: $uni-card-spacing;
166
+			overflow: hidden;
167
+
168
+			.uni-card__header-box {
169
+				/* #ifndef APP-NVUE */
170
+				display: flex;
171
+				/* #endif */
172
+				flex: 1;
173
+				flex-direction: row;
174
+				align-items: center;
175
+				overflow: hidden;
176
+			}
177
+
178
+			.uni-card__header-avatar {
179
+				width: 40px;
180
+				height: 40px;
181
+				overflow: hidden;
182
+				border-radius: 5px;
183
+				margin-right: $uni-card-spacing;
184
+				.uni-card__header-avatar-image {
185
+					flex: 1;
186
+					width: 40px;
187
+					height: 40px;
188
+				}
189
+			}
190
+
191
+			.uni-card__header-content {
192
+				/* #ifndef APP-NVUE */
193
+				display: flex;
194
+				/* #endif */
195
+				flex-direction: column;
196
+				justify-content: center;
197
+				flex: 1;
198
+				// height: 40px;
199
+				overflow: hidden;
200
+
201
+				.uni-card__header-content-title {
202
+					font-size: $uni-card-title;
203
+					color: $uni-cart-title-color;
204
+					// line-height: 22px;
205
+				}
206
+
207
+				.uni-card__header-content-subtitle {
208
+					font-size: $uni-card-subtitle;
209
+					margin-top: 5px;
210
+					color: $uni-cart-subtitle-color;
211
+				}
212
+			}
213
+
214
+			.uni-card__header-extra {
215
+				line-height: 12px;
216
+
217
+				.uni-card__header-extra-text {
218
+					font-size: 12px;
219
+					color: $uni-cart-subtitle-color;
220
+				}
221
+			}
222
+		}
223
+
224
+		.uni-card__content {
225
+			padding: $uni-card-spacing;
226
+			font-size: 14px;
227
+			color: $uni-card-content-color;
228
+			line-height: 22px;
229
+		}
230
+
231
+		.uni-card__actions {
232
+			font-size: 12px;
233
+		}
234
+	}
235
+
236
+	.uni-card--border {
237
+		border: 1px solid $uni-border-color;
238
+	}
239
+
240
+	.uni-card--shadow {
241
+		position: relative;
242
+		/* #ifndef APP-NVUE */
243
+		box-shadow: $uni-shadow;
244
+		/* #endif */
245
+	}
246
+
247
+	.uni-card--full {
248
+		margin: 0;
249
+		border-left-width: 0;
250
+		border-left-width: 0;
251
+		border-radius: 0;
252
+	}
253
+
254
+	/* #ifndef APP-NVUE */
255
+	.uni-card--full:after {
256
+		border-radius: 0;
257
+	}
258
+
259
+	/* #endif */
260
+	.uni-ellipsis {
261
+		/* #ifndef APP-NVUE */
262
+		overflow: hidden;
263
+		white-space: nowrap;
264
+		text-overflow: ellipsis;
265
+		/* #endif */
266
+		/* #ifdef APP-NVUE */
267
+		lines: 1;
268
+		/* #endif */
269
+	}
270
+</style>

+ 90
- 0
oa-ui-app/uni_modules/uni-card/package.json Voir le fichier

@@ -0,0 +1,90 @@
1
+{
2
+  "id": "uni-card",
3
+  "displayName": "uni-card 卡片",
4
+  "version": "1.3.1",
5
+  "description": "Card 组件,提供常见的卡片样式。",
6
+  "keywords": [
7
+    "uni-ui",
8
+    "uniui",
9
+    "card",
10
+    "",
11
+    "卡片"
12
+],
13
+  "repository": "https://github.com/dcloudio/uni-ui",
14
+  "engines": {
15
+    "HBuilderX": ""
16
+  },
17
+  "directories": {
18
+    "example": "../../temps/example_temps"
19
+  },
20
+  "dcloudext": {
21
+    "category": [
22
+      "前端组件",
23
+      "通用组件"
24
+    ],
25
+    "sale": {
26
+      "regular": {
27
+        "price": "0.00"
28
+      },
29
+      "sourcecode": {
30
+        "price": "0.00"
31
+      }
32
+    },
33
+    "contact": {
34
+      "qq": ""
35
+    },
36
+    "declaration": {
37
+      "ads": "无",
38
+      "data": "无",
39
+      "permissions": "无"
40
+    },
41
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
42
+  },
43
+  "uni_modules": {
44
+    "dependencies": [
45
+			"uni-icons",
46
+			"uni-scss"
47
+		],
48
+    "encrypt": [],
49
+    "platforms": {
50
+      "cloud": {
51
+        "tcb": "y",
52
+        "aliyun": "y"
53
+      },
54
+      "client": {
55
+        "App": {
56
+          "app-vue": "y",
57
+          "app-nvue": "y"
58
+        },
59
+        "H5-mobile": {
60
+          "Safari": "y",
61
+          "Android Browser": "y",
62
+          "微信浏览器(Android)": "y",
63
+          "QQ浏览器(Android)": "y"
64
+        },
65
+        "H5-pc": {
66
+          "Chrome": "y",
67
+          "IE": "y",
68
+          "Edge": "y",
69
+          "Firefox": "y",
70
+          "Safari": "y"
71
+        },
72
+        "小程序": {
73
+          "微信": "y",
74
+          "阿里": "y",
75
+          "百度": "y",
76
+          "字节跳动": "y",
77
+          "QQ": "y"
78
+        },
79
+        "快应用": {
80
+          "华为": "u",
81
+          "联盟": "u"
82
+        },
83
+        "Vue": {
84
+            "vue2": "y",
85
+            "vue3": "y"
86
+        }
87
+      }
88
+    }
89
+  }
90
+}

+ 12
- 0
oa-ui-app/uni_modules/uni-card/readme.md Voir le fichier

@@ -0,0 +1,12 @@
1
+
2
+
3
+## Card 卡片
4
+> **组件名:uni-card**
5
+> 代码块: `uCard`
6
+
7
+卡片视图组件。
8
+
9
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-card)
10
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
11
+
12
+

+ 36
- 0
oa-ui-app/uni_modules/uni-collapse/changelog.md Voir le fichier

@@ -0,0 +1,36 @@
1
+## 1.4.3(2022-01-25)
2
+- 修复 初始化的时候 ,open 属性失效的bug
3
+## 1.4.2(2022-01-21)
4
+- 修复 微信小程序resize后组件收起的bug
5
+## 1.4.1(2021-11-22)
6
+- 修复 vue3中个别scss变量无法找到的问题
7
+## 1.4.0(2021-11-19)
8
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
9
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-collapse](https://uniapp.dcloud.io/component/uniui/uni-collapse)
10
+## 1.3.3(2021-08-17)
11
+- 优化 show-arrow 属性默认为true
12
+## 1.3.2(2021-08-17)
13
+- 新增 show-arrow 属性,控制是否显示右侧箭头
14
+## 1.3.1(2021-07-30)
15
+- 优化 vue3下小程序事件警告的问题
16
+## 1.3.0(2021-07-30)
17
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
18
+## 1.2.2(2021-07-21)
19
+- 修复 由1.2.0版本引起的 change 事件返回 undefined 的Bug
20
+## 1.2.1(2021-07-21)
21
+- 优化 组件示例
22
+## 1.2.0(2021-07-21)
23
+- 新增 组件折叠动画
24
+- 新增 value\v-model 属性 ,动态修改面板折叠状态
25
+- 新增 title 插槽 ,可定义面板标题
26
+- 新增 border 属性 ,显示隐藏面板内容分隔线
27
+- 新增 title-border 属性 ,显示隐藏面板标题分隔线
28
+- 修复 resize 方法失效的Bug
29
+- 修复 change 事件返回参数不正确的Bug
30
+- 优化 H5、App 平台自动更具内容更新高度,无需调用 reszie() 方法
31
+## 1.1.7(2021-05-12)
32
+- 新增 组件示例地址
33
+## 1.1.6(2021-02-05)
34
+- 优化 组件引用关系,通过uni_modules引用组件
35
+## 1.1.5(2021-02-05)
36
+- 调整为uni_modules目录规范

+ 402
- 0
oa-ui-app/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue Voir le fichier

@@ -0,0 +1,402 @@
1
+<template>
2
+	<view class="uni-collapse-item">
3
+		<!-- onClick(!isOpen) -->
4
+		<view @click="onClick(!isOpen)" class="uni-collapse-item__title"
5
+			:class="{'is-open':isOpen &&titleBorder === 'auto' ,'uni-collapse-item-border':titleBorder !== 'none'}">
6
+			<view class="uni-collapse-item__title-wrap">
7
+				<slot name="title">
8
+					<view class="uni-collapse-item__title-box" :class="{'is-disabled':disabled}">
9
+						<image v-if="thumb" :src="thumb" class="uni-collapse-item__title-img" />
10
+						<text class="uni-collapse-item__title-text">{{ title }}</text>
11
+					</view>
12
+				</slot>
13
+			</view>
14
+			<view v-if="showArrow"
15
+				:class="{ 'uni-collapse-item__title-arrow-active': isOpen, 'uni-collapse-item--animation': showAnimation === true }"
16
+				class="uni-collapse-item__title-arrow">
17
+				<uni-icons :color="disabled?'#ddd':'#bbb'" size="14" type="bottom" />
18
+			</view>
19
+		</view>
20
+		<view class="uni-collapse-item__wrap" :class="{'is--transition':showAnimation}"
21
+			:style="{height: (isOpen?height:0) +'px'}">
22
+			<view :id="elId" ref="collapse--hook" class="uni-collapse-item__wrap-content"
23
+				:class="{open:isheight,'uni-collapse-item--border':border&&isOpen}">
24
+				<slot></slot>
25
+			</view>
26
+		</view>
27
+
28
+	</view>
29
+</template>
30
+
31
+<script>
32
+	// #ifdef APP-NVUE
33
+	const dom = weex.requireModule('dom')
34
+	// #endif
35
+	/**
36
+	 * CollapseItem 折叠面板子组件
37
+	 * @description 折叠面板子组件
38
+	 * @property {String} title 标题文字
39
+	 * @property {String} thumb 标题左侧缩略图
40
+	 * @property {String} name 唯一标志符
41
+	 * @property {Boolean} open = [true|false] 是否展开组件
42
+	 * @property {Boolean} titleBorder = [true|false] 是否显示标题分隔线
43
+	 * @property {Boolean} border = [true|false] 是否显示分隔线
44
+	 * @property {Boolean} disabled = [true|false] 是否展开面板
45
+	 * @property {Boolean} showAnimation = [true|false] 开启动画
46
+	 * @property {Boolean} showArrow = [true|false] 是否显示右侧箭头
47
+	 */
48
+	export default {
49
+		name: 'uniCollapseItem',
50
+		props: {
51
+			// 列表标题
52
+			title: {
53
+				type: String,
54
+				default: ''
55
+			},
56
+			name: {
57
+				type: [Number, String],
58
+				default: ''
59
+			},
60
+			// 是否禁用
61
+			disabled: {
62
+				type: Boolean,
63
+				default: false
64
+			},
65
+			// #ifdef APP-PLUS
66
+			// 是否显示动画,app 端默认不开启动画,卡顿严重
67
+			showAnimation: {
68
+				type: Boolean,
69
+				default: false
70
+			},
71
+			// #endif
72
+			// #ifndef APP-PLUS
73
+			// 是否显示动画
74
+			showAnimation: {
75
+				type: Boolean,
76
+				default: true
77
+			},
78
+			// #endif
79
+			// 是否展开
80
+			open: {
81
+				type: Boolean,
82
+				default: false
83
+			},
84
+			// 缩略图
85
+			thumb: {
86
+				type: String,
87
+				default: ''
88
+			},
89
+			// 标题分隔线显示类型
90
+			titleBorder: {
91
+				type: String,
92
+				default: 'auto'
93
+			},
94
+			border: {
95
+				type: Boolean,
96
+				default: true
97
+			},
98
+			showArrow: {
99
+				type: Boolean,
100
+				default: true
101
+			}
102
+		},
103
+		data() {
104
+			// TODO 随机生生元素ID,解决百度小程序获取同一个元素位置信息的bug
105
+			const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
106
+			return {
107
+				isOpen: false,
108
+				isheight: null,
109
+				height: 0,
110
+				elId,
111
+				nameSync: 0
112
+			}
113
+		},
114
+		watch: {
115
+			open(val) {
116
+				this.isOpen = val
117
+				this.onClick(val, 'init')
118
+			}
119
+		},
120
+		updated(e) {
121
+			this.$nextTick(() => {
122
+				this.init(true)
123
+			})
124
+		},
125
+		created() {
126
+			this.collapse = this.getCollapse()
127
+			this.oldHeight = 0
128
+			this.onClick(this.open, 'init')
129
+		},
130
+		// #ifndef VUE3
131
+		// TODO vue2
132
+		destroyed() {
133
+			if (this.__isUnmounted) return
134
+			this.uninstall()
135
+		},
136
+		// #endif
137
+		// #ifdef VUE3
138
+		// TODO vue3
139
+		unmounted() {
140
+			this.__isUnmounted = true
141
+			this.uninstall()
142
+		},
143
+		// #endif
144
+		mounted() {
145
+			if (!this.collapse) return
146
+			if (this.name !== '') {
147
+				this.nameSync = this.name
148
+			} else {
149
+				this.nameSync = this.collapse.childrens.length + ''
150
+			}
151
+			if (this.collapse.names.indexOf(this.nameSync) === -1) {
152
+				this.collapse.names.push(this.nameSync)
153
+			} else {
154
+				console.warn(`name 值 ${this.nameSync} 重复`);
155
+			}
156
+			if (this.collapse.childrens.indexOf(this) === -1) {
157
+				this.collapse.childrens.push(this)
158
+			}
159
+			this.init()
160
+		},
161
+		methods: {
162
+			init(type) {
163
+				// #ifndef APP-NVUE
164
+				this.getCollapseHeight(type)
165
+				// #endif
166
+				// #ifdef APP-NVUE
167
+				this.getNvueHwight(type)
168
+				// #endif
169
+			},
170
+			uninstall() {
171
+				if (this.collapse) {
172
+					this.collapse.childrens.forEach((item, index) => {
173
+						if (item === this) {
174
+							this.collapse.childrens.splice(index, 1)
175
+						}
176
+					})
177
+					this.collapse.names.forEach((item, index) => {
178
+						if (item === this.nameSync) {
179
+							this.collapse.names.splice(index, 1)
180
+						}
181
+					})
182
+				}
183
+			},
184
+			onClick(isOpen, type) {
185
+				if (this.disabled) return
186
+				this.isOpen = isOpen
187
+				if (this.isOpen && this.collapse) {
188
+					this.collapse.setAccordion(this)
189
+				}
190
+				if (type !== 'init') {
191
+					this.collapse.onChange(isOpen, this)
192
+				}
193
+			},
194
+			getCollapseHeight(type, index = 0) {
195
+				const views = uni.createSelectorQuery().in(this)
196
+				views
197
+					.select(`#${this.elId}`)
198
+					.fields({
199
+						size: true
200
+					}, data => {
201
+						// TODO 百度中可能获取不到节点信息 ,需要循环获取
202
+						if (index >= 10) return
203
+						if (!data) {
204
+							index++
205
+							this.getCollapseHeight(false, index)
206
+							return
207
+						}
208
+						// #ifdef APP-NVUE
209
+						this.height = data.height + 1
210
+						// #endif
211
+						// #ifndef APP-NVUE
212
+						this.height = data.height
213
+						// #endif
214
+						this.isheight = true
215
+						if (type) return
216
+						this.onClick(this.isOpen, 'init')
217
+					})
218
+					.exec()
219
+			},
220
+			getNvueHwight(type) {
221
+				const result = dom.getComponentRect(this.$refs['collapse--hook'], option => {
222
+					if (option && option.result && option.size) {
223
+						// #ifdef APP-NVUE
224
+						this.height = option.size.height + 1
225
+						// #endif
226
+						// #ifndef APP-NVUE
227
+						this.height = option.size.height
228
+						// #endif
229
+						this.isheight = true
230
+						if (type) return
231
+						this.onClick(this.open, 'init')
232
+					}
233
+				})
234
+			},
235
+			/**
236
+			 * 获取父元素实例
237
+			 */
238
+			getCollapse(name = 'uniCollapse') {
239
+				let parent = this.$parent;
240
+				let parentName = parent.$options.name;
241
+				while (parentName !== name) {
242
+					parent = parent.$parent;
243
+					if (!parent) return false;
244
+					parentName = parent.$options.name;
245
+				}
246
+				return parent;
247
+			}
248
+		}
249
+	}
250
+</script>
251
+
252
+<style lang="scss">
253
+	.uni-collapse-item {
254
+		/* #ifndef APP-NVUE */
255
+		box-sizing: border-box;
256
+
257
+		/* #endif */
258
+		&__title {
259
+			/* #ifndef APP-NVUE */
260
+			display: flex;
261
+			width: 100%;
262
+			box-sizing: border-box;
263
+			/* #endif */
264
+			flex-direction: row;
265
+			align-items: center;
266
+			transition: border-bottom-color .3s;
267
+
268
+			// transition-property: border-bottom-color;
269
+			// transition-duration: 5s;
270
+			&-wrap {
271
+				width: 100%;
272
+				flex: 1;
273
+
274
+			}
275
+
276
+			&-box {
277
+				padding: 0 15px;
278
+				/* #ifndef APP-NVUE */
279
+				display: flex;
280
+				width: 100%;
281
+				box-sizing: border-box;
282
+				/* #endif */
283
+				flex-direction: row;
284
+				justify-content: space-between;
285
+				align-items: center;
286
+				height: 48px;
287
+				line-height: 48px;
288
+				background-color: #fff;
289
+				color: #303133;
290
+				font-size: 13px;
291
+				font-weight: 500;
292
+				/* #ifdef H5 */
293
+				cursor: pointer;
294
+				outline: none;
295
+
296
+				/* #endif */
297
+				&.is-disabled {
298
+					.uni-collapse-item__title-text {
299
+						color: #999;
300
+					}
301
+				}
302
+
303
+			}
304
+
305
+			&.uni-collapse-item-border {
306
+				border-bottom: 1px solid #ebeef5;
307
+			}
308
+
309
+			&.is-open {
310
+				border-bottom-color: transparent;
311
+			}
312
+
313
+			&-img {
314
+				height: 22px;
315
+				width: 22px;
316
+				margin-right: 10px;
317
+			}
318
+
319
+			&-text {
320
+				flex: 1;
321
+				font-size: 14px;
322
+				/* #ifndef APP-NVUE */
323
+				white-space: nowrap;
324
+				color: inherit;
325
+				/* #endif */
326
+				/* #ifdef APP-NVUE */
327
+				lines: 1;
328
+				/* #endif */
329
+				overflow: hidden;
330
+				text-overflow: ellipsis;
331
+			}
332
+
333
+			&-arrow {
334
+				/* #ifndef APP-NVUE */
335
+				display: flex;
336
+				box-sizing: border-box;
337
+				/* #endif */
338
+				align-items: center;
339
+				justify-content: center;
340
+				width: 20px;
341
+				height: 20px;
342
+				margin-right: 10px;
343
+				transform: rotate(0deg);
344
+
345
+				&-active {
346
+					transform: rotate(-180deg);
347
+				}
348
+			}
349
+
350
+
351
+		}
352
+
353
+		&__wrap {
354
+			/* #ifndef APP-NVUE */
355
+			will-change: height;
356
+			box-sizing: border-box;
357
+			/* #endif */
358
+			background-color: #fff;
359
+			overflow: hidden;
360
+			position: relative;
361
+			height: 0;
362
+
363
+			&.is--transition {
364
+				// transition: all 0.3s;
365
+				transition-property: height, border-bottom-width;
366
+				transition-duration: 0.3s;
367
+				/* #ifndef APP-NVUE */
368
+				will-change: height;
369
+				/* #endif */
370
+			}
371
+
372
+
373
+
374
+			&-content {
375
+				position: absolute;
376
+				font-size: 13px;
377
+				color: #303133;
378
+				// transition: height 0.3s;
379
+				border-bottom-color: transparent;
380
+				border-bottom-style: solid;
381
+				border-bottom-width: 0;
382
+
383
+				&.uni-collapse-item--border {
384
+					border-bottom-width: 1px;
385
+					border-bottom-color: red;
386
+					border-bottom-color: #ebeef5;
387
+				}
388
+
389
+				&.open {
390
+					position: relative;
391
+				}
392
+			}
393
+		}
394
+
395
+		&--animation {
396
+			transition-property: transform;
397
+			transition-duration: 0.3s;
398
+			transition-timing-function: ease;
399
+		}
400
+
401
+	}
402
+</style>

+ 147
- 0
oa-ui-app/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue Voir le fichier

@@ -0,0 +1,147 @@
1
+<template>
2
+	<view class="uni-collapse">
3
+		<slot />
4
+	</view>
5
+</template>
6
+<script>
7
+	/**
8
+	 * Collapse 折叠面板
9
+	 * @description 展示可以折叠 / 展开的内容区域
10
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=23
11
+	 * @property {String|Array} value 当前激活面板改变时触发(如果是手风琴模式,参数类型为string,否则为array)
12
+	 * @property {Boolean} accordion = [true|false] 是否开启手风琴效果是否开启手风琴效果
13
+	 * @event {Function} change 切换面板时触发,如果是手风琴模式,返回类型为string,否则为array
14
+	 */
15
+	export default {
16
+		name: 'uniCollapse',
17
+		emits:['change','activeItem','input','update:modelValue'],
18
+		props: {
19
+			value: {
20
+				type: [String, Array],
21
+				default: ''
22
+			},
23
+			modelValue: {
24
+				type: [String, Array],
25
+				default: ''
26
+			},
27
+			accordion: {
28
+				// 是否开启手风琴效果
29
+				type: [Boolean, String],
30
+				default: false
31
+			},
32
+		},
33
+		data() {
34
+			return {}
35
+		},
36
+		computed: {
37
+			// TODO 兼容 vue2 和 vue3
38
+			dataValue() {
39
+				let value = (typeof this.value === 'string' && this.value === '') ||
40
+					(Array.isArray(this.value) && this.value.length === 0)
41
+				let modelValue = (typeof this.modelValue === 'string' && this.modelValue === '') ||
42
+					(Array.isArray(this.modelValue) && this.modelValue.length === 0)
43
+				if (value) {
44
+					return this.modelValue
45
+				}
46
+				if (modelValue) {
47
+					return this.value
48
+				}
49
+
50
+				return this.value
51
+			}
52
+		},
53
+		watch: {
54
+			dataValue(val) {
55
+				this.setOpen(val)
56
+			}
57
+		},
58
+		created() {
59
+			this.childrens = []
60
+			this.names = []
61
+		},
62
+		mounted() {
63
+			this.$nextTick(()=>{
64
+				this.setOpen(this.dataValue)
65
+			})
66
+		},
67
+		methods: {
68
+			setOpen(val) {
69
+				let str = typeof val === 'string'
70
+				let arr = Array.isArray(val)
71
+				this.childrens.forEach((vm, index) => {
72
+					if (str) {
73
+						if (val === vm.nameSync) {
74
+							if (!this.accordion) {
75
+								console.warn('accordion 属性为 false ,v-model 类型应该为 array')
76
+								return
77
+							}
78
+							vm.isOpen = true
79
+						}
80
+					}
81
+					if (arr) {
82
+						val.forEach(v => {
83
+							if (v === vm.nameSync) {
84
+								if (this.accordion) {
85
+									console.warn('accordion 属性为 true ,v-model 类型应该为 string')
86
+									return
87
+								}
88
+								vm.isOpen = true
89
+							}
90
+						})
91
+					}
92
+				})
93
+				this.emit(val)
94
+			},
95
+			setAccordion(self) {
96
+				if (!this.accordion) return
97
+				this.childrens.forEach((vm, index) => {
98
+					if (self !== vm) {
99
+						vm.isOpen = false
100
+					}
101
+				})
102
+			},
103
+			resize() {
104
+				this.childrens.forEach((vm, index) => {
105
+					// #ifndef APP-NVUE
106
+					vm.getCollapseHeight()
107
+					// #endif
108
+					// #ifdef APP-NVUE
109
+					vm.getNvueHwight()
110
+					// #endif
111
+				})
112
+			},
113
+			onChange(isOpen, self) {
114
+				let activeItem = []
115
+
116
+				if (this.accordion) {
117
+					activeItem = isOpen ? self.nameSync : ''
118
+				} else {
119
+					this.childrens.forEach((vm, index) => {
120
+						if (vm.isOpen) {
121
+							activeItem.push(vm.nameSync)
122
+						}
123
+					})
124
+				}
125
+				this.$emit('change', activeItem)
126
+				this.emit(activeItem)
127
+			},
128
+			emit(val){
129
+				this.$emit('input', val)
130
+				this.$emit('update:modelValue', val)
131
+			}
132
+		}
133
+	}
134
+</script>
135
+<style lang="scss" >
136
+	.uni-collapse {
137
+		/* #ifndef APP-NVUE */
138
+		width: 100%;
139
+		display: flex;
140
+		/* #endif */
141
+		/* #ifdef APP-NVUE */
142
+		flex: 1;
143
+		/* #endif */
144
+		flex-direction: column;
145
+		background-color: #fff;
146
+	}
147
+</style>

+ 89
- 0
oa-ui-app/uni_modules/uni-collapse/package.json Voir le fichier

@@ -0,0 +1,89 @@
1
+{
2
+  "id": "uni-collapse",
3
+  "displayName": "uni-collapse 折叠面板",
4
+  "version": "1.4.3",
5
+  "description": "Collapse 组件,可以折叠 / 展开的内容区域。",
6
+  "keywords": [
7
+    "uni-ui",
8
+    "折叠",
9
+    "折叠面板",
10
+    "手风琴"
11
+],
12
+  "repository": "https://github.com/dcloudio/uni-ui",
13
+  "engines": {
14
+    "HBuilderX": ""
15
+  },
16
+  "directories": {
17
+    "example": "../../temps/example_temps"
18
+  },
19
+  "dcloudext": {
20
+    "category": [
21
+      "前端组件",
22
+      "通用组件"
23
+    ],
24
+    "sale": {
25
+      "regular": {
26
+        "price": "0.00"
27
+      },
28
+      "sourcecode": {
29
+        "price": "0.00"
30
+      }
31
+    },
32
+    "contact": {
33
+      "qq": ""
34
+    },
35
+    "declaration": {
36
+      "ads": "无",
37
+      "data": "无",
38
+      "permissions": "无"
39
+    },
40
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
41
+  },
42
+  "uni_modules": {
43
+    "dependencies": [
44
+			"uni-scss",
45
+      "uni-icons"
46
+    ],
47
+    "encrypt": [],
48
+    "platforms": {
49
+      "cloud": {
50
+        "tcb": "y",
51
+        "aliyun": "y"
52
+      },
53
+      "client": {
54
+        "App": {
55
+          "app-vue": "y",
56
+          "app-nvue": "y"
57
+        },
58
+        "H5-mobile": {
59
+          "Safari": "y",
60
+          "Android Browser": "y",
61
+          "微信浏览器(Android)": "y",
62
+          "QQ浏览器(Android)": "y"
63
+        },
64
+        "H5-pc": {
65
+          "Chrome": "y",
66
+          "IE": "y",
67
+          "Edge": "y",
68
+          "Firefox": "y",
69
+          "Safari": "y"
70
+        },
71
+        "小程序": {
72
+          "微信": "y",
73
+          "阿里": "y",
74
+          "百度": "y",
75
+          "字节跳动": "y",
76
+          "QQ": "y"
77
+        },
78
+        "快应用": {
79
+          "华为": "u",
80
+          "联盟": "u"
81
+        },
82
+        "Vue": {
83
+            "vue2": "y",
84
+            "vue3": "y"
85
+        }
86
+      }
87
+    }
88
+  }
89
+}

+ 12
- 0
oa-ui-app/uni_modules/uni-collapse/readme.md Voir le fichier

@@ -0,0 +1,12 @@
1
+
2
+
3
+## Collapse 折叠面板
4
+> **组件名:uni-collapse**
5
+> 代码块: `uCollapse`
6
+> 关联组件:`uni-collapse-item`、`uni-icons`。
7
+
8
+
9
+折叠面板用来折叠/显示过长的内容或者是列表。通常是在多内容分类项使用,折叠不重要的内容,显示重要内容。点击可以展开折叠部分。
10
+
11
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-collapse)
12
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 15
- 0
oa-ui-app/uni_modules/uni-combox/changelog.md Voir le fichier

@@ -0,0 +1,15 @@
1
+## 1.0.1(2021-11-23)
2
+- 优化 label、label-width 属性
3
+## 1.0.0(2021-11-19)
4
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
5
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-combox](https://uniapp.dcloud.io/component/uniui/uni-combox)
6
+## 0.1.0(2021-07-30)
7
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
8
+## 0.0.6(2021-05-12)
9
+- 新增 组件示例地址
10
+## 0.0.5(2021-04-21)
11
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
12
+## 0.0.4(2021-02-05)
13
+- 优化 组件引用关系,通过uni_modules引用组件
14
+## 0.0.3(2021-02-04)
15
+- 调整为uni_modules目录规范

+ 275
- 0
oa-ui-app/uni_modules/uni-combox/components/uni-combox/uni-combox.vue Voir le fichier

@@ -0,0 +1,275 @@
1
+<template>
2
+	<view class="uni-combox" :class="border ? '' : 'uni-combox__no-border'">
3
+		<view v-if="label" class="uni-combox__label" :style="labelStyle">
4
+			<text>{{label}}</text>
5
+		</view>
6
+		<view class="uni-combox__input-box">
7
+			<input class="uni-combox__input" type="text" :placeholder="placeholder" 
8
+			placeholder-class="uni-combox__input-plac" v-model="inputVal" @input="onInput" @focus="onFocus" 
9
+@blur="onBlur" />
10
+			<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#999" @click="toggleSelector">
11
+			</uni-icons>
12
+		</view>
13
+		<view class="uni-combox__selector" v-if="showSelector">
14
+			<view class="uni-popper__arrow"></view>
15
+			<scroll-view scroll-y="true" class="uni-combox__selector-scroll">
16
+				<view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0">
17
+					<text>{{emptyTips}}</text>
18
+				</view>
19
+				<view class="uni-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index" 
20
+				@click="onSelectorClick(index)">
21
+					<text>{{item}}</text>
22
+				</view>
23
+			</scroll-view>
24
+		</view>
25
+	</view>
26
+</template>
27
+
28
+<script>
29
+	/**
30
+	 * Combox 组合输入框
31
+	 * @description 组合输入框一般用于既可以输入也可以选择的场景
32
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=1261
33
+	 * @property {String} label 左侧文字
34
+	 * @property {String} labelWidth 左侧内容宽度
35
+	 * @property {String} placeholder 输入框占位符
36
+	 * @property {Array} candidates 候选项列表
37
+	 * @property {String} emptyTips 筛选结果为空时显示的文字
38
+	 * @property {String} value 组合框的值
39
+	 */
40
+	export default {
41
+		name: 'uniCombox',
42
+		emits: ['input', 'update:modelValue'],
43
+		props: {
44
+			border: {
45
+				type: Boolean,
46
+				default: true
47
+			},
48
+			label: {
49
+				type: String,
50
+				default: ''
51
+			},
52
+			labelWidth: {
53
+				type: String,
54
+				default: 'auto'
55
+			},
56
+			placeholder: {
57
+				type: String,
58
+				default: ''
59
+			},
60
+			candidates: {
61
+				type: Array,
62
+				default () {
63
+					return []
64
+				}
65
+			},
66
+			emptyTips: {
67
+				type: String,
68
+				default: '无匹配项'
69
+			},
70
+			// #ifndef VUE3
71
+			value: {
72
+				type: [String, Number],
73
+				default: ''
74
+			},
75
+			// #endif
76
+			// #ifdef VUE3
77
+			modelValue: {
78
+				type: [String, Number],
79
+				default: ''
80
+			},
81
+			// #endif
82
+		},
83
+		data() {
84
+			return {
85
+				showSelector: false,
86
+				inputVal: ''
87
+			}
88
+		},
89
+		computed: {
90
+			labelStyle() {
91
+				if (this.labelWidth === 'auto') {
92
+					return ""
93
+				}
94
+				return `width: ${this.labelWidth}`
95
+			},
96
+			filterCandidates() {
97
+				return this.candidates.filter((item) => {
98
+					return item.toString().indexOf(this.inputVal) > -1
99
+				})
100
+			},
101
+			filterCandidatesLength() {
102
+				return this.filterCandidates.length
103
+			}
104
+		},
105
+		watch: {
106
+			// #ifndef VUE3
107
+			value: {
108
+				handler(newVal) {
109
+					this.inputVal = newVal
110
+				},
111
+				immediate: true
112
+			},
113
+			// #endif
114
+			// #ifdef VUE3
115
+			modelValue: {
116
+				handler(newVal) {
117
+					this.inputVal = newVal
118
+				},
119
+				immediate: true
120
+			},
121
+			// #endif
122
+		},
123
+		methods: {
124
+			toggleSelector() {
125
+				this.showSelector = !this.showSelector
126
+			},
127
+			onFocus() {
128
+				this.showSelector = true
129
+			},
130
+			onBlur() {
131
+				setTimeout(() => {
132
+					this.showSelector = false
133
+				}, 153)
134
+			},
135
+			onSelectorClick(index) {
136
+				this.inputVal = this.filterCandidates[index]
137
+				this.showSelector = false
138
+				this.$emit('input', this.inputVal)
139
+				this.$emit('update:modelValue', this.inputVal)
140
+			},
141
+			onInput() {
142
+				setTimeout(() => {
143
+					this.$emit('input', this.inputVal)
144
+					this.$emit('update:modelValue', this.inputVal)
145
+				})
146
+			}
147
+		}
148
+	}
149
+</script>
150
+
151
+<style lang="scss" >
152
+	.uni-combox {
153
+		font-size: 14px;
154
+		border: 1px solid #DCDFE6;
155
+		border-radius: 4px;
156
+		padding: 6px 10px;
157
+		position: relative;
158
+		/* #ifndef APP-NVUE */
159
+		display: flex;
160
+		/* #endif */
161
+		// height: 40px;
162
+		flex-direction: row;
163
+		align-items: center;
164
+		// border-bottom: solid 1px #DDDDDD;
165
+	}
166
+
167
+	.uni-combox__label {
168
+		font-size: 16px;
169
+		line-height: 22px;
170
+		padding-right: 10px;
171
+		color: #999999;
172
+	}
173
+
174
+	.uni-combox__input-box {
175
+		position: relative;
176
+		/* #ifndef APP-NVUE */
177
+		display: flex;
178
+		/* #endif */
179
+		flex: 1;
180
+		flex-direction: row;
181
+		align-items: center;
182
+	}
183
+
184
+	.uni-combox__input {
185
+		flex: 1;
186
+		font-size: 14px;
187
+		height: 22px;
188
+		line-height: 22px;
189
+	}
190
+
191
+	.uni-combox__input-plac {
192
+		font-size: 14px;
193
+		color: #999;
194
+	}
195
+
196
+	.uni-combox__selector {
197
+		/* #ifndef APP-NVUE */
198
+		box-sizing: border-box;
199
+		/* #endif */
200
+		position: absolute;
201
+		top: calc(100% + 12px);
202
+		left: 0;
203
+		width: 100%;
204
+		background-color: #FFFFFF;
205
+		border: 1px solid #EBEEF5;
206
+		border-radius: 6px;
207
+		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
208
+		z-index: 2;
209
+		padding: 4px 0;
210
+	}
211
+
212
+	.uni-combox__selector-scroll {
213
+		/* #ifndef APP-NVUE */
214
+		max-height: 200px;
215
+		box-sizing: border-box;
216
+		/* #endif */
217
+	}
218
+
219
+	.uni-combox__selector-empty,
220
+	.uni-combox__selector-item {
221
+		/* #ifndef APP-NVUE */
222
+		display: flex;
223
+		cursor: pointer;
224
+		/* #endif */
225
+		line-height: 36px;
226
+		font-size: 14px;
227
+		text-align: center;
228
+		// border-bottom: solid 1px #DDDDDD;
229
+		padding: 0px 10px;
230
+	}
231
+
232
+	.uni-combox__selector-item:hover {
233
+		background-color: #f9f9f9;
234
+	}
235
+
236
+	.uni-combox__selector-empty:last-child,
237
+	.uni-combox__selector-item:last-child {
238
+		/* #ifndef APP-NVUE */
239
+		border-bottom: none;
240
+		/* #endif */
241
+	}
242
+
243
+	// picker 弹出层通用的指示小三角
244
+	.uni-popper__arrow,
245
+	.uni-popper__arrow::after {
246
+		position: absolute;
247
+		display: block;
248
+		width: 0;
249
+		height: 0;
250
+		border-color: transparent;
251
+		border-style: solid;
252
+		border-width: 6px;
253
+	}
254
+
255
+	.uni-popper__arrow {
256
+		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
257
+		top: -6px;
258
+		left: 10%;
259
+		margin-right: 3px;
260
+		border-top-width: 0;
261
+		border-bottom-color: #EBEEF5;
262
+	}
263
+
264
+	.uni-popper__arrow::after {
265
+		content: " ";
266
+		top: 1px;
267
+		margin-left: -6px;
268
+		border-top-width: 0;
269
+		border-bottom-color: #fff;
270
+	}
271
+
272
+	.uni-combox__no-border {
273
+		border: none;
274
+	}
275
+</style>

+ 90
- 0
oa-ui-app/uni_modules/uni-combox/package.json Voir le fichier

@@ -0,0 +1,90 @@
1
+{
2
+  "id": "uni-combox",
3
+  "displayName": "uni-combox 组合框",
4
+  "version": "1.0.1",
5
+  "description": "可以选择也可以输入的表单项 ",
6
+  "keywords": [
7
+    "uni-ui",
8
+    "uniui",
9
+    "combox",
10
+    "组合框",
11
+    "select"
12
+],
13
+  "repository": "https://github.com/dcloudio/uni-ui",
14
+  "engines": {
15
+    "HBuilderX": ""
16
+  },
17
+  "directories": {
18
+    "example": "../../temps/example_temps"
19
+  },
20
+  "dcloudext": {
21
+    "category": [
22
+      "前端组件",
23
+      "通用组件"
24
+    ],
25
+    "sale": {
26
+      "regular": {
27
+        "price": "0.00"
28
+      },
29
+      "sourcecode": {
30
+        "price": "0.00"
31
+      }
32
+    },
33
+    "contact": {
34
+      "qq": ""
35
+    },
36
+    "declaration": {
37
+      "ads": "无",
38
+      "data": "无",
39
+      "permissions": "无"
40
+    },
41
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
42
+  },
43
+  "uni_modules": {
44
+    "dependencies": [
45
+			"uni-scss",
46
+			"uni-icons"
47
+		],
48
+    "encrypt": [],
49
+    "platforms": {
50
+      "cloud": {
51
+        "tcb": "y",
52
+        "aliyun": "y"
53
+      },
54
+      "client": {
55
+        "App": {
56
+          "app-vue": "y",
57
+          "app-nvue": "n"
58
+        },
59
+        "H5-mobile": {
60
+          "Safari": "y",
61
+          "Android Browser": "y",
62
+          "微信浏览器(Android)": "y",
63
+          "QQ浏览器(Android)": "y"
64
+        },
65
+        "H5-pc": {
66
+          "Chrome": "y",
67
+          "IE": "y",
68
+          "Edge": "y",
69
+          "Firefox": "y",
70
+          "Safari": "y"
71
+        },
72
+        "小程序": {
73
+          "微信": "y",
74
+          "阿里": "y",
75
+          "百度": "y",
76
+          "字节跳动": "y",
77
+          "QQ": "y"
78
+        },
79
+        "快应用": {
80
+          "华为": "u",
81
+          "联盟": "u"
82
+        },
83
+        "Vue": {
84
+            "vue2": "y",
85
+            "vue3": "y"
86
+        }
87
+      }
88
+    }
89
+  }
90
+}

+ 11
- 0
oa-ui-app/uni_modules/uni-combox/readme.md Voir le fichier

@@ -0,0 +1,11 @@
1
+
2
+
3
+## Combox 组合框
4
+> **组件名:uni-combox**
5
+> 代码块: `uCombox`
6
+
7
+
8
+组合框组件。
9
+
10
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-combox)
11
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 24
- 0
oa-ui-app/uni_modules/uni-countdown/changelog.md Voir le fichier

@@ -0,0 +1,24 @@
1
+## 1.2.2(2022-01-19)
2
+- 修复 在微信小程序中样式不生效的bug
3
+## 1.2.1(2022-01-18)
4
+- 新增 update 方法 ,在动态更新时间后,刷新组件
5
+## 1.2.0(2021-11-19)
6
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
7
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-countdown](https://uniapp.dcloud.io/component/uniui/uni-countdown)
8
+## 1.1.3(2021-10-18)
9
+- 重构
10
+- 新增 font-size 支持自定义字体大小
11
+## 1.1.2(2021-08-24)
12
+- 新增 支持国际化
13
+## 1.1.1(2021-07-30)
14
+- 优化 vue3下小程序事件警告的问题
15
+## 1.1.0(2021-07-30)
16
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
17
+## 1.0.5(2021-06-18)
18
+- 修复 uni-countdown 重复赋值跳两秒的 bug
19
+## 1.0.4(2021-05-12)
20
+- 新增 组件示例地址
21
+## 1.0.3(2021-05-08)
22
+- 修复 uni-countdown 不能控制倒计时的 bug
23
+## 1.0.2(2021-02-04)
24
+- 调整为uni_modules目录规范

+ 6
- 0
oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json Voir le fichier

@@ -0,0 +1,6 @@
1
+{
2
+	"uni-countdown.day": "day",
3
+	"uni-countdown.h": "h",
4
+	"uni-countdown.m": "m",
5
+	"uni-countdown.s": "s"
6
+}

+ 8
- 0
oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/i18n/index.js Voir le fichier

@@ -0,0 +1,8 @@
1
+import en from './en.json'
2
+import zhHans from './zh-Hans.json'
3
+import zhHant from './zh-Hant.json'
4
+export default {
5
+	en,
6
+	'zh-Hans': zhHans,
7
+	'zh-Hant': zhHant
8
+}

+ 6
- 0
oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json Voir le fichier

@@ -0,0 +1,6 @@
1
+{
2
+	"uni-countdown.day": "天",
3
+	"uni-countdown.h": "时",
4
+	"uni-countdown.m": "分",
5
+	"uni-countdown.s": "秒"
6
+}

+ 6
- 0
oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json Voir le fichier

@@ -0,0 +1,6 @@
1
+{
2
+	"uni-countdown.day": "天",
3
+	"uni-countdown.h": "時",
4
+	"uni-countdown.m": "分",
5
+	"uni-countdown.s": "秒"
6
+}

+ 271
- 0
oa-ui-app/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue Voir le fichier

@@ -0,0 +1,271 @@
1
+<template>
2
+	<view class="uni-countdown">
3
+		<text v-if="showDay" :style="[timeStyle]" class="uni-countdown__number">{{ d }}</text>
4
+		<text v-if="showDay" :style="[splitorStyle]" class="uni-countdown__splitor">{{dayText}}</text>
5
+		<text :style="[timeStyle]" class="uni-countdown__number">{{ h }}</text>
6
+		<text :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : hourText }}</text>
7
+		<text :style="[timeStyle]" class="uni-countdown__number">{{ i }}</text>
8
+		<text :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : minuteText }}</text>
9
+		<text :style="[timeStyle]" class="uni-countdown__number">{{ s }}</text>
10
+		<text v-if="!showColon" :style="[splitorStyle]" class="uni-countdown__splitor">{{secondText}}</text>
11
+	</view>
12
+</template>
13
+<script>
14
+	import {
15
+		initVueI18n
16
+	} from '@dcloudio/uni-i18n'
17
+	import messages from './i18n/index.js'
18
+	const {
19
+		t
20
+	} = initVueI18n(messages)
21
+	/**
22
+	 * Countdown 倒计时
23
+	 * @description 倒计时组件
24
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=25
25
+	 * @property {String} backgroundColor 背景色
26
+	 * @property {String} color 文字颜色
27
+	 * @property {Number} day 天数
28
+	 * @property {Number} hour 小时
29
+	 * @property {Number} minute 分钟
30
+	 * @property {Number} second 秒
31
+	 * @property {Number} timestamp 时间戳
32
+	 * @property {Boolean} showDay = [true|false] 是否显示天数
33
+	 * @property {Boolean} show-colon = [true|false] 是否以冒号为分隔符
34
+	 * @property {String} splitorColor 分割符号颜色
35
+	 * @event {Function} timeup 倒计时时间到触发事件
36
+	 * @example <uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-countdown>
37
+	 */
38
+	export default {
39
+		name: 'UniCountdown',
40
+		emits: ['timeup'],
41
+		props: {
42
+			showDay: {
43
+				type: Boolean,
44
+				default: true
45
+			},
46
+			showColon: {
47
+				type: Boolean,
48
+				default: true
49
+			},
50
+			start: {
51
+				type: Boolean,
52
+				default: true
53
+			},
54
+			backgroundColor: {
55
+				type: String,
56
+				default: ''
57
+			},
58
+			color: {
59
+				type: String,
60
+				default: '#333'
61
+			},
62
+			fontSize: {
63
+				type: Number,
64
+				default: 14
65
+			},
66
+			splitorColor: {
67
+				type: String,
68
+				default: '#333'
69
+			},
70
+			day: {
71
+				type: Number,
72
+				default: 0
73
+			},
74
+			hour: {
75
+				type: Number,
76
+				default: 0
77
+			},
78
+			minute: {
79
+				type: Number,
80
+				default: 0
81
+			},
82
+			second: {
83
+				type: Number,
84
+				default: 0
85
+			},
86
+			timestamp: {
87
+				type: Number,
88
+				default: 0
89
+			}
90
+		},
91
+		data() {
92
+			return {
93
+				timer: null,
94
+				syncFlag: false,
95
+				d: '00',
96
+				h: '00',
97
+				i: '00',
98
+				s: '00',
99
+				leftTime: 0,
100
+				seconds: 0
101
+			}
102
+		},
103
+		computed: {
104
+			dayText() {
105
+				return t("uni-countdown.day")
106
+			},
107
+			hourText(val) {
108
+				return t("uni-countdown.h")
109
+			},
110
+			minuteText(val) {
111
+				return t("uni-countdown.m")
112
+			},
113
+			secondText(val) {
114
+				return t("uni-countdown.s")
115
+			},
116
+			timeStyle() {
117
+				const {
118
+					color,
119
+					backgroundColor,
120
+					fontSize
121
+				} = this
122
+				return {
123
+					color,
124
+					backgroundColor,
125
+					fontSize: `${fontSize}px`,
126
+					width: `${fontSize * 22 / 14}px`, // 按字体大小为 14px 时的比例缩放
127
+ 					lineHeight: `${fontSize * 20 / 14}px`,
128
+					borderRadius: `${fontSize * 3 / 14}px`,
129
+				}
130
+			},
131
+			splitorStyle() {
132
+				const { splitorColor, fontSize, backgroundColor } = this
133
+				return {
134
+					color: splitorColor,
135
+					fontSize: `${fontSize * 12 / 14}px`,
136
+					margin: backgroundColor ? `${fontSize * 4 / 14}px` : ''
137
+				}
138
+			}
139
+		},
140
+		watch: {
141
+			day(val) {
142
+				this.changeFlag()
143
+			},
144
+			hour(val) {
145
+				this.changeFlag()
146
+			},
147
+			minute(val) {
148
+				this.changeFlag()
149
+			},
150
+			second(val) {
151
+				this.changeFlag()
152
+			},
153
+			start: {
154
+				immediate: true,
155
+				handler(newVal, oldVal) {
156
+					if (newVal) {
157
+						this.startData();
158
+					} else {
159
+						if (!oldVal) return
160
+						clearInterval(this.timer)
161
+					}
162
+				}
163
+
164
+			}
165
+		},
166
+		created: function(e) {
167
+			this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
168
+			this.countDown()
169
+		},
170
+		// #ifndef VUE3
171
+		destroyed() {
172
+			clearInterval(this.timer)
173
+		},
174
+		// #endif
175
+		// #ifdef VUE3
176
+		unmounted() {
177
+			clearInterval(this.timer)
178
+		},
179
+		// #endif
180
+		methods: {
181
+			toSeconds(timestamp, day, hours, minutes, seconds) {
182
+				if (timestamp) {
183
+					return timestamp - parseInt(new Date().getTime() / 1000, 10)
184
+				}
185
+				return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds
186
+			},
187
+			timeUp() {
188
+				clearInterval(this.timer)
189
+				this.$emit('timeup')
190
+			},
191
+			countDown() {
192
+				let seconds = this.seconds
193
+				let [day, hour, minute, second] = [0, 0, 0, 0]
194
+				if (seconds > 0) {
195
+					day = Math.floor(seconds / (60 * 60 * 24))
196
+					hour = Math.floor(seconds / (60 * 60)) - (day * 24)
197
+					minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
198
+					second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
199
+				} else {
200
+					this.timeUp()
201
+				}
202
+				if (day < 10) {
203
+					day = '0' + day
204
+				}
205
+				if (hour < 10) {
206
+					hour = '0' + hour
207
+				}
208
+				if (minute < 10) {
209
+					minute = '0' + minute
210
+				}
211
+				if (second < 10) {
212
+					second = '0' + second
213
+				}
214
+				this.d = day
215
+				this.h = hour
216
+				this.i = minute
217
+				this.s = second
218
+			},
219
+			startData() {
220
+				this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
221
+				if (this.seconds <= 0) {
222
+					this.seconds = this.toSeconds(0, 0, 0, 0, 0)
223
+					this.countDown()
224
+					return
225
+				}
226
+				clearInterval(this.timer)
227
+				this.countDown()
228
+				this.timer = setInterval(() => {
229
+					this.seconds--
230
+					if (this.seconds < 0) {
231
+						this.timeUp()
232
+						return
233
+					}
234
+					this.countDown()
235
+				}, 1000)
236
+			},
237
+			update(){
238
+				this.startData();
239
+			},
240
+			changeFlag() {
241
+				if (!this.syncFlag) {
242
+					this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
243
+					this.startData();
244
+					this.syncFlag = true;
245
+				}
246
+			}
247
+		}
248
+	}
249
+</script>
250
+<style lang="scss" scoped>
251
+	$font-size: 14px;
252
+
253
+	.uni-countdown {
254
+		display: flex;
255
+		flex-direction: row;
256
+		justify-content: flex-start;
257
+		align-items: center;
258
+
259
+		&__splitor {
260
+			margin: 0 2px;
261
+			font-size: $font-size;
262
+			color: #333;
263
+		}
264
+
265
+		&__number {
266
+			border-radius: 3px;
267
+			text-align: center;
268
+			font-size: $font-size;
269
+		}
270
+	}
271
+</style>

+ 86
- 0
oa-ui-app/uni_modules/uni-countdown/package.json Voir le fichier

@@ -0,0 +1,86 @@
1
+{
2
+  "id": "uni-countdown",
3
+  "displayName": "uni-countdown 倒计时",
4
+  "version": "1.2.2",
5
+  "description": "CountDown 倒计时组件",
6
+  "keywords": [
7
+    "uni-ui",
8
+    "uniui",
9
+    "countdown",
10
+    "倒计时"
11
+],
12
+  "repository": "https://github.com/dcloudio/uni-ui",
13
+  "engines": {
14
+    "HBuilderX": ""
15
+  },
16
+  "directories": {
17
+    "example": "../../temps/example_temps"
18
+  },
19
+  "dcloudext": {
20
+    "category": [
21
+      "前端组件",
22
+      "通用组件"
23
+    ],
24
+    "sale": {
25
+      "regular": {
26
+        "price": "0.00"
27
+      },
28
+      "sourcecode": {
29
+        "price": "0.00"
30
+      }
31
+    },
32
+    "contact": {
33
+      "qq": ""
34
+    },
35
+    "declaration": {
36
+      "ads": "无",
37
+      "data": "无",
38
+      "permissions": "无"
39
+    },
40
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
41
+  },
42
+  "uni_modules": {
43
+    "dependencies": ["uni-scss"],
44
+    "encrypt": [],
45
+    "platforms": {
46
+      "cloud": {
47
+        "tcb": "y",
48
+        "aliyun": "y"
49
+      },
50
+      "client": {
51
+        "App": {
52
+          "app-vue": "y",
53
+          "app-nvue": "y"
54
+        },
55
+        "H5-mobile": {
56
+          "Safari": "y",
57
+          "Android Browser": "y",
58
+          "微信浏览器(Android)": "y",
59
+          "QQ浏览器(Android)": "y"
60
+        },
61
+        "H5-pc": {
62
+          "Chrome": "y",
63
+          "IE": "y",
64
+          "Edge": "y",
65
+          "Firefox": "y",
66
+          "Safari": "y"
67
+        },
68
+        "小程序": {
69
+          "微信": "y",
70
+          "阿里": "y",
71
+          "百度": "y",
72
+          "字节跳动": "y",
73
+          "QQ": "y"
74
+        },
75
+        "快应用": {
76
+          "华为": "u",
77
+          "联盟": "u"
78
+        },
79
+        "Vue": {
80
+            "vue2": "y",
81
+            "vue3": "y"
82
+        }
83
+      }
84
+    }
85
+  }
86
+}

+ 10
- 0
oa-ui-app/uni_modules/uni-countdown/readme.md Voir le fichier

@@ -0,0 +1,10 @@
1
+
2
+
3
+## CountDown 倒计时
4
+> **组件名:uni-countdown**
5
+> 代码块: `uCountDown`
6
+
7
+倒计时组件。
8
+
9
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-countdown)
10
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 45
- 0
oa-ui-app/uni_modules/uni-data-checkbox/changelog.md Voir le fichier

@@ -0,0 +1,45 @@
1
+## 1.0.3(2022-09-16)
2
+- 可以使用 uni-scss 控制主题色
3
+## 1.0.2(2022-06-30)
4
+- 优化 在 uni-forms 中的依赖注入方式
5
+## 1.0.1(2022-02-07)
6
+- 修复 multiple 为 true 时,v-model 的值为 null 报错的 bug
7
+## 1.0.0(2021-11-19)
8
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
9
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-checkbox](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox)
10
+## 0.2.5(2021-08-23)
11
+- 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题
12
+## 0.2.4(2021-08-17)
13
+- 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题
14
+## 0.2.3(2021-08-11)
15
+- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
16
+## 0.2.2(2021-07-30)
17
+- 优化 在uni-forms组件,与label不对齐的问题
18
+## 0.2.1(2021-07-27)
19
+- 修复 单选默认值为0不能选中的Bug
20
+## 0.2.0(2021-07-13)
21
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
22
+## 0.1.11(2021-07-06)
23
+- 优化 删除无用日志
24
+## 0.1.10(2021-07-05)
25
+- 修复 由 0.1.9 引起的非 nvue 端图标不显示的问题
26
+## 0.1.9(2021-07-05)
27
+- 修复 nvue 黑框样式问题
28
+## 0.1.8(2021-06-28)
29
+- 修复 selectedTextColor 属性不生效的Bug
30
+## 0.1.7(2021-06-02)
31
+- 新增 map 属性,可以方便映射text/value属性
32
+## 0.1.6(2021-05-26)
33
+- 修复 不关联服务空间的情况下组件报错的Bug
34
+## 0.1.5(2021-05-12)
35
+- 新增 组件示例地址
36
+## 0.1.4(2021-04-09)
37
+- 修复 nvue 下无法选中的问题
38
+## 0.1.3(2021-03-22)
39
+- 新增 disabled属性
40
+## 0.1.2(2021-02-24)
41
+- 优化 默认颜色显示
42
+## 0.1.1(2021-02-24)
43
+- 新增 支持nvue
44
+## 0.1.0(2021-02-18)
45
+- “暂无数据”显示居中

+ 821
- 0
oa-ui-app/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue Voir le fichier

@@ -0,0 +1,821 @@
1
+<template>
2
+	<view class="uni-data-checklist" :style="{'margin-top':isTop+'px'}">
3
+		<template v-if="!isLocal">
4
+			<view class="uni-data-loading">
5
+				<uni-load-more v-if="!mixinDatacomErrorMessage" status="loading" iconType="snow" :iconSize="18" :content-text="contentText"></uni-load-more>
6
+				<text v-else>{{mixinDatacomErrorMessage}}</text>
7
+			</view>
8
+		</template>
9
+		<template v-else>
10
+			<checkbox-group v-if="multiple" class="checklist-group" :class="{'is-list':mode==='list' || wrap}" @change="chagne">
11
+				<label class="checklist-box" :class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
12
+				 :style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
13
+					<checkbox class="hidden" hidden :disabled="disabled || !!item.disabled" :value="item[map.value]+''" :checked="item.selected" />
14
+					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="checkbox__inner"  :style="item.styleIcon">
15
+						<view class="checkbox__inner-icon"></view>
16
+					</view>
17
+					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
18
+						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
19
+						<view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view>
20
+					</view>
21
+				</label>
22
+			</checkbox-group>
23
+			<radio-group v-else class="checklist-group" :class="{'is-list':mode==='list','is-wrap':wrap}" @change="chagne">
24
+				<!-- -->
25
+				<label class="checklist-box" :class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']"
26
+				 :style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index">
27
+					<radio class="hidden" hidden :disabled="disabled || item.disabled" :value="item[map.value]+''" :checked="item.selected" />
28
+					<view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="radio__inner"
29
+					 :style="item.styleBackgroud">
30
+						<view class="radio__inner-icon" :style="item.styleIcon"></view>
31
+					</view>
32
+					<view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}">
33
+						<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
34
+						<view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view>
35
+					</view>
36
+				</label>
37
+			</radio-group>
38
+		</template>
39
+	</view>
40
+</template>
41
+
42
+<script>
43
+	/**
44
+	 * DataChecklist 数据选择器
45
+	 * @description 通过数据渲染 checkbox 和 radio
46
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
47
+	 * @property {String} mode = [default| list | button | tag] 显示模式
48
+	 * @value default  	默认横排模式
49
+	 * @value list		列表模式
50
+	 * @value button	按钮模式
51
+	 * @value tag 		标签模式
52
+	 * @property {Boolean} multiple = [true|false] 是否多选
53
+	 * @property {Array|String|Number} value 默认值
54
+	 * @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
55
+	 * @property {Number|String} min 最小选择个数 ,multiple为true时生效
56
+	 * @property {Number|String} max 最大选择个数 ,multiple为true时生效
57
+	 * @property {Boolean} wrap 是否换行显示
58
+	 * @property {String} icon = [left|right]  list 列表模式下icon显示位置
59
+	 * @property {Boolean} selectedColor 选中颜色
60
+	 * @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
61
+	 * @property {Boolean} selectedTextColor 选中文本颜色,如不填写则自动显示
62
+	 * @property {Object} map 字段映射, 默认 map={text:'text',value:'value'}
63
+	 * @value left 左侧显示
64
+	 * @value right 右侧显示
65
+	 * @event {Function} change  选中发生变化触发
66
+	 */
67
+
68
+	export default {
69
+		name: 'uniDataChecklist',
70
+		mixins: [uniCloud.mixinDatacom || {}],
71
+		emits:['input','update:modelValue','change'],
72
+		props: {
73
+			mode: {
74
+				type: String,
75
+				default: 'default'
76
+			},
77
+
78
+			multiple: {
79
+				type: Boolean,
80
+				default: false
81
+			},
82
+			value: {
83
+				type: [Array, String, Number],
84
+				default () {
85
+					return ''
86
+				}
87
+			},
88
+			// TODO vue3
89
+			modelValue: {
90
+				type: [Array, String, Number],
91
+				default() {
92
+					return '';
93
+				}
94
+			},
95
+			localdata: {
96
+				type: Array,
97
+				default () {
98
+					return []
99
+				}
100
+			},
101
+			min: {
102
+				type: [Number, String],
103
+				default: ''
104
+			},
105
+			max: {
106
+				type: [Number, String],
107
+				default: ''
108
+			},
109
+			wrap: {
110
+				type: Boolean,
111
+				default: false
112
+			},
113
+			icon: {
114
+				type: String,
115
+				default: 'left'
116
+			},
117
+			selectedColor: {
118
+				type: String,
119
+				default: ''
120
+			},
121
+			selectedTextColor: {
122
+				type: String,
123
+				default: ''
124
+			},
125
+			emptyText:{
126
+				type: String,
127
+				default: '暂无数据'
128
+			},
129
+			disabled:{
130
+				type: Boolean,
131
+				default: false
132
+			},
133
+			map:{
134
+				type: Object,
135
+				default(){
136
+					return {
137
+						text:'text',
138
+						value:'value'
139
+					}
140
+				}
141
+			}
142
+		},
143
+		watch: {
144
+			localdata: {
145
+				handler(newVal) {
146
+					this.range = newVal
147
+					this.dataList = this.getDataList(this.getSelectedValue(newVal))
148
+				},
149
+				deep: true
150
+			},
151
+			mixinDatacomResData(newVal) {
152
+				this.range = newVal
153
+				this.dataList = this.getDataList(this.getSelectedValue(newVal))
154
+			},
155
+			value(newVal) {
156
+				this.dataList = this.getDataList(newVal)
157
+				// fix by mehaotian is_reset 在 uni-forms 中定义
158
+				// if(!this.is_reset){
159
+				// 	this.is_reset = false
160
+				// 	this.formItem && this.formItem.setValue(newVal)
161
+				// }
162
+			},
163
+			modelValue(newVal) {
164
+				this.dataList = this.getDataList(newVal);
165
+				// if(!this.is_reset){
166
+				// 	this.is_reset = false
167
+				// 	this.formItem && this.formItem.setValue(newVal)
168
+				// }
169
+			}
170
+		},
171
+		data() {
172
+			return {
173
+				dataList: [],
174
+				range: [],
175
+				contentText: {
176
+					contentdown: '查看更多',
177
+					contentrefresh: '加载中',
178
+					contentnomore: '没有更多'
179
+				},
180
+				isLocal:true,
181
+				styles: {
182
+					selectedColor: '#2979ff',
183
+					selectedTextColor: '#666',
184
+				},
185
+				isTop:0
186
+			};
187
+		},
188
+		computed:{
189
+			dataValue(){
190
+				if(this.value === '')return this.modelValue
191
+				if(this.modelValue === '') return this.value
192
+				return this.value
193
+			}
194
+		},
195
+		created() {
196
+			// this.form = this.getForm('uniForms')
197
+			// this.formItem = this.getForm('uniFormsItem')
198
+			// this.formItem && this.formItem.setValue(this.value)
199
+
200
+			// if (this.formItem) {
201
+			// 	this.isTop = 6
202
+			// 	if (this.formItem.name) {
203
+			// 		// 如果存在name添加默认值,否则formData 中不存在这个字段不校验
204
+			// 		if(!this.is_reset){
205
+			// 			this.is_reset = false
206
+			// 			this.formItem.setValue(this.dataValue)
207
+			// 		}
208
+			// 		this.rename = this.formItem.name
209
+			// 		this.form.inputChildrens.push(this)
210
+			// 	}
211
+			// }
212
+
213
+			if (this.localdata && this.localdata.length !== 0) {
214
+				this.isLocal = true
215
+				this.range = this.localdata
216
+				this.dataList = this.getDataList(this.getSelectedValue(this.range))
217
+			} else {
218
+				if (this.collection) {
219
+					this.isLocal = false
220
+					this.loadData()
221
+				}
222
+			}
223
+		},
224
+		methods: {
225
+			loadData() {
226
+				this.mixinDatacomGet().then(res=>{
227
+					this.mixinDatacomResData = res.result.data
228
+					if(this.mixinDatacomResData.length === 0){
229
+						this.isLocal = false
230
+						this.mixinDatacomErrorMessage = this.emptyText
231
+					}else{
232
+						this.isLocal = true
233
+					}
234
+				}).catch(err=>{
235
+					this.mixinDatacomErrorMessage = err.message
236
+				})
237
+			},
238
+			/**
239
+			 * 获取父元素实例
240
+			 */
241
+			getForm(name = 'uniForms') {
242
+				let parent = this.$parent;
243
+				let parentName = parent.$options.name;
244
+				while (parentName !== name) {
245
+					parent = parent.$parent;
246
+					if (!parent) return false
247
+					parentName = parent.$options.name;
248
+				}
249
+				return parent;
250
+			},
251
+			chagne(e) {
252
+				const values = e.detail.value
253
+
254
+				let detail = {
255
+					value: [],
256
+					data: []
257
+				}
258
+
259
+				if (this.multiple) {
260
+					this.range.forEach(item => {
261
+
262
+						if (values.includes(item[this.map.value] + '')) {
263
+							detail.value.push(item[this.map.value])
264
+							detail.data.push(item)
265
+						}
266
+					})
267
+				} else {
268
+					const range = this.range.find(item => (item[this.map.value] + '') === values)
269
+					if (range) {
270
+						detail = {
271
+							value: range[this.map.value],
272
+							data: range
273
+						}
274
+					}
275
+				}
276
+				// this.formItem && this.formItem.setValue(detail.value)
277
+				// TODO 兼容 vue2
278
+				this.$emit('input', detail.value);
279
+				// // TOTO 兼容 vue3
280
+				this.$emit('update:modelValue', detail.value);
281
+				this.$emit('change', {
282
+					detail
283
+				})
284
+				if (this.multiple) {
285
+					// 如果 v-model 没有绑定 ,则走内部逻辑
286
+					// if (this.value.length === 0) {
287
+					this.dataList = this.getDataList(detail.value, true)
288
+					// }
289
+				} else {
290
+					this.dataList = this.getDataList(detail.value)
291
+				}
292
+			},
293
+
294
+			/**
295
+			 * 获取渲染的新数组
296
+			 * @param {Object} value 选中内容
297
+			 */
298
+			getDataList(value) {
299
+				// 解除引用关系,破坏原引用关系,避免污染源数据
300
+				let dataList = JSON.parse(JSON.stringify(this.range))
301
+				let list = []
302
+				if (this.multiple) {
303
+					if (!Array.isArray(value)) {
304
+						value = []
305
+					}
306
+				}
307
+				dataList.forEach((item, index) => {
308
+					item.disabled = item.disable || item.disabled || false
309
+					if (this.multiple) {
310
+						if (value.length > 0) {
311
+							let have = value.find(val => val === item[this.map.value])
312
+							item.selected = have !== undefined
313
+						} else {
314
+							item.selected = false
315
+						}
316
+					} else {
317
+						item.selected = value === item[this.map.value]
318
+					}
319
+
320
+					list.push(item)
321
+				})
322
+				return this.setRange(list)
323
+			},
324
+			/**
325
+			 * 处理最大最小值
326
+			 * @param {Object} list
327
+			 */
328
+			setRange(list) {
329
+				let selectList = list.filter(item => item.selected)
330
+				let min = Number(this.min) || 0
331
+				let max = Number(this.max) || ''
332
+				list.forEach((item, index) => {
333
+					if (this.multiple) {
334
+						if (selectList.length <= min) {
335
+							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
336
+							if (have !== undefined) {
337
+								item.disabled = true
338
+							}
339
+						}
340
+
341
+						if (selectList.length >= max && max !== '') {
342
+							let have = selectList.find(val => val[this.map.value] === item[this.map.value])
343
+							if (have === undefined) {
344
+								item.disabled = true
345
+							}
346
+						}
347
+					}
348
+					this.setStyles(item, index)
349
+					list[index] = item
350
+				})
351
+				return list
352
+			},
353
+			/**
354
+			 * 设置 class
355
+			 * @param {Object} item
356
+			 * @param {Object} index
357
+			 */
358
+			setStyles(item, index) {
359
+				//  设置自定义样式
360
+				item.styleBackgroud = this.setStyleBackgroud(item)
361
+				item.styleIcon = this.setStyleIcon(item)
362
+				item.styleIconText = this.setStyleIconText(item)
363
+				item.styleRightIcon = this.setStyleRightIcon(item)
364
+			},
365
+
366
+			/**
367
+			 * 获取选中值
368
+			 * @param {Object} range
369
+			 */
370
+			getSelectedValue(range) {
371
+				if (!this.multiple) return this.dataValue
372
+				let selectedArr = []
373
+				range.forEach((item) => {
374
+					if (item.selected) {
375
+						selectedArr.push(item[this.map.value])
376
+					}
377
+				})
378
+				return this.dataValue.length > 0 ? this.dataValue : selectedArr
379
+			},
380
+
381
+			/**
382
+			 * 设置背景样式
383
+			 */
384
+			setStyleBackgroud(item) {
385
+				let styles = {}
386
+				let selectedColor = this.selectedColor?this.selectedColor:'#2979ff'
387
+				if (this.selectedColor) {
388
+					if (this.mode !== 'list') {
389
+						styles['border-color'] = item.selected?selectedColor:'#DCDFE6'
390
+					}
391
+					if (this.mode === 'tag') {
392
+						styles['background-color'] = item.selected? selectedColor:'#f5f5f5'
393
+					}
394
+				}
395
+				let classles = ''
396
+				for (let i in styles) {
397
+					classles += `${i}:${styles[i]};`
398
+				}
399
+				return classles
400
+			},
401
+			setStyleIcon(item) {
402
+				let styles = {}
403
+				let classles = ''
404
+				if (this.selectedColor) {
405
+					let selectedColor = this.selectedColor?this.selectedColor:'#2979ff'
406
+					styles['background-color'] = item.selected?selectedColor:'#fff'
407
+					styles['border-color'] = item.selected?selectedColor:'#DCDFE6'
408
+					
409
+					if(!item.selected && item.disabled){
410
+						styles['background-color'] = '#F2F6FC'
411
+						styles['border-color'] = item.selected?selectedColor:'#DCDFE6'
412
+					}
413
+				}
414
+				for (let i in styles) {
415
+					classles += `${i}:${styles[i]};`
416
+				}
417
+				return classles
418
+			},
419
+			setStyleIconText(item) {
420
+				let styles = {}
421
+				let classles = ''
422
+				if (this.selectedColor) {
423
+					let selectedColor = this.selectedColor?this.selectedColor:'#2979ff'
424
+					if (this.mode === 'tag') {
425
+						styles.color = item.selected?(this.selectedTextColor?this.selectedTextColor:'#fff'):'#666'
426
+					} else {
427
+						styles.color = item.selected?(this.selectedTextColor?this.selectedTextColor:selectedColor):'#666'
428
+					}
429
+					if(!item.selected && item.disabled){
430
+						styles.color = '#999'
431
+					}
432
+				}
433
+				for (let i in styles) {
434
+					classles += `${i}:${styles[i]};`
435
+				}
436
+				return classles
437
+			},
438
+			setStyleRightIcon(item) {
439
+				let styles = {}
440
+				let classles = ''
441
+				if (this.mode === 'list') {
442
+					styles['border-color'] = item.selected?this.styles.selectedColor:'#DCDFE6'
443
+				}
444
+				for (let i in styles) {
445
+					classles += `${i}:${styles[i]};`
446
+				}
447
+
448
+				return classles
449
+			}
450
+		}
451
+	}
452
+</script>
453
+
454
+<style lang="scss">
455
+	$uni-primary: #2979ff !default;
456
+	$border-color: #DCDFE6;
457
+	$disable:0.4;
458
+
459
+	@mixin flex {
460
+		/* #ifndef APP-NVUE */
461
+		display: flex;
462
+		/* #endif */
463
+	}
464
+
465
+	.uni-data-loading {
466
+		@include flex;
467
+		flex-direction: row;
468
+		justify-content: center;
469
+		align-items: center;
470
+		height: 36px;
471
+		padding-left: 10px;
472
+		color: #999;
473
+	}
474
+
475
+	.uni-data-checklist {
476
+		position: relative;
477
+		z-index: 0;
478
+		flex: 1;
479
+		// 多选样式
480
+		.checklist-group {
481
+			@include flex;
482
+			flex-direction: row;
483
+			flex-wrap: wrap;
484
+
485
+			&.is-list {
486
+				flex-direction: column;
487
+			}
488
+
489
+			.checklist-box {
490
+				@include flex;
491
+				flex-direction: row;
492
+				align-items: center;
493
+				position: relative;
494
+				margin: 5px 0;
495
+				margin-right: 25px;
496
+
497
+				.hidden {
498
+					position: absolute;
499
+					opacity: 0;
500
+				}
501
+
502
+				// 文字样式
503
+				.checklist-content {
504
+					@include flex;
505
+					flex: 1;
506
+					flex-direction: row;
507
+					align-items: center;
508
+					justify-content: space-between;
509
+					.checklist-text {
510
+						font-size: 14px;
511
+						color: #666;
512
+						margin-left: 5px;
513
+						line-height: 14px;
514
+					}
515
+
516
+					.checkobx__list {
517
+						border-right-width: 1px;
518
+						border-right-color: #007aff;
519
+						border-right-style: solid;
520
+						border-bottom-width:1px;
521
+						border-bottom-color: #007aff;
522
+						border-bottom-style: solid;
523
+						height: 12px;
524
+						width: 6px;
525
+						left: -5px;
526
+						transform-origin: center;
527
+						transform: rotate(45deg);
528
+						opacity: 0;
529
+					}
530
+				}
531
+
532
+				// 多选样式
533
+				.checkbox__inner {
534
+					/* #ifndef APP-NVUE */
535
+					flex-shrink: 0;
536
+					box-sizing: border-box;
537
+					/* #endif */
538
+					position: relative;
539
+					width: 16px;
540
+					height: 16px;
541
+					border: 1px solid $border-color;
542
+					border-radius: 4px;
543
+					background-color: #fff;
544
+					z-index: 1;
545
+					.checkbox__inner-icon {
546
+						position: absolute;
547
+						/* #ifdef APP-NVUE */
548
+						top: 2px;
549
+						/* #endif */
550
+						/* #ifndef APP-NVUE */
551
+						top: 1px;
552
+						/* #endif */
553
+						left: 5px;
554
+						height: 8px;
555
+						width: 4px;
556
+						border-right-width: 1px;
557
+						border-right-color: #fff;
558
+						border-right-style: solid;
559
+						border-bottom-width:1px ;
560
+						border-bottom-color: #fff;
561
+						border-bottom-style: solid;
562
+						opacity: 0;
563
+						transform-origin: center;
564
+						transform: rotate(40deg);
565
+					}
566
+				}
567
+
568
+				// 单选样式
569
+				.radio__inner {
570
+					@include flex;
571
+					/* #ifndef APP-NVUE */
572
+					flex-shrink: 0;
573
+					box-sizing: border-box;
574
+					/* #endif */
575
+					justify-content: center;
576
+					align-items: center;
577
+					position: relative;
578
+					width: 16px;
579
+					height: 16px;
580
+					border: 1px solid $border-color;
581
+					border-radius: 16px;
582
+					background-color: #fff;
583
+					z-index: 1;
584
+
585
+					.radio__inner-icon {
586
+						width: 8px;
587
+						height: 8px;
588
+						border-radius: 10px;
589
+						opacity: 0;
590
+					}
591
+				}
592
+
593
+				// 默认样式
594
+				&.is--default {
595
+
596
+					// 禁用
597
+					&.is-disable {
598
+						/* #ifdef H5 */
599
+						cursor: not-allowed;
600
+						/* #endif */
601
+						.checkbox__inner {
602
+							background-color: #F2F6FC;
603
+							border-color: $border-color;
604
+							/* #ifdef H5 */
605
+							cursor: not-allowed;
606
+							/* #endif */
607
+						}
608
+
609
+						.radio__inner {
610
+							background-color: #F2F6FC;
611
+							border-color: $border-color;
612
+						}
613
+						.checklist-text {
614
+							color: #999;
615
+						}
616
+					}
617
+
618
+					// 选中
619
+					&.is-checked {
620
+						.checkbox__inner {
621
+							border-color: $uni-primary;
622
+							background-color: $uni-primary;
623
+
624
+							.checkbox__inner-icon {
625
+								opacity: 1;
626
+								transform: rotate(45deg);
627
+							}
628
+						}
629
+						.radio__inner {
630
+							border-color: $uni-primary;
631
+							.radio__inner-icon {
632
+								opacity: 1;
633
+								background-color: $uni-primary;
634
+							}
635
+						}
636
+						.checklist-text {
637
+							color: $uni-primary;
638
+						}
639
+						// 选中禁用
640
+						&.is-disable {
641
+							.checkbox__inner {
642
+								opacity: $disable;
643
+							}
644
+
645
+							.checklist-text {
646
+								opacity: $disable;
647
+							}
648
+							.radio__inner {
649
+								opacity: $disable;
650
+							}
651
+						}
652
+					}
653
+				}
654
+
655
+				// 按钮样式
656
+				&.is--button {
657
+					margin-right: 10px;
658
+					padding: 5px 10px;
659
+					border: 1px $border-color solid;
660
+					border-radius: 3px;
661
+					transition: border-color 0.2s;
662
+
663
+					// 禁用
664
+					&.is-disable {
665
+						/* #ifdef H5 */
666
+						cursor: not-allowed;
667
+						/* #endif */
668
+						border: 1px #eee solid;
669
+						opacity: $disable;
670
+						.checkbox__inner {
671
+							background-color: #F2F6FC;
672
+							border-color: $border-color;
673
+							/* #ifdef H5 */
674
+							cursor: not-allowed;
675
+							/* #endif */
676
+						}
677
+						.radio__inner {
678
+							background-color: #F2F6FC;
679
+							border-color: $border-color;
680
+							/* #ifdef H5 */
681
+							cursor: not-allowed;
682
+							/* #endif */
683
+						}
684
+						.checklist-text {
685
+							color: #999;
686
+						}
687
+					}
688
+
689
+					&.is-checked {
690
+						border-color: $uni-primary;
691
+						.checkbox__inner {
692
+							border-color: $uni-primary;
693
+							background-color: $uni-primary;
694
+							.checkbox__inner-icon {
695
+								opacity: 1;
696
+								transform: rotate(45deg);
697
+							}
698
+						}
699
+
700
+						.radio__inner {
701
+							border-color: $uni-primary;
702
+
703
+							.radio__inner-icon {
704
+								opacity: 1;
705
+								background-color: $uni-primary;
706
+							}
707
+						}
708
+
709
+						.checklist-text {
710
+							color: $uni-primary;
711
+						}
712
+
713
+						// 选中禁用
714
+						&.is-disable {
715
+							opacity: $disable;
716
+						}
717
+					}
718
+				}
719
+
720
+				// 标签样式
721
+				&.is--tag {
722
+					margin-right: 10px;
723
+					padding: 5px 10px;
724
+					border: 1px $border-color solid;
725
+					border-radius: 3px;
726
+					background-color: #f5f5f5;
727
+
728
+					.checklist-text {
729
+						margin: 0;
730
+						color: #666;
731
+					}
732
+
733
+					// 禁用
734
+					&.is-disable {
735
+						/* #ifdef H5 */
736
+						cursor: not-allowed;
737
+						/* #endif */
738
+						opacity: $disable;
739
+					}
740
+
741
+					&.is-checked {
742
+						background-color: $uni-primary;
743
+						border-color: $uni-primary;
744
+
745
+						.checklist-text {
746
+							color: #fff;
747
+						}
748
+					}
749
+				}
750
+				// 列表样式
751
+				&.is--list {
752
+					/* #ifndef APP-NVUE */
753
+					display: flex;
754
+					/* #endif */
755
+					padding: 10px 15px;
756
+					padding-left: 0;
757
+					margin: 0;
758
+
759
+					&.is-list-border {
760
+						border-top: 1px #eee solid;
761
+					}
762
+
763
+					// 禁用
764
+					&.is-disable {
765
+						/* #ifdef H5 */
766
+						cursor: not-allowed;
767
+						/* #endif */
768
+						.checkbox__inner {
769
+							background-color: #F2F6FC;
770
+							border-color: $border-color;
771
+							/* #ifdef H5 */
772
+							cursor: not-allowed;
773
+							/* #endif */
774
+						}
775
+						.checklist-text {
776
+							color: #999;
777
+						}
778
+					}
779
+
780
+					&.is-checked {
781
+						.checkbox__inner {
782
+							border-color: $uni-primary;
783
+							background-color: $uni-primary;
784
+
785
+							.checkbox__inner-icon {
786
+								opacity: 1;
787
+								transform: rotate(45deg);
788
+							}
789
+						}
790
+						.radio__inner {
791
+							.radio__inner-icon {
792
+								opacity: 1;
793
+							}
794
+						}
795
+						.checklist-text {
796
+							color: $uni-primary;
797
+						}
798
+
799
+						.checklist-content {
800
+							.checkobx__list {
801
+								opacity: 1;
802
+								border-color: $uni-primary;
803
+							}
804
+						}
805
+
806
+						// 选中禁用
807
+						&.is-disable {
808
+							.checkbox__inner {
809
+								opacity: $disable;
810
+							}
811
+
812
+							.checklist-text {
813
+								opacity: $disable;
814
+							}
815
+						}
816
+					}
817
+				}
818
+			}
819
+		}
820
+	}
821
+</style>

+ 84
- 0
oa-ui-app/uni_modules/uni-data-checkbox/package.json Voir le fichier

@@ -0,0 +1,84 @@
1
+{
2
+  "id": "uni-data-checkbox",
3
+  "displayName": "uni-data-checkbox 数据选择器",
4
+  "version": "1.0.3",
5
+  "description": "通过数据驱动的单选框和复选框",
6
+  "keywords": [
7
+    "uni-ui",
8
+    "checkbox",
9
+    "单选",
10
+    "多选",
11
+    "单选多选"
12
+],
13
+  "repository": "https://github.com/dcloudio/uni-ui",
14
+  "engines": {
15
+    "HBuilderX": "^3.1.1"
16
+  },
17
+  "directories": {
18
+    "example": "../../temps/example_temps"
19
+  },
20
+"dcloudext": {
21
+    "sale": {
22
+      "regular": {
23
+        "price": "0.00"
24
+      },
25
+      "sourcecode": {
26
+        "price": "0.00"
27
+      }
28
+    },
29
+    "contact": {
30
+      "qq": ""
31
+    },
32
+    "declaration": {
33
+      "ads": "无",
34
+      "data": "无",
35
+      "permissions": "无"
36
+    },
37
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
38
+    "type": "component-vue"
39
+  },
40
+  "uni_modules": {
41
+    "dependencies": ["uni-load-more","uni-scss"],
42
+    "encrypt": [],
43
+    "platforms": {
44
+      "cloud": {
45
+        "tcb": "y",
46
+        "aliyun": "y"
47
+      },
48
+      "client": {
49
+        "App": {
50
+          "app-vue": "y",
51
+          "app-nvue": "y"
52
+        },
53
+        "H5-mobile": {
54
+          "Safari": "y",
55
+          "Android Browser": "y",
56
+          "微信浏览器(Android)": "y",
57
+          "QQ浏览器(Android)": "y"
58
+        },
59
+        "H5-pc": {
60
+          "Chrome": "y",
61
+          "IE": "y",
62
+          "Edge": "y",
63
+          "Firefox": "y",
64
+          "Safari": "y"
65
+        },
66
+        "小程序": {
67
+          "微信": "y",
68
+          "阿里": "y",
69
+          "百度": "y",
70
+          "字节跳动": "y",
71
+          "QQ": "y"
72
+        },
73
+        "快应用": {
74
+          "华为": "u",
75
+          "联盟": "u"
76
+        },
77
+        "Vue": {
78
+            "vue2": "y",
79
+            "vue3": "y"
80
+        }
81
+      }
82
+    }
83
+  }
84
+}

+ 18
- 0
oa-ui-app/uni_modules/uni-data-checkbox/readme.md Voir le fichier

@@ -0,0 +1,18 @@
1
+
2
+
3
+## DataCheckbox 数据驱动的单选复选框
4
+> **组件名:uni-data-checkbox**
5
+> 代码块: `uDataCheckbox`
6
+
7
+
8
+本组件是基于uni-app基础组件checkbox的封装。本组件要解决问题包括:
9
+
10
+1. 数据绑定型组件:给本组件绑定一个data,会自动渲染一组候选内容。再以往,开发者需要编写不少代码实现类似功能
11
+2. 自动的表单校验:组件绑定了data,且符合[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)组件的表单校验规范,搭配使用会自动实现表单校验
12
+3. 本组件合并了单选多选
13
+4. 本组件有若干风格选择,如普通的单选多选框、并列button风格、tag风格。开发者可以快速选择需要的风格。但作为一个封装组件,样式代码虽然不用自己写了,却会牺牲一定的样式自定义性
14
+
15
+在uniCloud开发中,`DB Schema`中配置了enum枚举等类型后,在web控制台的[自动生成表单](https://uniapp.dcloud.io/uniCloud/schema?id=autocode)功能中,会自动生成``uni-data-checkbox``组件并绑定好data
16
+
17
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox)
18
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 66
- 0
oa-ui-app/uni_modules/uni-data-picker/changelog.md Voir le fichier

@@ -0,0 +1,66 @@
1
+## 1.0.8(2022-09-16)
2
+- 可以使用 uni-scss 控制主题色
3
+## 1.0.7(2022-07-06)
4
+- 优化 pc端图标位置不正确的问题
5
+## 1.0.6(2022-07-05)
6
+- 优化 显示样式
7
+## 1.0.5(2022-07-04)
8
+- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
9
+## 1.0.4(2022-04-19)
10
+- 修复 字节小程序 本地数据无法选择下一级的Bug
11
+## 1.0.3(2022-02-25)
12
+- 修复 nvue 不支持的 v-show 的 bug
13
+## 1.0.2(2022-02-25)
14
+- 修复 条件编译 nvue 不支持的 css 样式
15
+## 1.0.1(2021-11-23)
16
+- 修复 由上个版本引发的map、v-model等属性不生效的bug
17
+## 1.0.0(2021-11-19)
18
+- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
19
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
20
+## 0.4.9(2021-10-28)
21
+- 修复 VUE2 v-model 概率无效的 bug
22
+## 0.4.8(2021-10-27)
23
+- 修复 v-model 概率无效的 bug
24
+## 0.4.7(2021-10-25)
25
+- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+
26
+- 修复 树型 uniCloud 数据类型为 int 时报错的 bug
27
+## 0.4.6(2021-10-19)
28
+- 修复 非 VUE3 v-model 为 0 时无法选中的 bug
29
+## 0.4.5(2021-09-26)
30
+- 新增 清除已选项的功能(通过 clearIcon 属性配置是否显示按钮),同时提供 clear 方法以供调用,二者等效
31
+- 修复 readonly 为 true 时报错的 bug
32
+## 0.4.4(2021-09-26)
33
+- 修复 上一版本造成的 map 属性失效的 bug
34
+- 新增 ellipsis 属性,支持配置 tab 选项长度过长时是否自动省略
35
+## 0.4.3(2021-09-24)
36
+- 修复 某些情况下级联未触发的 bug
37
+## 0.4.2(2021-09-23)
38
+- 新增 提供 show 和 hide 方法,开发者可以通过 ref 调用
39
+- 新增 选项内容过长自动添加省略号
40
+## 0.4.1(2021-09-15)
41
+- 新增 map 属性 字段映射,将 text/value 映射到数据中的其他字段
42
+## 0.4.0(2021-07-13)
43
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
44
+## 0.3.5(2021-06-04)
45
+- 修复 无法加载云端数据的问题
46
+## 0.3.4(2021-05-28)
47
+- 修复 v-model 无效问题
48
+- 修复 loaddata 为空数据组时加载时间过长问题
49
+- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点
50
+## 0.3.3(2021-05-12)
51
+- 新增 组件示例地址
52
+## 0.3.2(2021-04-22)
53
+- 修复 非树形数据有 where 属性查询报错的问题
54
+## 0.3.1(2021-04-15)
55
+- 修复 本地数据概率无法回显时问题
56
+## 0.3.0(2021-04-07)
57
+- 新增 支持云端非树形表结构数据
58
+- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题
59
+## 0.2.0(2021-03-15)
60
+- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题
61
+## 0.1.9(2021-03-09)
62
+- 修复 微信小程序某些情况下无法选择的问题
63
+## 0.1.8(2021-02-05)
64
+- 优化 部分样式在 nvue 上的兼容表现
65
+## 0.1.7(2021-02-05)
66
+- 调整为 uni_modules 目录规范

+ 45
- 0
oa-ui-app/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js Voir le fichier

@@ -0,0 +1,45 @@
1
+// #ifdef H5
2
+export default {
3
+  name: 'Keypress',
4
+  props: {
5
+    disable: {
6
+      type: Boolean,
7
+      default: false
8
+    }
9
+  },
10
+  mounted () {
11
+    const keyNames = {
12
+      esc: ['Esc', 'Escape'],
13
+      tab: 'Tab',
14
+      enter: 'Enter',
15
+      space: [' ', 'Spacebar'],
16
+      up: ['Up', 'ArrowUp'],
17
+      left: ['Left', 'ArrowLeft'],
18
+      right: ['Right', 'ArrowRight'],
19
+      down: ['Down', 'ArrowDown'],
20
+      delete: ['Backspace', 'Delete', 'Del']
21
+    }
22
+    const listener = ($event) => {
23
+      if (this.disable) {
24
+        return
25
+      }
26
+      const keyName = Object.keys(keyNames).find(key => {
27
+        const keyName = $event.key
28
+        const value = keyNames[key]
29
+        return value === keyName || (Array.isArray(value) && value.includes(keyName))
30
+      })
31
+      if (keyName) {
32
+        // 避免和其他按键事件冲突
33
+        setTimeout(() => {
34
+          this.$emit(keyName, {})
35
+        }, 0)
36
+      }
37
+    }
38
+    document.addEventListener('keyup', listener)
39
+    this.$once('hook:beforeDestroy', () => {
40
+      document.removeEventListener('keyup', listener)
41
+    })
42
+  },
43
+	render: () => {}
44
+}
45
+// #endif

+ 547
- 0
oa-ui-app/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue Voir le fichier

@@ -0,0 +1,547 @@
1
+<template>
2
+  <view class="uni-data-tree">
3
+    <view class="uni-data-tree-input" @click="handleInput">
4
+      <slot :options="options" :data="inputSelected" :error="errorMessage">
5
+        <view class="input-value" :class="{'input-value-border': border}">
6
+          <text v-if="errorMessage" class="selected-area error-text">{{errorMessage}}</text>
7
+          <view v-else-if="loading && !isOpened" class="selected-area">
8
+            <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
9
+          </view>
10
+          <scroll-view v-else-if="inputSelected.length" class="selected-area" scroll-x="true">
11
+            <view class="selected-list">
12
+              <view class="selected-item" v-for="(item,index) in inputSelected" :key="index">
13
+                <text class="text-color">{{item.text}}</text><text v-if="index<inputSelected.length-1"
14
+                  class="input-split-line">{{split}}</text>
15
+              </view>
16
+            </view>
17
+          </scroll-view>
18
+          <text v-else class="selected-area placeholder">{{placeholder}}</text>
19
+          <view v-if="clearIcon && !readonly && inputSelected.length" class="icon-clear" @click.stop="clear">
20
+            <uni-icons type="clear" color="#c0c4cc" size="24"></uni-icons>
21
+          </view>
22
+          <view class="arrow-area" v-if="(!clearIcon || !inputSelected.length) && !readonly ">
23
+            <view class="input-arrow"></view>
24
+          </view>
25
+        </view>
26
+      </slot>
27
+    </view>
28
+    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
29
+    <view class="uni-data-tree-dialog" v-if="isOpened">
30
+      <view class="uni-popper__arrow"></view>
31
+      <view class="dialog-caption">
32
+        <view class="title-area">
33
+          <text class="dialog-title">{{popupTitle}}</text>
34
+        </view>
35
+        <view class="dialog-close" @click="handleClose">
36
+          <view class="dialog-close-plus" data-id="close"></view>
37
+          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
38
+        </view>
39
+      </view>
40
+      <data-picker-view class="picker-view" ref="pickerView" v-model="dataValue" :localdata="localdata"
41
+        :preload="preload" :collection="collection" :field="field" :orderby="orderby" :where="where"
42
+        :step-searh="stepSearh" :self-field="selfField" :parent-field="parentField" :managed-mode="true" :map="map"
43
+        :ellipsis="ellipsis" @change="onchange" @datachange="ondatachange" @nodeclick="onnodeclick">
44
+      </data-picker-view>
45
+    </view>
46
+  </view>
47
+</template>
48
+
49
+<script>
50
+  import dataPicker from "../uni-data-pickerview/uni-data-picker.js"
51
+  import DataPickerView from "../uni-data-pickerview/uni-data-pickerview.vue"
52
+
53
+  /**
54
+   * DataPicker 级联选择
55
+   * @description 支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
56
+   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
57
+   * @property {String} popup-title 弹出窗口标题
58
+   * @property {Array} localdata 本地数据,参考
59
+   * @property {Boolean} border = [true|false] 是否有边框
60
+   * @property {Boolean} readonly = [true|false] 是否仅读
61
+   * @property {Boolean} preload = [true|false] 是否预加载数据
62
+   * @value true 开启预加载数据,点击弹出窗口后显示已加载数据
63
+   * @value false 关闭预加载数据,点击弹出窗口后开始加载数据
64
+   * @property {Boolean} step-searh = [true|false] 是否分布查询
65
+   * @value true 启用分布查询,仅查询当前选中节点
66
+   * @value false 关闭分布查询,一次查询出所有数据
67
+   * @property {String|DBFieldString} self-field 分布查询当前字段名称
68
+   * @property {String|DBFieldString} parent-field 分布查询父字段名称
69
+   * @property {String|DBCollectionString} collection 表名
70
+   * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
71
+   * @property {String} orderby 排序字段及正序倒叙设置
72
+   * @property {String|JQLString} where 查询条件
73
+   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
74
+   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
75
+   */
76
+  export default {
77
+    name: 'UniDataPicker',
78
+    emits: ['popupopened', 'popupclosed', 'nodeclick', 'input', 'change', 'update:modelValue'],
79
+    mixins: [dataPicker],
80
+    components: {
81
+      DataPickerView
82
+    },
83
+    props: {
84
+      options: {
85
+        type: [Object, Array],
86
+        default () {
87
+          return {}
88
+        }
89
+      },
90
+      popupTitle: {
91
+        type: String,
92
+        default: '请选择'
93
+      },
94
+      placeholder: {
95
+        type: String,
96
+        default: '请选择'
97
+      },
98
+      heightMobile: {
99
+        type: String,
100
+        default: ''
101
+      },
102
+      readonly: {
103
+        type: Boolean,
104
+        default: false
105
+      },
106
+      clearIcon: {
107
+        type: Boolean,
108
+        default: true
109
+      },
110
+      border: {
111
+        type: Boolean,
112
+        default: true
113
+      },
114
+      split: {
115
+        type: String,
116
+        default: '/'
117
+      },
118
+      ellipsis: {
119
+        type: Boolean,
120
+        default: true
121
+      }
122
+    },
123
+    data() {
124
+      return {
125
+        isOpened: false,
126
+        inputSelected: []
127
+      }
128
+    },
129
+    created() {
130
+      this.$nextTick(() => {
131
+        this.load();
132
+      })
133
+    },
134
+    methods: {
135
+      clear() {
136
+        this.modelValue = null;
137
+        this._dispatchEvent([]);
138
+      },
139
+      onPropsChange() {
140
+        this._treeData = [];
141
+        this.selectedIndex = 0;
142
+
143
+        this.load();
144
+      },
145
+      load() {
146
+        if (this.readonly) {
147
+          this._processReadonly(this.localdata, this.dataValue);
148
+          return;
149
+        }
150
+
151
+        if (!this.hasValue) {
152
+          return;
153
+        }
154
+
155
+        // 回显本地数据
156
+        if (this.isLocalData) {
157
+          this.loadData();
158
+          this.inputSelected = this.selected.slice(0);
159
+        } else if (this.isCloudDataList || this.isCloudDataTree) { // 回显 Cloud 数据
160
+          this.loading = true;
161
+          this.getCloudDataValue().then((res) => {
162
+            this.loading = false;
163
+            this.inputSelected = res;
164
+          }).catch((err) => {
165
+            this.loading = false;
166
+            this.errorMessage = err;
167
+          })
168
+        }
169
+      },
170
+      show() {
171
+        this.isOpened = true
172
+        setTimeout(() => {
173
+          this.$refs.pickerView.updateData({
174
+            treeData: this._treeData,
175
+            selected: this.selected,
176
+            selectedIndex: this.selectedIndex
177
+          })
178
+        }, 200)
179
+        this.$emit('popupopened')
180
+      },
181
+      hide() {
182
+        this.isOpened = false
183
+        this.$emit('popupclosed')
184
+      },
185
+      handleInput() {
186
+        if (this.readonly) {
187
+          return
188
+        }
189
+        this.show()
190
+      },
191
+      handleClose(e) {
192
+        this.hide()
193
+      },
194
+      onnodeclick(e) {
195
+        this.$emit('nodeclick', e)
196
+      },
197
+      ondatachange(e) {
198
+        this._treeData = this.$refs.pickerView._treeData
199
+      },
200
+      onchange(e) {
201
+        this.hide()
202
+        this.$nextTick(() => {
203
+          this.inputSelected = e;
204
+        })
205
+        this._dispatchEvent(e)
206
+      },
207
+      _processReadonly(dataList, value) {
208
+        var isTree = dataList.findIndex((item) => {
209
+          return item.children
210
+        })
211
+        if (isTree > -1) {
212
+          let inputValue
213
+          if (Array.isArray(value)) {
214
+            inputValue = value[value.length - 1]
215
+            if (typeof inputValue === 'object' && inputValue.value) {
216
+              inputValue = inputValue.value
217
+            }
218
+          } else {
219
+            inputValue = value
220
+          }
221
+          this.inputSelected = this._findNodePath(inputValue, this.localdata)
222
+          return
223
+        }
224
+
225
+        if (!this.hasValue) {
226
+          this.inputSelected = []
227
+          return
228
+        }
229
+
230
+        let result = []
231
+        for (let i = 0; i < value.length; i++) {
232
+          var val = value[i]
233
+          var item = dataList.find((v) => {
234
+            return v.value == val
235
+          })
236
+          if (item) {
237
+            result.push(item)
238
+          }
239
+        }
240
+        if (result.length) {
241
+          this.inputSelected = result
242
+        }
243
+      },
244
+      _filterForArray(data, valueArray) {
245
+        var result = []
246
+        for (let i = 0; i < valueArray.length; i++) {
247
+          var value = valueArray[i]
248
+          var found = data.find((item) => {
249
+            return item.value == value
250
+          })
251
+          if (found) {
252
+            result.push(found)
253
+          }
254
+        }
255
+        return result
256
+      },
257
+      _dispatchEvent(selected) {
258
+        let item = {}
259
+        if (selected.length) {
260
+          var value = new Array(selected.length)
261
+          for (var i = 0; i < selected.length; i++) {
262
+            value[i] = selected[i].value
263
+          }
264
+          item = selected[selected.length - 1]
265
+        } else {
266
+          item.value = ''
267
+        }
268
+        if (this.formItem) {
269
+          this.formItem.setValue(item.value)
270
+        }
271
+
272
+        this.$emit('input', item.value)
273
+        this.$emit('update:modelValue', item.value)
274
+        this.$emit('change', {
275
+          detail: {
276
+            value: selected
277
+          }
278
+        })
279
+      }
280
+    }
281
+  }
282
+</script>
283
+
284
+<style>
285
+  .uni-data-tree {
286
+    flex: 1;
287
+    position: relative;
288
+    font-size: 14px;
289
+  }
290
+
291
+  .error-text {
292
+    color: #DD524D;
293
+  }
294
+
295
+  .input-value {
296
+    /* #ifndef APP-NVUE */
297
+    display: flex;
298
+    /* #endif */
299
+    flex-direction: row;
300
+    align-items: center;
301
+    flex-wrap: nowrap;
302
+    font-size: 14px;
303
+    /* line-height: 35px; */
304
+    padding: 0 10px;
305
+    padding-right: 5px;
306
+    overflow: hidden;
307
+    height: 35px;
308
+    /* #ifndef APP-NVUE */
309
+    box-sizing: border-box;
310
+    /* #endif */
311
+  }
312
+
313
+  .input-value-border {
314
+    border: 1px solid #e5e5e5;
315
+    border-radius: 5px;
316
+  }
317
+
318
+  .selected-area {
319
+    flex: 1;
320
+    overflow: hidden;
321
+    /* #ifndef APP-NVUE */
322
+    display: flex;
323
+    /* #endif */
324
+    flex-direction: row;
325
+  }
326
+
327
+  .load-more {
328
+    /* #ifndef APP-NVUE */
329
+    margin-right: auto;
330
+    /* #endif */
331
+    /* #ifdef APP-NVUE */
332
+    width: 40px;
333
+    /* #endif */
334
+  }
335
+
336
+  .selected-list {
337
+    /* #ifndef APP-NVUE */
338
+    display: flex;
339
+    /* #endif */
340
+    flex-direction: row;
341
+    flex-wrap: nowrap;
342
+    /* padding: 0 5px; */
343
+  }
344
+
345
+  .selected-item {
346
+    flex-direction: row;
347
+    /* padding: 0 1px; */
348
+    /* #ifndef APP-NVUE */
349
+    white-space: nowrap;
350
+    /* #endif */
351
+  }
352
+
353
+  .text-color {
354
+    color: #333;
355
+  }
356
+
357
+  .placeholder {
358
+    color: grey;
359
+    font-size: 12px;
360
+  }
361
+
362
+  .input-split-line {
363
+    opacity: .5;
364
+  }
365
+
366
+  .arrow-area {
367
+    position: relative;
368
+    width: 20px;
369
+    /* #ifndef APP-NVUE */
370
+    margin-bottom: 5px;
371
+    margin-left: auto;
372
+    display: flex;
373
+    /* #endif */
374
+    justify-content: center;
375
+    transform: rotate(-45deg);
376
+    transform-origin: center;
377
+  }
378
+
379
+  .input-arrow {
380
+    width: 7px;
381
+    height: 7px;
382
+    border-left: 1px solid #999;
383
+    border-bottom: 1px solid #999;
384
+  }
385
+
386
+  .uni-data-tree-cover {
387
+    position: fixed;
388
+    left: 0;
389
+    top: 0;
390
+    right: 0;
391
+    bottom: 0;
392
+    background-color: rgba(0, 0, 0, .4);
393
+    /* #ifndef APP-NVUE */
394
+    display: flex;
395
+    /* #endif */
396
+    flex-direction: column;
397
+    z-index: 100;
398
+  }
399
+
400
+  .uni-data-tree-dialog {
401
+    position: fixed;
402
+    left: 0;
403
+    /* #ifndef APP-NVUE */
404
+    top: 20%;
405
+    /* #endif */
406
+    /* #ifdef APP-NVUE */
407
+    top: 200px;
408
+    /* #endif */
409
+    right: 0;
410
+    bottom: 0;
411
+    background-color: #FFFFFF;
412
+    border-top-left-radius: 10px;
413
+    border-top-right-radius: 10px;
414
+    /* #ifndef APP-NVUE */
415
+    display: flex;
416
+    /* #endif */
417
+    flex-direction: column;
418
+    z-index: 102;
419
+    overflow: hidden;
420
+    /* #ifdef APP-NVUE */
421
+    width: 750rpx;
422
+    /* #endif */
423
+  }
424
+
425
+  .dialog-caption {
426
+    position: relative;
427
+    /* #ifndef APP-NVUE */
428
+    display: flex;
429
+    /* #endif */
430
+    flex-direction: row;
431
+    /* border-bottom: 1px solid #f0f0f0; */
432
+  }
433
+
434
+  .title-area {
435
+    /* #ifndef APP-NVUE */
436
+    display: flex;
437
+    /* #endif */
438
+    align-items: center;
439
+    /* #ifndef APP-NVUE */
440
+    margin: auto;
441
+    /* #endif */
442
+    padding: 0 10px;
443
+  }
444
+
445
+  .dialog-title {
446
+    /* font-weight: bold; */
447
+    line-height: 44px;
448
+  }
449
+
450
+  .dialog-close {
451
+    position: absolute;
452
+    top: 0;
453
+    right: 0;
454
+    bottom: 0;
455
+    /* #ifndef APP-NVUE */
456
+    display: flex;
457
+    /* #endif */
458
+    flex-direction: row;
459
+    align-items: center;
460
+    padding: 0 15px;
461
+  }
462
+
463
+  .dialog-close-plus {
464
+    width: 16px;
465
+    height: 2px;
466
+    background-color: #666;
467
+    border-radius: 2px;
468
+    transform: rotate(45deg);
469
+  }
470
+
471
+  .dialog-close-rotate {
472
+    position: absolute;
473
+    transform: rotate(-45deg);
474
+  }
475
+
476
+  .picker-view {
477
+    flex: 1;
478
+    overflow: hidden;
479
+  }
480
+
481
+  .icon-clear {
482
+    display: flex;
483
+    align-items: center;
484
+  }
485
+
486
+  /* #ifdef H5 */
487
+  @media all and (min-width: 768px) {
488
+    .uni-data-tree-cover {
489
+      background-color: transparent;
490
+    }
491
+
492
+    .uni-data-tree-dialog {
493
+      position: absolute;
494
+      top: 55px;
495
+      height: auto;
496
+      min-height: 400px;
497
+      max-height: 50vh;
498
+      background-color: #fff;
499
+      border: 1px solid #EBEEF5;
500
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
501
+      border-radius: 4px;
502
+      overflow: unset;
503
+    }
504
+
505
+    .dialog-caption {
506
+      display: none;
507
+    }
508
+
509
+    .icon-clear {
510
+      /* margin-right: 5px; */
511
+    }
512
+  }
513
+
514
+  /* #endif */
515
+
516
+  /* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */
517
+  /* #ifndef APP-NVUE */
518
+  .uni-popper__arrow,
519
+  .uni-popper__arrow::after {
520
+    position: absolute;
521
+    display: block;
522
+    width: 0;
523
+    height: 0;
524
+    border-color: transparent;
525
+    border-style: solid;
526
+    border-width: 6px;
527
+  }
528
+
529
+  .uni-popper__arrow {
530
+    filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
531
+    top: -6px;
532
+    left: 10%;
533
+    margin-right: 3px;
534
+    border-top-width: 0;
535
+    border-bottom-color: #EBEEF5;
536
+  }
537
+
538
+  .uni-popper__arrow::after {
539
+    content: " ";
540
+    top: 1px;
541
+    margin-left: -6px;
542
+    border-top-width: 0;
543
+    border-bottom-color: #fff;
544
+  }
545
+
546
+  /* #endif */
547
+</style>

+ 0
- 0
oa-ui-app/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js Voir le fichier


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff

Loading…
Annuler
Enregistrer