王晓寒 8 months ago
parent
commit
48de3d5cd4
100 changed files with 12574 additions and 22 deletions
  1. +1
    -22
      SafeCampus.WEB/src/views/attendance/roolcall/detail.vue
  2. +27
    -0
      monitorMobile/.gitignore
  3. +24
    -0
      monitorMobile/App.vue
  4. +10
    -0
      monitorMobile/api/student/home/index.js
  5. +102
    -0
      monitorMobile/api/user.js
  6. +197
    -0
      monitorMobile/common/mixins.vue
  7. +58
    -0
      monitorMobile/common/setting.js
  8. +51
    -0
      monitorMobile/components/cell.vue
  9. +87
    -0
      monitorMobile/components/selectRadio.vue
  10. +180
    -0
      monitorMobile/components/selectSearch.vue
  11. +252
    -0
      monitorMobile/components/selectTree.vue
  12. +88
    -0
      monitorMobile/http/api.js
  13. +49
    -0
      monitorMobile/http/config.js
  14. +18
    -0
      monitorMobile/http/install.js
  15. +20
    -0
      monitorMobile/index.html
  16. +46
    -0
      monitorMobile/main.js
  17. +72
    -0
      monitorMobile/manifest.json
  18. +1416
    -0
      monitorMobile/package-lock.json
  19. +10
    -0
      monitorMobile/package.json
  20. +128
    -0
      monitorMobile/pages.json
  21. +53
    -0
      monitorMobile/pages/attendanceCall/index.vue
  22. +88
    -0
      monitorMobile/pages/attendanceCall/passengerFlow/add.vue
  23. +35
    -0
      monitorMobile/pages/attendanceCall/passengerFlow/detail.vue
  24. +173
    -0
      monitorMobile/pages/attendanceCall/passengerFlow/index.vue
  25. +137
    -0
      monitorMobile/pages/attendanceCall/returnBed/comfirm.vue
  26. +159
    -0
      monitorMobile/pages/attendanceCall/returnBed/detail.vue
  27. +188
    -0
      monitorMobile/pages/attendanceCall/returnBed/index.vue
  28. +22
    -0
      monitorMobile/pages/attendanceCall/rollCall/index.vue
  29. +690
    -0
      monitorMobile/pages/earlyWarning/index.vue
  30. +21
    -0
      monitorMobile/pages/home.vue
  31. +22
    -0
      monitorMobile/pages/my/index.vue
  32. BIN
      monitorMobile/static/image/add.png
  33. BIN
      monitorMobile/static/image/confirm.png
  34. BIN
      monitorMobile/static/image/earlyWarning/arrowRight.png
  35. BIN
      monitorMobile/static/image/earlyWarning/calendar.png
  36. BIN
      monitorMobile/static/image/earlyWarning/delete.png
  37. BIN
      monitorMobile/static/image/earlyWarning/detail.png
  38. BIN
      monitorMobile/static/image/earlyWarning/down.png
  39. BIN
      monitorMobile/static/image/earlyWarning/handle.png
  40. BIN
      monitorMobile/static/image/earlyWarning/handleDisabled.png
  41. BIN
      monitorMobile/static/image/earlyWarning/majorBack.png
  42. BIN
      monitorMobile/static/image/earlyWarning/screen.png
  43. BIN
      monitorMobile/static/image/earlyWarning/screenActive.png
  44. BIN
      monitorMobile/static/image/earlyWarning/warnBack.png
  45. BIN
      monitorMobile/static/image/earlyWarning/warnType.png
  46. BIN
      monitorMobile/static/image/earlyWarning/warnVideo.png
  47. BIN
      monitorMobile/static/image/home1.png
  48. BIN
      monitorMobile/static/image/peopleNum.png
  49. BIN
      monitorMobile/static/image/see.png
  50. BIN
      monitorMobile/static/image/tabbar/attendanceCall.png
  51. BIN
      monitorMobile/static/image/tabbar/earlyWarning_active.png
  52. BIN
      monitorMobile/static/image/tabbar/home.png
  53. BIN
      monitorMobile/static/image/tabbar/my.png
  54. BIN
      monitorMobile/static/image/test/test.png
  55. +30
    -0
      monitorMobile/store/$u.mixin.js
  56. +75
    -0
      monitorMobile/store/index.js
  57. +10
    -0
      monitorMobile/uni.promisify.adaptor.js
  58. +78
    -0
      monitorMobile/uni.scss
  59. +4
    -0
      monitorMobile/uni_modules/jp-select-plus/changelog.md
  60. BIN
      monitorMobile/uni_modules/jp-select-plus/components/jp-select-plus/arrow.png
  61. +682
    -0
      monitorMobile/uni_modules/jp-select-plus/components/jp-select-plus/jp-select-plus.vue
  62. +76
    -0
      monitorMobile/uni_modules/jp-select-plus/components/jp-select-plus/loading.vue
  63. +78
    -0
      monitorMobile/uni_modules/jp-select-plus/package.json
  64. +86
    -0
      monitorMobile/uni_modules/jp-select-plus/pages/index/index.vue
  65. +160
    -0
      monitorMobile/uni_modules/jp-select-plus/readme.md
  66. +160
    -0
      monitorMobile/uni_modules/uni-datetime-picker/changelog.md
  67. +177
    -0
      monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue
  68. +947
    -0
      monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue
  69. +22
    -0
      monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json
  70. +8
    -0
      monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js
  71. +22
    -0
      monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json
  72. +22
    -0
      monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json
  73. +940
    -0
      monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue
  74. +1057
    -0
      monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
  75. +421
    -0
      monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
  76. +88
    -0
      monitorMobile/uni_modules/uni-datetime-picker/package.json
  77. +21
    -0
      monitorMobile/uni_modules/uni-datetime-picker/readme.md
  78. +42
    -0
      monitorMobile/uni_modules/uni-icons/changelog.md
  79. +91
    -0
      monitorMobile/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
  80. +110
    -0
      monitorMobile/uni_modules/uni-icons/components/uni-icons/uni-icons.vue
  81. +664
    -0
      monitorMobile/uni_modules/uni-icons/components/uni-icons/uniicons.css
  82. BIN
      monitorMobile/uni_modules/uni-icons/components/uni-icons/uniicons.ttf
  83. +664
    -0
      monitorMobile/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
  84. +649
    -0
      monitorMobile/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
  85. +89
    -0
      monitorMobile/uni_modules/uni-icons/package.json
  86. +8
    -0
      monitorMobile/uni_modules/uni-icons/readme.md
  87. +8
    -0
      monitorMobile/uni_modules/uni-scss/changelog.md
  88. +1
    -0
      monitorMobile/uni_modules/uni-scss/index.scss
  89. +82
    -0
      monitorMobile/uni_modules/uni-scss/package.json
  90. +4
    -0
      monitorMobile/uni_modules/uni-scss/readme.md
  91. +7
    -0
      monitorMobile/uni_modules/uni-scss/styles/index.scss
  92. +3
    -0
      monitorMobile/uni_modules/uni-scss/styles/setting/_border.scss
  93. +66
    -0
      monitorMobile/uni_modules/uni-scss/styles/setting/_color.scss
  94. +55
    -0
      monitorMobile/uni_modules/uni-scss/styles/setting/_radius.scss
  95. +56
    -0
      monitorMobile/uni_modules/uni-scss/styles/setting/_space.scss
  96. +167
    -0
      monitorMobile/uni_modules/uni-scss/styles/setting/_styles.scss
  97. +24
    -0
      monitorMobile/uni_modules/uni-scss/styles/setting/_text.scss
  98. +146
    -0
      monitorMobile/uni_modules/uni-scss/styles/setting/_variables.scss
  99. +19
    -0
      monitorMobile/uni_modules/uni-scss/styles/tools/functions.scss
  100. +31
    -0
      monitorMobile/uni_modules/uni-scss/theme.scss

+ 1
- 22
SafeCampus.WEB/src/views/attendance/roolcall/detail.vue View File

@@ -13,15 +13,12 @@
<el-col :span="6">
<el-text class="mx-1" type="warning" size="large">趴桌子:{{ LieOnTable.length }}人</el-text></el-col
>
<el-col :span="6">
<el-text class="mx-1" type="info" size="large">未识别:{{ UnrecognizedD.length }}</el-text></el-col
>
</el-row>
</el-col>
</el-row>
</div>
<el-row :gutter="20">
<el-col :span="18"
<el-col :span="24"
><el-row class="rowbg">
<el-col :xl="4" :lg="4" :md="6" :sm="8" :xs="12" v-for="(item, index) in listData" :key="index"
><div class="grid-content">
@@ -49,24 +46,6 @@
>
</el-row></el-col
>
<el-col :span="6">
<div class="unrecognized">
<div class="title">未识别人员</div>
<ul>
<li class="imgBox" v-for="(item, index) in UnrecognizedD" :key="index">
<el-image
style="width: 80px; height: 80px"
v-if="item.snapshotUrl"
:src="item.snapshotUrl"
:preview-src-list="[item.snapshotUrl]"
:initial-index="4"
fit="cover"
/>
<el-button color="#626aef" size="small" @click="assignFn(item)">指派</el-button>
</li>
</ul>
</div>
</el-col>
</el-row>
<el-dialog v-model="visible" title="指派" width="830px" :before-close="handleClose">
<el-row class="rowbg">


+ 27
- 0
monitorMobile/.gitignore View File

@@ -0,0 +1,27 @@
.DS_Store
node_modules/
dist/
unpackage/
.hbuilderx/

npm-debug.log*
yarn-debug.log*
yarn-error.log*
**/*.log

tests/**/coverage/
tests/e2e/reports
selenium-debug.log

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.local
.env.development

package-lock.json
yarn.lock

+ 24
- 0
monitorMobile/App.vue View File

@@ -0,0 +1,24 @@
<script>
export default {
onLaunch: function() {
},
onShow: function() {
},
onHide: function() {
}
}
</script>

<style lang="scss">
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
@import "uview-ui/index.scss";
.uni-tabbar-bottom{
.uni-tabbar{
box-shadow: 0px -3px 9px 0px rgba(0,0,0,0.06), 0px 4px 4px 0px rgba(0,0,0,0.01);
}
}
uni-page-body{
height: 100%;
background-color: #F6F8FA;
}
</style>

+ 10
- 0
monitorMobile/api/student/home/index.js View File

@@ -0,0 +1,10 @@

import http from '@/http/api.js'
// 获取校历事件数据
export const getSchoolCalendarlist = (params) => {
return http.request({
url: '/api/blade-basic-data/semester/schoolCalendarlist',
method: 'get',
params
})
}

+ 102
- 0
monitorMobile/api/user.js View File

@@ -0,0 +1,102 @@
import http from '@/http/api.js'

// 获取token
const token = (tenantId, username, password, type) => {
return http.request({
url: '/api/blade-auth/oauth/token',
method: 'POST',
header: {
'Tenant-Id': tenantId
},
params: {
tenantId,
username,
password,
grant_type: "password",
scope: "all",
type
}
})
}
const getTenantId = (params) => {
return http.request({
url: '/api/blade-auth/oauth/getTenantId',
method: 'get',
params: {
...params
}
})
}

const refreshToken = (refresh_token, tenantId) => {
return http.request({
url: '/api/blade-auth/oauth/token',
method: 'post',
header: {
'Tenant-Id': tenantId
},
params: {
tenantId,
refresh_token,
grant_type: "refresh_token",
scope: "all",
}
})
}

// 获取用户信息
const userInfo = () => {
return http.request({
url: '/api/blade-user/info',
method: 'GET',
})
}

// 获取用户信息
export const getUser = (id) => {
return http.request({
url: '/api/blade-user/detail',
method: 'GET',
params: { id }
})
}
export const getUserInfo = () => {
return http.request({
url: '/api/blade-user/info',
method: 'get',
})
}
/* 修改用户信息 */
const updateInfo = (row) => {
return http.request({
url: '/api/blade-user/update-info',
method: 'post',
data: row
})
}
// 修改密码
const updatePassword = (data) => {
return http.request({
url: '/api/blade-user/update-password',
method: 'post',
params: data
})
}
// 修改密码
const passwordCheck = (data) => {
return http.request({
url: '/api/blade-user/passwordCheck',
method: 'post',
params: data
})
}

export default {
token,
userInfo,
refreshToken,
getTenantId,
updatePassword,
updateInfo,
passwordCheck
}

+ 197
- 0
monitorMobile/common/mixins.vue View File

@@ -0,0 +1,197 @@
<script>
import http from '@/http/api.js'
import {
options
} from '@/http/config.js';
import {
Base64
} from '@/utils/base64.js';
import {
clientId,
clientSecret
} from '@/common/setting'
export default{
methods:{
// 暂存一个跨页面变量 (与 this.GET_PARAM 成对使用)
SET_PARAM(val) {
this.SET_GLOBAL('pageParam', val)
},
// 获取之前暂存的跨页面变量 (与 this.SET_PARAM 成对使用)
GET_PARAM() {
return this.GET_GLOBAL('pageParam')
},
// 进入某个页面
NAV_TO(url, param, usePageParam) {
uni.navigateTo({
url: this.handleNav(url, param, usePageParam)
})
},
// 返回上个页面
// delta 参数为返回的次数
NAV_BACK(delta = 1) {
uni.navigateBack({
delta
})
},
// 跳转到某个页面,跳转后无法返回
JUMP_TO(url, param, usePageParam) {
uni.redirectTo({
url: this.handleNav(url, param, usePageParam)
})
},
// 转到某个 Tab 页
TAB_TO(url, param) {
uni.switchTab({
url: this.handleNav(url, param, true)
})
},
// 【内部方法】处理页面跳转 url 和参数
handleNav(url, param, usePageParam) {
let query = ''
if (param && usePageParam) {
this.SET_PARAM(param)
} else if (param && !usePageParam) {
query += '?' + Object.entries(param).filter(([k, v]) => k && v).map(([k, v]) => k + '=' + v).join('&')
}
return url + query
},
// 设置页面标题
SET_TITLE(title) {
uni.setNavigationBarTitle({
title
})
},
// 监听一个全局事件
ON(name, func) {
uni.$on(name, func)
},
// 仅单次监听一个全局事件
ONCE(name, func) {
uni.$once(name, func)
},
// 触发一个全局事件
EMIT(name, data) {
uni.$emit(name, data)
},
// 移除全局事件监听器
OFF(name, func) {
uni.$off(name, func)
},
// 二次确认提示框
CONFIRM(content='是否确认执行此操作?'){
return new Promise((resolve)=>{
uni.showModal({
title: '提示信息',
content: content,
cancelText: "取消",
confirmText: "确认",
confirmColor: '#F2C827',
cancelColor: '#9E9E9E',
success: function (res) {
if (res.confirm) {
resolve(true)
} else if (res.cancel) {
resolve(false)
}
}
});
})
},
TOAST(title){
uni.showToast({
icon: "none",
title,
duration: 2000,
});
},
UPLOAD_FILE(filePath){
let that = this
// 假设有token值需要在头部需要携带
let header = {}
let accessToken = uni.getStorageSync('accessToken');
if (accessToken) {
header['Blade-Auth'] = 'bearer ' + accessToken;
}
// 客户端认证参数
header['Authorization'] = 'Basic ' + Base64.encode(clientId + ':' + clientSecret);
console.log(filePath)
return new Promise(resovle=>{
uni.uploadFile({
url:options.baseURL + '/api/blade-resource/oss/endpoint/put-uplaod-file?bucketName=',
filePath,
name:'file',
header,
success(e){
if(e.statusCode == 200){
let res = JSON.parse(e.data)
if(res.code == 200){
resovle(res.data)
}else{
resovle(res.msg)
}
}else{
resovle(false)
}
},
fail(e){
console.log('fail',e)
resovle(false)
},
})
})
},
DELETE_FILE(attachIds){
return http.request({
url: '/api/blade-resource/oss/endpoint/remove-file-attachIds',
method: 'post',
params:{attachIds}
})
},
// 显示 loading 提示框
// title 为提示文字
// mask 为是否禁止点击
LOADING(title, mask = true) {
uni.showLoading({
title,
mask
})
},
// 停止展示 loading 提示框
HIDE_LOADING() {
uni.hideLoading()
},
// url获取文件流
DOWNLOAD_FILE(url){
return uni.downloadFile({
url
})
},
//复制链接
COPYLINK(item){
return new Promise((resolve)=>{
uni.setClipboardData({
data: item, // 要复制的路径
success: function(res) {
resolve(true)
// uni.getClipboardData({
// success: function(data) {
// resolve(true)
// },
// fail: function(data1) {
// resolve(false)
// }
// });
}
});
})
},
},
}
</script>

+ 58
- 0
monitorMobile/common/setting.js View File

@@ -0,0 +1,58 @@
/**
* 全局变量配置
*/
// #ifdef H5
let origin = window.location.origin
console.log(window.location.origin)
// #endif
module.exports = {
// 应用名
name: 'Rider',
// 应用logo,支持本地路径和网络路径
logo: '/static/images/icon/logo.png',
// 版本号
version: '2.0.0',
version: '2.0.1',
// H5接口Url
// #ifdef H5
devUrl: `${origin}/`,
prodUrl: `${origin}/`,
// #endif
// 小程序接口Url
// #ifndef H5
// devUrl: 'http://192.168.10.46',
devUrl: 'https://www.bjjyp.org.cn/rider',//开发环境接口Url
prodUrl: `https://www.bjjyp.org.cn/rider`,//线上环境接口Url
// prodUrl: 'http://192.168.100.236:1888',
// prodUrl: 'http://114.255.136.189:1888',
// #endif
// 后端数据的接收方式application/json;charset=UTF-8或者application/x-www-form-urlencoded;charset=UTF-8
contentType: 'application/json;charset=UTF-8',
// 后端返回状态码
codeName: 'code',
// 操作正常code
successCode: 200,
// 登录失效code
invalidCode: 401,
// 客户端ID
clientId: 'rider',
// 客户端密钥
clientSecret: 'rider_secret',
// token过期时间
tokenTime: 3000,
switchMode: true, // 是否开启部门切换模式
//本地
previewUrl: 'http://cp.qjkjedu.com/onlinePreview',
//金隅生产
// previewUrl: 'https://www.bjjyp.org.cn/preview/onlinePreview',
}

+ 51
- 0
monitorMobile/components/cell.vue View File

@@ -0,0 +1,51 @@
<template>
<u-cell :title="title" isLink :border="false" @click="click" :titleStyle="{fontSize:'28rpx'}">
<view v-if="multiple&&cellValue.length" slot="title" class="u-slot-title selectedBox">
<view v-for="(item,index) in cellValue" :key="index">
{{item}}
</view>
</view>
</u-cell>
</template>

<script>
export default {
name: "myCell",
props: {
title: {
default: "",
},
multiple: {
default: false,
},
cellValue: {
default: () => [],
}
},
methods: {
click() {
this.$emit("click")
}
}
}
</script>

<style scoped lang="scss">
.u-cell {
background: #fff;
border-radius: 20rpx;
}
.selectedBox{
display: flex;
flex-wrap: wrap;
>view{
display: inline-block;
background-color: #F2F8FF;
border-radius: 8rpx;
padding: 12rpx 18rpx;
margin: 6rpx;
font-size: 26rpx;
color: #000;
}
}
</style>

+ 87
- 0
monitorMobile/components/selectRadio.vue View File

@@ -0,0 +1,87 @@
<template>
<view>
<myCell v-show="cellVisible" :title="title_" isLink :border="false" @click="show = true"></myCell>
<u-popup :show="show" mode="center" :round="10" @close="close" @open="open">
<u-radio-group v-model="value_" iconPlacement="right" placement="column" @change="change" borderBottom>
<u-radio v-for="(item,index) in options" :key="index" :label="item.label" :name="item.value"></u-radio>
</u-radio-group>
</u-popup>
</view>
</template>

<script>
import myCell from "@/components/cell.vue"
export default {
name: "selectRadio",
components:{
myCell
},
props: {
value: {
default: "",
},
options: {
default: [],
type: Array
},
title:{
default: "",
},
cellVisible: {
default: true,
},
},
data() {
return {
show: false,
title_:this.title,
value_:this.value,
};
},
mounted() {
if(this.value){
let obj = this.options.find(e1=>e1.value == this.value)
if(obj) this.title_ = obj.label
}
},
methods: {
close() {
this.show = false
},
open(){
let obj = this.options.find(e1 => e1.value == this.value)
if (obj) this.title_ = obj.label
this.title_ = obj ? obj.label : this.title
this.value_ = this.value
},
change(e) {
this.$emit("update:value",e)
let obj = this.options.find(e1=>e1.value == e)
if(obj) this.title_ = obj.label
this.$emit("change")
},
}
}
</script>

<style scoped lang="scss">
.u-radio-group {
width: 550rpx;
max-height: 680rpx;
overflow-y: auto;
padding: 0 24rpx;
.u-cell {
background-color: #fff;
border-radius: 20rpx;
padding: 24rpx 0;
}
}

.u-border-bottom {
border-color: #F6F6F6 !important;
}

.u-radio {
margin-top: 18rpx;
}
</style>

+ 180
- 0
monitorMobile/components/selectSearch.vue View File

@@ -0,0 +1,180 @@
<template>
<view>
<myCell v-show="cellVisible" :multiple="multiple" :cellValue="cellValue" :title="title_" isLink :border="false" @click="show = true">
</myCell>
<u-popup :show="show" mode="bottom" :closeable="true" :round="10" @close="close" @open="open">
<view>
<view class="title">
{{popupTitle}}
</view>
<view v-if="filterable" style="padding: 0 30rpx 30rpx 30rpx">
<u-search v-model="searchText" :placeholder="searchPlaceholder" shape="round"
:showAction="false"></u-search>
</view>
<u-radio-group v-if="!multiple" :value="value_" iconPlacement="right" placement="column"
@change="change" borderBottom>
<u-radio v-show="item.label.includes(searchText)" v-for="(item,index) in options" :key="index"
:label="item.label" :name="item.value"></u-radio>
</u-radio-group>
<u-checkbox-group v-else v-model="value_" iconPlacement="right" placement="column" @change="change"
borderBottom>
<u-checkbox v-show="item.label.includes(searchText)" v-for="(item, index) in options" :key="index"
:label="item.label" :name="item.value">
</u-checkbox>
</u-checkbox-group>
<view style="padding: 36rpx 50rpx">
<u-button @click="cofirm" type="primary" style="border-radius: 36rpx;height: 72rpx;"
text="确定"></u-button>
</view>
</view>
</u-popup>
</view>
</template>

<script>
import myCell from "@/components/cell.vue"
export default {
name: "selectRadio",
components: {
myCell
},
props: {
value: {
default: "",
},
options: {
default: [],
type: Array
},
// 是否显示cell回显
cellVisible: {
default: true,
},
// cell回显默认文字
placeholder:{
default:'请选择'
},
// 弹框标题
popupTitle: {
default: "请选择",
type: String
},
// 是否显示搜索
filterable: {
default: true,
},
// 搜索框默认文字
searchPlaceholder: {
default: "请输入",
type: String
},
// 单选时候cell回显的文字
title: {
default: "",
},
// 是否多选
multiple: {
default: false,
},
},
data() {
return {
show: false,
title_: this.title||this.placeholder,
value_: this.value,
gruopValue: '',
searchText: '',
cellValue:[],
};
},
mounted() {
if (this.multiple) this.gruopValue = []
if (!this.multiple) {
let obj = this.options.find(e1 => e1.value == this.value)
if (obj) this.title_ = obj.label
} else {
let arr = this.options.filter(e1 => this.value.includes(e1.value))
this.cellValue = arr.map(e => e.label)
}
},
methods: {
close() {
this.show = false
},
open() {
if (this.multiple) this.gruopValue = []
if (!this.multiple) {
let obj = this.options.find(e1 => e1.value == this.value)
if (obj) this.title_ = obj.label
} else {
let arr = this.options.filter(e1 => this.value.includes(e1.value))
this.cellValue = arr.map(e => e.label)
}
this.value_ = this.value
this.searchText = ''
},
change(e) {
this.gruopValue = e
},
cofirm() {
this.$emit("update:value", this.gruopValue)
this.$emit("change", this.gruopValue)
if (!this.multiple) {
let obj = this.options.find(e1 => e1.value == this.gruopValue)
if (obj) this.title_ = obj.label
} else {
let arr = this.options.filter(e1 => this.gruopValue.includes(e1.value))
this.cellValue = arr.map(e => e.label)
}
this.close()
},
}
}
</script>

<style scoped lang="scss">
.title {
color: #000000;
font-size: 32rpx;
text-align: center;
line-height: 100rpx;
}

.u-radio-group {
width: 92%;
max-height: 680rpx;
overflow-y: auto;
padding: 0 30rpx;

.u-cell {
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
padding: 24rpx 0;
}
}

.u-checkbox-group {
width: 92%;
max-height: 680rpx;
overflow-y: auto;
padding: 0 30rpx;

.u-cell {
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
padding: 24rpx 0;
}
}

.u-border-bottom {
border-color: #F6F6F6 !important;
}

.u-radio {
margin-top: 18rpx;
}

.u-checkbox {
margin-top: 18rpx;
}
</style>

+ 252
- 0
monitorMobile/components/selectTree.vue View File

@@ -0,0 +1,252 @@
<template>
<view>
<myCell v-show="cellVisible" :title="title" isLink :border="false" @click="show = true"></myCell>
<u-popup :show="show" mode="bottom" :closeable="true" :round="10" @close="close" @open="open">
<view class="title">
{{popupTitle}}
</view>
<view>
<u-tabs :list="tabsList" :current="tabIndex" @change="tabsChange" :activeStyle="{
color: '#000000',
}" itemStyle="height:84rpx;width:33.33%;box-sizing:border-box;background:#fff;border-top:1rpx solid rgba(0,0,0,0.03)"></u-tabs>
<view v-for="(item) in tabsList" :key="item.value">
<template v-if="tabIndex == item.value">
<u-radio-group v-model="selectValue" iconPlacement="right" placement="column" @change="change"
borderBottom>
<u-radio v-for="(item,index) in selectOptions" :key="index" :label="item.label"
:name="item.value"></u-radio>
</u-radio-group>
</template>
</view>
<view style="padding: 36rpx 50rpx">
<u-button @click="cofirm" type="primary" style="border-radius: 36rpx;height: 72rpx;"
text="确定"></u-button>
</view>
</view>
</u-popup>
</view>
</template>

<script>
import myCell from "@/components/cell.vue"
export default {
name: "selectRadio",
components: {
myCell
},
props: {
value: {
default: () => [],
type: Array
},
labels: {
default: () => [],
type: Array
},
placeholder: {
default: '请选择'
},
popupTitle: {
default: "请选择",
type: String
},
cellVisible: {
default: true,
},
},
data() {
return {
show: false,
title: this.labels.join('/') || this.placeholder,
tabsList: [{
name: "系部",
cate:"系部",
value: 0,
disabled: false,
list: [{
value: 222,
label: '信息系'
}, {
value: 333,
label: '金融系'
}]
},
{
name: "专业",
cate:"专业",
value: 1,
disabled: true,
list: [{
value: 222,
label: '计算机应用'
}, {
value: 333,
label: '土木工程'
}]
},
{
name: "班级",
cate:"班级",
value: 2,
disabled: true,
list: [{
value: 222,
label: '1班'
}, {
value: 333,
label: '2班'
}]
},
],
tabIndex: 0,
selectValue: null,
selectOptions: [],

selectValues: this.value,
selectLabels: [],
};
},
mounted() {
// 获取第一个tab的selectOptions
},
methods: {
close() {
this.show = false
},
// 打开选择弹框
open() {
this.selectValues = this.value || []
this.title = this.labels.join('/') || this.placeholder
if(!this.selectValues.length){
// 展示tabs第一个数据
this.tabIndex = 0
}else{
// 展示tabs最后一个数据
this.tabIndex = 2
}
this.setSelectOptions()
this.show = true
},
// 设置单选列表数据
setSelectOptions(){
switch(this.tabIndex){
case 0:
this.selectOptions = this.tabsList[0].list
break
case 1:
this.selectOptions = this.tabsList[1].list
break
case 2:
this.selectOptions = this.tabsList[2].list
break
}
},
// 单选改变
change(e) {
// 赋值
this.selectValues[this.tabIndex] = e
let obj = this.selectOptions.find(e1 => e1.value == e)
this.selectLabels[this.tabIndex] = obj.label
// 切换tab
if (this.tabIndex < this.tabsList.length - 1) {
let nextItem = this.tabsList[this.tabIndex + 1]
this.tabsChange(nextItem)
}
if(this.tabIndex == this.tabsList.length - 1){
this.tabsList[this.tabIndex].name = obj.label
}
},
// 切换tab
tabsChange(item) {
console.log(1)
if (this.tabIndex == item.value) return
this.tabIndex = item.value
setTimeout(() => {
this.setSelectOptions()
this.selectValue = null
this.initTabs()
}, 150)
},
// 初始化tab数据
initTabs() {
for (let item of this.tabsList) {
if (item.value > this.tabIndex) {
item.disabled = true
this.selectValues[item.value] = ''
this.selectLabels[item.value] = ''
} else if (item.value < this.tabIndex) {
item.disabled = false
} else {
item.disabled = false
this.selectValues[item.value] = ''
this.selectLabels[item.value] = ''
}
item.name = this.selectLabels[item.value]||item.cate
}
},
// 确定
cofirm() {
if (this.selectValues[2]) {
this.$emit("input", this.selectValues)
this.$emit("update:labels", this.selectLabels)
this.$emit("change", this.selectValues)
this.title = this.selectLabels.join('/')
this.close()
}else{
this.$emit("input", [])
this.$emit("update:labels", [])
this.$emit("change", [])
this.title = this.placeholder
this.close()
}
},
}
}
</script>

<style scoped lang="scss">
.title {
color: #000000;
font-size: 32rpx;
text-align: center;
line-height: 100rpx;
}

.u-radio-group {
width: 92%;
max-height: 680rpx;
overflow-y: auto;
padding: 0 30rpx;

.u-cell {
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
padding: 24rpx 0;
}
}

.u-checkbox-group {
width: 92%;
max-height: 680rpx;
overflow-y: auto;
padding: 0 30rpx;

.u-cell {
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
padding: 24rpx 0;
}
}

.u-border-bottom {
border-color: #F6F6F6 !important;
}

.u-radio {
margin-top: 18rpx;
}

.u-checkbox {
margin-top: 18rpx;
}
</style>

+ 88
- 0
monitorMobile/http/api.js View File

@@ -0,0 +1,88 @@
import {
devUrl,
clientId,
clientSecret
} from '@/common/setting'
import {
options
} from '@/http/config.js';
import {
Base64
} from '@/utils/base64.js';
import Request from '@/utils/luch-request/index.js';
const http = new Request(options);
http.interceptors.request.use((config) => { // 可使用async await 做异步操作
// 假设有token值需要在头部需要携带
let accessToken = uni.getStorageSync('accessToken');
if (accessToken) {
config.header['Blade-Auth'] = 'bearer ' + accessToken;
}
// 客户端认证参数
config.header['Authorization'] = 'Basic ' + Base64.encode(clientId + ':' + clientSecret);
// #ifndef H5
let url = config.url
if (process.env.NODE_ENV == 'development' && !url.startsWith("http")) {
// url = url.substring(url.indexOf('/api') + 4)
config.url = url
}
// #endif

// 额外参数
// config.data = config.data || {};
// config.data.pf = uni.getSystemInfoSync().platform;
// config.data.sys = uni.getSystemInfoSync().system;

// 演示custom 用处
// if (config.custom.auth) {
// config.header.token = 'token'
// }
// if (config.custom.loading) {
// uni.showLoading()
// }
/**
/* 演示
if (!token) { // 如果token不存在,return Promise.reject(config) 会取消本次请求
return Promise.reject(config)
}
**/
return config
}, config => { // 可使用async await 做异步操作
return Promise.reject(config)
})
http.interceptors.response.use((response) => {
// 若有数据返回则通过
if (response.data.access_token || response.data.key) {
return response.data
}
// 服务端返回的状态码不等于200,则reject()
if (response.data.code && response.data.code !== 200) {
setTimeout(()=>{
uni.showToast({
title: response.data.msg,
icon: 'none'
});
})
return Promise.reject(response);
}
return response.data;
}, (response) => {
/* 对响应错误做点什么 (statusCode !== 200)*/
setTimeout(()=>{
uni.showToast({
title: response.data.msg || response.data.error_description || '网络错误',
icon: 'none'
});
})
if (response.statusCode == 401) {
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
uni.redirectTo({
url: `/pages/login/login?redirect=/${currentPage.route}`
})
}
return Promise.reject(response)
})
export default http;

+ 49
- 0
monitorMobile/http/config.js View File

@@ -0,0 +1,49 @@
import {
devUrl,
prodUrl,
contentType
} from '@/common/setting'
console.log('--',process.env.NODE_ENV)
var options = {
baseURL: process.env.NODE_ENV === 'development' ? devUrl : prodUrl,
header: {
'Content-Type': contentType
},
method: 'POST',
dataType: 'json',
// #ifndef MP-ALIPAY || APP-PLUS
responseType: 'text',
// #endif
// 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
custom: {}, // 全局自定义参数默认值
// #ifdef MP-ALIPAY || MP-WEIXIN
timeout: 30000,
// #endif
// #ifdef APP-PLUS
sslVerify: true,
// #endif
// #ifdef H5
// 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
//withCredentials: false,
// #endif
// #ifdef APP-PLUS
firstIpv4: false, // DNS解析时优先使用ipv4 仅 App-Android 支持 (HBuilderX 2.8.0+)
// #endif
// 局部优先级高于全局,返回当前请求的task,options。请勿在此处修改options。非必填
// getTask: (task, options) => {
// 相当于设置了请求超时时间500ms
// setTimeout(() => {
// task.abort()
// }, 500)
// },
// 全局自定义验证器。参数为statusCode 且必存在,不用判断空情况。
// validateStatus: (statusCode) => { // statusCode 必存在。此处示例为全局默认配置
// return statusCode >= 200 && statusCode < 300
// }
// 预览地址
// previewUrl: 'https://www.bjjyp.org.cn/preview/onlinePreview',
// previewUrl: 'http://114.255.136.189:6696/onlinePreview',
// previewUrl: 'http://192.168.100.236:85/onlinePreview',
previewUrl: 'http://cp.qjkjedu.com/onlinePreview',
};
export { options };

+ 18
- 0
monitorMobile/http/install.js View File

@@ -0,0 +1,18 @@
// 获取api目录所有js文件
const files = require.context('@/api', false, /\.js$/)
// 此处第二个参数vm,就是我们在页面使用的this,可以通过vm获取vuex等操作
const install = (Vue, vm) => {
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api下(因为vm就是this,也即this.$u.api)
// 自动将所有api挂载到vm.$u.api中
vm.$u.api = {}
files.keys().forEach(key => {
const api = files(key).default
for (let item in api) {
vm.$u.api[item] = api[item]
}
})
}

export default {
install
}

+ 20
- 0
monitorMobile/index.html View File

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

+ 46
- 0
monitorMobile/main.js View File

@@ -0,0 +1,46 @@
import App from './App'
import Vue from 'vue'
import store from '@/store';
import mixins from '@/common/mixins.vue'

Vue.mixin(mixins)

// 引入vuex
Vue.prototype.$u = {}
const vuexStore = require("@/store/$u.mixin.js");
Vue.mixin(vuexStore);

// 引入uview-ui
import uView from "uview-ui";
Vue.use(uView);

// #ifndef VUE3
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif

// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif

// 接口集中管理
import httpInstall from '@/http/install.js'
Vue.use(httpInstall, app)

import http from '@/http/api.js'
Vue.prototype.$http = http

// 公共函数
import globalFunc from '@/utils/func.js'
Vue.use(globalFunc, app);

+ 72
- 0
monitorMobile/manifest.json View File

@@ -0,0 +1,72 @@
{
"name" : "monitorMobile",
"appid" : "",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* 模块配置 */
"modules" : {},
/* 应用发布信息 */
"distribute" : {
/* android打包配置 */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios打包配置 */
"ios" : {},
/* SDK配置 */
"sdkConfigs" : {}
}
},
/* 快应用特有相关 */
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
}

+ 1416
- 0
monitorMobile/package-lock.json
File diff suppressed because it is too large
View File


+ 10
- 0
monitorMobile/package.json View File

@@ -0,0 +1,10 @@
{
"dependencies": {
"uview-ui": "^2.0.36",
"vuex": "^3.6.2"
},
"devDependencies": {
"sass": "^1.77.8",
"sass-loader": "^10.5.2"
}
}

+ 128
- 0
monitorMobile/pages.json View File

@@ -0,0 +1,128 @@
{
"easycom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
},
"tabBar":{
"color":"#777777",
"selectedColor":"#2388FF",
"backgroundColor":"#FFFFFF",
"borderStyle":"white",
"fontSize":"18rpx",
"list": [
{
"pagePath": "pages/home",
"iconPath": "/static/image/tabbar/home.png",
"selectedIconPath": "/static/image/tabbar/home.png",
"text": "首页"
},
{
"pagePath": "pages/attendanceCall/index",
"iconPath": "/static/image/tabbar/attendanceCall.png",
"selectedIconPath": "/static/image/tabbar/attendanceCall.png",
"text": "考勤点名"
},
{
"pagePath": "pages/earlyWarning/index",
"iconPath": "/static/image/tabbar/earlyWarning_active.png",
"selectedIconPath": "/static/image/tabbar/earlyWarning_active.png",
"text": "预警巡警"
},
{
"pagePath": "pages/my/index",
"iconPath": "/static/image/tabbar/my.png",
"selectedIconPath": "/static/image/tabbar/my.png",
"text": "我的"
}
]
},
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
// 首页
{
"path": "pages/home",
"style": {
"navigationBarTitleText": "首页"
}
},
// 考勤点名
{
"path": "pages/attendanceCall/index",
"style": {
"navigationBarTitleText": "考勤点名",
"enablePullDownRefresh": true
}
},
// 归寝
{
"path" : "pages/attendanceCall/returnBed/detail",
"style" :
{
"navigationBarTitleText": "查看详情",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/attendanceCall/returnBed/comfirm",
"style" :
{
"navigationBarTitleText": "归寝确认",
"enablePullDownRefresh": false
}
},
// 客流
{
"path" : "pages/attendanceCall/passengerFlow/detail",
"style" :
{
"navigationBarTitleText": "分片详情",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/attendanceCall/passengerFlow/add",
"style" :
{
"navigationBarTitleText": "新增查询",
"enablePullDownRefresh": false
}
},
// {
// "path": "pages/attendanceCall/rollCall/index",
// "style": {
// "navigationBarTitleText": "点名"
// }
// },
// {
// "path": "pages/attendanceCall/returnBed/index",
// "style": {
// "navigationBarTitleText": "归寝"
// }
// },
// {
// "path": "pages/attendanceCall/passengerFlow/index",
// "style": {
// "navigationBarTitleText": "客流"
// }
// },
// 预警巡警
{
"path": "pages/earlyWarning/index",
"style": {
"navigationStyle": "custom"
}
},
// 我的
{
"path": "pages/my/index",
"style": {
"navigationBarTitleText": "我的"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "校园监控预警平台",
"navigationBarBackgroundColor": "#fff",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}

+ 53
- 0
monitorMobile/pages/attendanceCall/index.vue View File

@@ -0,0 +1,53 @@
<template>
<view style="height: 100%;">
<u-tabs :list="tabsList" @click="tabsClick" :activeStyle="{
color: '#000000',
}" itemStyle="height:84rpx;width:33.33%;box-sizing:border-box;background:#fff;border-top:1rpx solid rgba(0,0,0,0.03)"></u-tabs>
<view style="height: calc(100% - 84rpx);">
<component :is="componentName" ref="pageComponent"/>
</view>
</view>
</template>

<script>
import passengerFlow from "./passengerFlow/index.vue"
import returnBed from "./returnBed/index.vue"
import rollCall from "./rollCall/index.vue"
export default {
components:{
passengerFlow,returnBed,rollCall
},
data() {
return {
tabsList: [{
name: "点名",
value: 'rollCall'
},
{
name: "归寝",
value: 'returnBed'
},
{
name: "客流",
value: 'passengerFlow'
},
],
componentName:'rollCall'
}
},
methods: {
tabsClick(item) {
this.componentName = item.value
}
},
onPullDownRefresh(){
this.$refs['pageComponent'].pullDownRefresh()
uni.stopPullDownRefresh()
}
}
</script>

<style>

</style>

+ 88
- 0
monitorMobile/pages/attendanceCall/passengerFlow/add.vue View File

@@ -0,0 +1,88 @@
<template>
<view style="padding-top: 30rpx;">
<view class="whiteCard">
<u--form labelPosition="top" :labelStyle="{fontSize:'32rpx',color:'#666'}" labelWidth="200" :model="form" :rules="rules" ref="uForm">
<u-form-item label="摄像头(多选)" prop="name" borderBottom>
<view
style="width: 160%;margin-left: -30rpx;margin-right: -30rpx;margin-bottom: -20rpx;margin-top: -10rpx;">
<selectSearch :value.sync="form.shexiangtou"
:options="[{value:1,label:'走廊尽头(海康)'},{value:2,label:'厨房(海康)'},{value:3,label:'走廊尽头(海康)'},{value:4,label:'厨房(海康)'}]"
placeholder="请选择摄像头" :filterable="false" multiple />
</view>
</u-form-item>
<u-form-item label="查询时间段" prop="timeslot" borderBottom>
<uni-datetime-picker v-model="form.tick" type="datetimerange">
<view class="demo-layout">
<view>
{{form.tick.length?form.tick.join('-'):'请选择'}}
</view>
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/calendar.png" mode=""></image>
</view>
</uni-datetime-picker>
</u-form-item>
<u-form-item label="系部/专业/班级" prop="timeslot" borderBottom>
<view
style="width: 160%;margin-left: -30rpx;margin-right: -30rpx;margin-bottom: -20rpx;margin-top: -10rpx;">
<selectTree v-model="form.departCalss" :labels.sync="form.departCalssName"/>
</view>
</u-form-item>
<u-form-item labelPosition="left" label="分片类型(天/小时)" prop="timeslot" borderBottom>
<u-radio-group v-model="form.type">
<u-radio v-for="(item,index) in [{value:'1',label:'天'},{value:'2',label:'小时'}]" :key="index" :label="item.label"
:name="item.value"></u-radio>
</u-radio-group>
</u-form-item>
</u--form>
</view>
</view>
</template>

<script>
import selectSearch from "@/components/selectSearch.vue"
import selectTree from "@/components/selectTree.vue"
export default {
components: {
selectSearch,
selectTree
},
data() {
return {
form: {
shexiangtou: [],
tick: [],
},
rules: []
}
},
methods: {}
}
</script>

<style scoped lang="scss">
.whiteCard {
padding: 30rpx 30rpx;
margin: 15rpx 30rpx;
border-radius: 18rpx;
background-color: #ffffff;
font-size: 32rpx;
}
.demo-layout{
display: flex;
padding: 15rpx 0;
justify-content: space-between;
align-items: center;
&:first-child{
flex: 1;
padding-right:30rpx;
}
}
.u-radio-group{
&>*:first-child{
margin-right: 36rpx;
}
}
</style>

+ 35
- 0
monitorMobile/pages/attendanceCall/passengerFlow/detail.vue View File

@@ -0,0 +1,35 @@
<template>
<view>
<view class="table">
<uni-table border stripe emptyText="暂无更多数据">
<!-- 表头行 -->
<uni-tr>
<uni-th align="left">时间</uni-th>
<uni-th align="left">人数</uni-th>
</uni-tr>
<!-- 表格数据行 -->
<uni-tr v-for="(item,index) in list" :key="index">
<uni-td>2020-10-20</uni-td>
<uni-td>50</uni-td>
</uni-tr>
</uni-table>
</view>
</view>
</template>

<script>
export default {
data() {
return {
list: [{},{},{}],
}
},
methods: {}
}
</script>

<style scoped lang="scss">
.table{
padding: 30rpx;
}
</style>

+ 173
- 0
monitorMobile/pages/attendanceCall/passengerFlow/index.vue View File

@@ -0,0 +1,173 @@
<template>
<view style="height: 100%;">
<u-empty marginTop="100rpx" :show="false" mode="list" text="暂无数据"></u-empty>
<u-list @scrolltolower="scrolltolower" style="height: calc(100% - 0rpx);">
<u-list-item v-for="(item, index) in list" :key="index">
<view class="whiteCard">
<view class="row1">
摄像头:教室(海康)、大厅(魔豆)
</view>
<view class="row2">
查询时间:2024-08-14 08:34:59
</view>
<view class="row3">
<view class="">
<text>开始时间:</text>2024-08-14 08:34:59
</view>
<view class="">
<text>结束时间:</text>2024-08-14 08:34:59
</view>
<view class="type">
<text>分片类型:<text style="color: #333;">小时</text></text>
<view class="peopleNum">
<image src="@/static/image/peopleNum.png" mode=""></image>
<text>总人数:6</text>
</view>
</view>
</view>
<view class="bottom">
<view class="btn" @click="NAV_TO('./passengerFlow/detail')">
<image src="@/static/image/see.png" mode=""></image>
<text>分片详情</text>
</view>
</view>
</view>
</u-list-item>
<u-loadmore :status="status" />
</u-list>
<image class="addBtn" @click="NAV_TO('./passengerFlow/add')" src="@/static/image/add.png" mode=""></image>
</view>
</template>

<script>
export default {
data() {
return {
list: [{}, {}, {}, {}, {}, {}, {}, {}, {}, ],
isLoading: false,
status: 'loadmore', //loading正在加载 loadmore加载更多 nomore没有更多了
search: {
loudong: 1,
qinshi: ''
},
page: {
size: 8,
page: 8,
}
}
},
methods: {
scrolltolower() {
this.loadmore()
},
loadmore() {
if (this.status != 'loadmore') return
this.status = 'loading'
setTimeout(() => {
for (let i = 0; i < 1; i++) {
this.list.push({}, {}, {}, {})
}
// 获取到的总条数>=接口总条数 || 接口总条数为0
if (this.list.length >= 14) {
this.status = 'nomore'
} else {
this.status = 'loadmore'
}
}, 2000)
},
refresh() {
this.status = 'loadmore'
this.list = []
this.page.page = 1
this.loadmore()
},
pullDownRefresh() {
this.refresh()
}
},
onLoad() {
this.loadmore()
},
}
</script>

<style lang="scss" scoped>
.addBtn{
width: 140rpx;
height: 140rpx;
position: fixed;
right: 15rpx;
bottom: 160rpx;
}
.whiteCard {
background-color: #fff;
border-radius: 18rpx;
margin: 12rpx 28rpx;
padding: 30rpx;
color: #333333;

.row1 {
font-size: 32rpx;
}

.row2 {
font-size: 26rpx;
margin-top: 14rpx;
}
.row3{
background-color: #F2F8FF;
border-radius: 16rpx;
font-size: 26rpx;
padding: 18rpx 24rpx;
line-height: 48rpx;
margin-top: 18rpx;
text{
color: #777777;
}
.type{
display: flex;
justify-content: space-between;
.peopleNum {
uni-image {
width: 34rpx;
height: 34rpx;
position: relative;
top: 8rpx;
margin-right: 10rpx;
}
uni-text {
color: #2388FF;
}
}
}
}

.bottom {
display: flex;
border-top: 1rpx solid rgba(0, 0, 0, 0.1);
margin-top: 24rpx;
padding-top: 22rpx;
position: relative;

.btn {
width: 100%;
display: flex;
align-items: center;
justify-content: center;

uni-image {
width: 34rpx;
height: 34rpx;
margin-right: 6rpx;
}

uni-text {
font-size: 30rpx;
}
}
}
}
</style>

+ 137
- 0
monitorMobile/pages/attendanceCall/returnBed/comfirm.vue View File

@@ -0,0 +1,137 @@
<template>
<view>
<view class="title">
<image src="@/static/image/home1.png" mode="" style="width: 40rpx;height: 40rpx;margin-right: 8rpx;"></image>
寝室104
</view>
<view class="time">
2024年8月24日 18:00:00 ~ 18:59:00
</view>
<u-checkbox-group v-model="checkboxValue" class="list" placement="column">
<view v-for="(item, index) in list" :key="index" class="item">
<u-checkbox :name="item.name" shape="circle" label=""></u-checkbox>
<view class="right">
<image src="@/static/image/test/test.png" mode="" style="width: 160rpx;height: 160rpx;"></image>
<view class="des">
<view class="name">
杨云
</view>
<view class="depart">
系部:安环部
</view>
<view class="bottom">
<view class="major">专业:环艺</view>
<view class="class">班级:第二班</view>
</view>
</view>
</view>
</view>
</u-checkbox-group>
<view class="returnConfirm">
<u-checkbox-group><u-checkbox shape="circle" label="全选" name="" @change="radioChange"></u-checkbox></u-checkbox-group>
<u-button @click="returnConfirm" type="primary" style="border-radius: 36rpx;height: 72rpx;margin-left:16rpx"
text="确定归寝(0)"></u-button>
</view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
list: [{
name: 1
}, {
name: 2
}, {
name: 3
}],
checkboxValue:[],
}
},
methods: {
radioChange(e){
if(e){
let ids = this.list.map(e=>e.name)
this.checkboxValue = ids
}else{
this.checkboxValue = []
}
},
returnConfirm() {
console.log(this.checkboxValue)
}
}
}
</script>

<style scoped lang="scss">
.title {
display: flex;
color: #333333;
padding: 26rpx;
background: #fff;
border-top: 1rpx solid rgba(0, 0, 0, 0.03);
font-size: 30rpx;
}

.time {
color: #333333;
font-size: 28rpx;
padding: 26rpx;
}

.list {
padding: 0 26rpx;

.item {
display: flex;
margin-bottom: 28rpx;

&:last-child {
margin-bottom: 0;
}

.right {
margin-left: 12rpx;
padding: 30rpx;
flex: 1;
background-color: #fff;
border-radius: 18rpx;
display: flex;

.des {
flex: 1;
padding-left: 24rpx;
font-size: 26rpx;
color: #333;

.name {
color: #333;
font-size: 32rpx
}

.depart {
margin-top: 28rpx;
}

.bottom {
margin-top: 18rpx;
display: flex;
justify-content: space-between;

.major {}

.class {}
}
}
}
}
}

.returnConfirm {
padding: 30rpx;
display: flex;
}
</style>

+ 159
- 0
monitorMobile/pages/attendanceCall/returnBed/detail.vue View File

@@ -0,0 +1,159 @@
<template>
<view>
<view class="title">
<image src="@/static/image/home1.png" mode="" style="width: 40rpx;height: 40rpx;margin-right: 8rpx;">
</image>
寝室104
</view>
<view class="listTitlte">
已归寝
</view>
<view class="list">
<view v-for="(item, index) in list" :key="index" class="item">
<view class="right">
<image src="@/static/image/test/test.png" mode="" style="width: 160rpx;height: 160rpx;"></image>
<view class="des">
<view class="top">
<view class="status">
已归寝
</view>
<view class="name">
杨云
</view>
</view>
<view class="depart">
系部:安环部
</view>
<view class="bottom">
<view class="major">专业:环艺</view>
<view class="class">班级:第二班</view>
</view>
</view>
</view>
</view>
</view>
<view class="listTitlte">
未归寝
</view>
<view class="list">
<view v-for="(item, index) in list" :key="index" class="item">
<view class="right">
<image src="@/static/image/test/test.png" mode="" style="width: 160rpx;height: 160rpx;"></image>
<view class="des">
<view class="top">
<view class="status error">
未归寝
</view>
<view class="name">
杨云
</view>
</view>
<view class="depart">
系部:安环部
</view>
<view class="bottom">
<view class="major">专业:环艺</view>
<view class="class">班级:第二班</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
list: [{
name: 1
}, {
name: 2
}, {
name: 3
}],
checkboxValue:[],
}
},
methods: {
}
}
</script>

<style scoped lang="scss">
.title {
display: flex;
color: #333333;
padding: 26rpx;
background: #fff;
border-top: 1rpx solid rgba(0, 0, 0, 0.03);
font-size: 30rpx;
}
.listTitlte{
color: #777777;
font-size:28rpx;
padding:18rpx 30rpx;
}
.list {
padding: 0 26rpx;
margin-bottom: 16rpx;
.item {
display: flex;
margin-bottom: 28rpx;

&:last-child {
margin-bottom: 0;
}

.right {
padding: 30rpx;
flex: 1;
background-color: #fff;
border-radius: 18rpx;
display: flex;

.des {
flex: 1;
padding-left: 24rpx;
font-size: 26rpx;
color: #333;

.top {
color: #333;
font-size: 32rpx;
display:flex;
.status{
display: inline-block;
font-size: 26rpx;
line-height: 1.5;
background-color: #0FAF76;
color: #fff;
padding: 0 12rpx;
border-radius: 8rpx;
margin-right: 12rpx;
}
.status.error{
background-color: #EF2D2D;
}
}

.depart {
margin-top: 28rpx;
}

.bottom {
margin-top: 18rpx;
display: flex;
justify-content: space-between;

.major {}

.class {}
}
}
}
}
}
</style>

+ 188
- 0
monitorMobile/pages/attendanceCall/returnBed/index.vue View File

@@ -0,0 +1,188 @@
<template>
<view style="height: 100%;">
<view class="searchBox">
<selectRadio :value.sync="search.loudong" :options="[{value:1,label:'loudong1'},{value:2,label:'loudong2'}]"
title="楼栋" />
<selectSearch :value.sync="search.qinshi" :options="[{value:1,label:'qinshi1'},{value:2,label:'qinshi2'}]"
placeholder="请选择寝室" popupTitle="请选择寝室" search-placeholder="请输入寝室号"/>
</view>
<u-empty marginTop="100rpx" :show="false" mode="list" text="暂无数据"></u-empty>
<u-list @scrolltolower="scrolltolower" style="height: calc(100% - 220rpx);">
<u-list-item v-for="(item, index) in list" :key="index">
<view class="whiteCard">
<view class="row1">
<text class="room">寝室302</text>
<view class="peopleNum">
<image src="@/static/image/peopleNum.png" mode=""></image>
<text>寝室人数:6</text>
</view>
</view>
<view class="row2">
<text class="returnNum">归寝人数:4</text>
<text class="noReturnNum">未归寝人数:2</text>
</view>
<view class="bottom">
<view class="btn" @click="NAV_TO('./returnBed/detail')">
<image src="@/static/image/see.png" mode=""></image>
<text>查看</text>
</view>
<view class="btn" @click="NAV_TO('./returnBed/comfirm')">
<image src="@/static/image/confirm.png" mode=""></image>
<text>归寝确认</text>
</view>
</view>
</view>
</u-list-item>
<u-loadmore :status="status" />
</u-list>
</view>
</template>

<script>
import selectRadio from "@/components/selectRadio.vue"
import selectSearch from "@/components/selectSearch.vue"
export default {
components: {
selectRadio,
selectSearch
},
data() {
return {
list: [{}, {}, {}, {}, {}, {}, {}, {}, {}, ],
isLoading: false,
status: 'loadmore', //loading正在加载 loadmore加载更多 nomore没有更多了
search: {
loudong: 1,
qinshi: ''
},
page:{
size:8,
page:8,
}
}
},
methods: {
scrolltolower() {
this.loadmore()
},
loadmore() {
if (this.status != 'loadmore') return
this.status = 'loading'
setTimeout(() => {
for (let i = 0; i < 1; i++) {
this.list.push({}, {},{},{})
}
// 获取到的总条数>=接口总条数 || 接口总条数为0
if (this.list.length >= 14) {
this.status = 'nomore'
} else {
this.status = 'loadmore'
}
}, 2000)
},
refresh(){
this.status = 'loadmore'
this.list = []
this.page.page = 1
this.loadmore()
},
pullDownRefresh(){
this.refresh()
}
},
onLoad() {
this.loadmore()
},
}
</script>

<style lang="scss" scoped>
.searchBox {
margin: 24rpx 28rpx 12rpx;

>view {
margin-bottom: 18rpx;

&:last-child {
margin-bottom: 0rpx;
}
}
}

.whiteCard {
background-color: #fff;
border-radius: 18rpx;
margin: 12rpx 28rpx;
padding: 30rpx;
color: #333333;

.row1 {
display: flex;
justify-content: space-between;

.room {
font-size: 34rpx;
}

.peopleNum {
uni-image {
width: 34rpx;
height: 34rpx;
position: relative;
top: 8rpx;
margin-right: 6rpx;
}

uni-text {
color: #2388FF;
font-size: 30rpx;
}
}
}

.row2 {
margin-top: 18rpx;
display: flex;
justify-content: space-between;
font-size: 30rpx;

.returnNum {}

.noReturnNum {}
}

.bottom {
display: flex;
border-top: 1rpx solid rgba(0, 0, 0, 0.1);
margin-top: 24rpx;
padding-top: 22rpx;
position: relative;
::after{
content: "";
display: block;
position: absolute;
top: 30rpx;bottom: 0;
left: 0;right: 0;
margin: 0 auto;
width: 1rpx;
height: 32rpx;
background-color: rgba(0, 0, 0, 0.01);
}
.btn {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
uni-image {
width: 34rpx;
height: 34rpx;
margin-right: 6rpx;
}

uni-text {
font-size: 30rpx;
}
}
}
}
</style>

+ 22
- 0
monitorMobile/pages/attendanceCall/rollCall/index.vue View File

@@ -0,0 +1,22 @@
<template>
<view>
点名
</view>
</template>

<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>

<style>

</style>

+ 690
- 0
monitorMobile/pages/earlyWarning/index.vue View File

@@ -0,0 +1,690 @@
<template>
<view class="warningBox">
<!-- 头部背景 -->
<view class="headerBox">
<image :src="modelObj.backgroundImg"></image>
<view class="selectModel" @click="showSelectModel = true">
<view class="modelName">
{{modelObj.name}}
</view>
<image src="@/static/image/earlyWarning/down.png"></image>
</view>
<u-popup :show="showSelectModel" @close="close" @open="open" mode="top">
<view class="selectPopupBox">
<view class="modelLi" :class="item.id == isActive ? 'active' : ''" @click="modelChange(item)"
v-for="(item,i) in modelList">
{{item.name}}
</view>
</view>
</u-popup>
</view>
<view class="contentBox" v-if="isActive == '1'">
<view class="searchBox">
<view class="searchLine">
<view class="leftSearchBox">
<view class="searchLabel">
筛选条件:
</view>
<view class="searchValue">
111111111111111111111111111111111111111111111111111111111111111111111111
</view>
</view>
<view class="searchShow" @click="openSearch">
<image v-show="isShowSearch==false" style="width:20px;height:20px;"
src="@/static/image/earlyWarning/screen.png" mode="">
</image>
<image v-show="isShowSearch" style="width:20px;height:20px;"
src="@/static/image/earlyWarning/screenActive.png" mode="">
</image>
</view>
</view>
<view @click="isShowSearch=false" class="searchDialog" v-if="isShowSearch">
<view class="content" @click.stop="isSelect">
<u-row justify="space-between" gutter="10">
<u-col span="7">
<view class="demo-layout" @click="toOpen">
<view class="left-layout">
<text>{{searchForm.alarmType}}</text>
</view>
<view class="right-layout">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
</view>
</view>

<!-- <jp-select-plus ref="selectPlus" :isShow="false" color="#2388FF" placeholder="请选择"
isSearch v-model="va3" :list="listc"></jp-select-plus> -->
</u-col>
<u-col span="5">
<view class="demo-layout">
<view class="left-layout">
<text>{{searchForm.warnHand}}</text>
</view>
<view class="right-layout">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/arrowRight.png" mode=""></image>
</view>
</view>
</u-col>
</u-row>
<u-row style="margin-top:10px;" justify="space-between" gutter="10">
<u-col span="12">
<uni-datetime-picker v-model="searchForm.tick" type="datetimerange">
<view class="demo-layout">
<view class="startBox">
{{searchForm.StartTick}}
</view>
<text>至</text>
<view class="endBox">
{{searchForm.EndTick}}
</view>
<view class="timeIcon">
<image style="width: 30rpx;height:30rpx;"
src="@/static/image/earlyWarning/calendar.png" mode=""></image>
</view>
</view>
</uni-datetime-picker>

</u-col>
</u-row>
<view class="btnBox">
<view class="leftBtn">
重置
</view>
<view class="rightBtn">
确认
</view>
</view>
</view>
</view>

</view>
<view class="tableBox">
<u-empty marginTop="100rpx" :show="false" mode="warnList" text="暂无数据"></u-empty>
<u-list @scrolltolower="scrolltolower" style="height: calc(100% - 0rpx);">
<u-list-item v-for="(item, index) in warnList" :key="index">
<view class="liBox">
<view class="topCard">
<view class="pic">
<image src="@/static/image/earlyWarning/warnBack.png" mode=""></image>
</view>
<view class="rightCard">
<view class="firstCard">
<view class="schoolName">
学校名称学校名称学校名称学校名称
</view>
<view class="statusBox" :class="[item.warnHand == 1?'handle':'nohandle']">
{{item.warnHand == 1 ? '已处理' : '未处理'}}
</view>
</view>
<view class="secondCard">
<image style="width: 30rpx;height: 30rpx;"
src="@/static/image/earlyWarning/warnType.png" mode=""></image>
<view class="txt">
警告类型:周界入侵
</view>
</view>
<view class="thirdCard">
<image style="width: 30rpx;height: 30rpx;"
src="@/static/image/earlyWarning/warnVideo.png" mode=""></image>
<view class="txt">
警告摄像头:厨房(良景)
</view>
</view>
</view>
</view>
<view class="midCard">
<u-row>
<u-col span="6">
<view class="midContent">
姓名:杨云
</view>
</u-col>
<u-col span="6">
<view class="midContent">
系部:安环部
</view>
</u-col>
</u-row>
<u-row>
<u-col span="6">
<view class="midContent">
专业:环艺
</view>
</u-col>
<u-col span="6">
<view class="midContent">
班级:第二班
</view>
</u-col>
</u-row>
<u-row>
<u-col span="12">
<view class="midContent">
时间:2024-08-15 11:59:12
</view>
</u-col>
</u-row>
</view>
<view class="btoCard">
<view class="leftBox btoBox">
<image src="@/static/image/earlyWarning/detail.png" mode=""></image>
<view class="txt">
查看
</view>
</view>
<view class="midBox btoBox">
<image v-if="item.warnHand == 1" src="@/static/image/earlyWarning/handle.png"
mode=""></image>
<image v-if="item.warnHand == 0"
src="@/static/image/earlyWarning/handleDisabled.png" mode=""></image>
<view :class="[item.warnHand == 1?'txt':'disabled']">
处理
</view>
</view>
<view class="rightBox btoBox">
<image src="@/static/image/earlyWarning/delete.png" mode=""></image>
<view class="txt">
删除
</view>
</view>
</view>
</view>
</u-list-item>
<u-loadmore :status="status" />
</u-list>
</view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
searchForm: {
alarmType: '警告类型',
warnHand: '处理状态',
tick: [],
StartTick: '开始时间',
EndTick: '结束时间',
},
showSelectModel: false,
modelObj: {
name: '预警信息',
backgroundImg: require(`@/static/image/earlyWarning/warnBack.png`)
},
isActive: '1',
modelList: [{
id: '1',
name: '预警信息',
imgUrl: require(`@/static/image/earlyWarning/warnBack.png`)
},
{
id: '2',
name: '巡检中心',
imgUrl: require(`@/static/image/earlyWarning/majorBack.png`)
}
],
isShowSearch: false,
warnList: [{
warnHand: 0
}, {}, {}, {}, {}, {}, {}, {}, {}, ],
isLoading: false,
status: 'loadmore', //loading正在加载 loadmore加载更多 nomore没有更多了
listc: [{
code: 1,
name: 'dasda'
}, {
code: 2,
name: 'dasda'
},
{
code: 3,
name: 'dasda'
},
{
code: 4,
name: 'dasda'
},
{
code: 5,
name: 'dasda'
},
{
code: 6,
name: 'dasda'
},
{
code: 7,
name: 'dasda'
},
{
code: 8,
name: 'dasda'
},
{
code: 9,
name: 'dasda'
},
{
code: 10,
name: 'dasda'
},
{
code: 11,
name: 'dasda'
},
{
code: 12,
name: 'dasda'
},
{
code: 13,
name: '你好'
}
]
}
},
watch: {
"searchForm.tick"() {
console.log('日期时间:', this.searchForm.tick);
if(this.searchForm.tick && this.searchForm.tick.length>0) {
this.searchForm.StartTick = this.searchForm.tick[0]
this.searchForm.EndTick = this.searchForm.tick[1]
}
},
},
filters: {
// statusChange(val) {
// switch (val) {
// case 'todo':
// return '我的待办'
// break;
// case 'send':
// return '由我发起'
// break;
// case 'done':
// return '我的已办'
// break;
// default:

// }
// },
},
onLoad() {
// 隐藏导航栏
this.loadmore()
},
methods: {
toOpen() {
this.$refs.selectPlus.open()
},
open() {
// console.log('open');
},
close() {
this.showSelectModel = false;
// console.log('close');
},
// 切换模块
modelChange(item) {
console.log(item)
this.modelObj.name = item.name;
this.modelObj.backgroundImg = item.imgUrl;
this.isActive = item.id;
this.showSelectModel = false;
// switch (item.id) {
// case '1':

// break;
// case '2':
// break;
// default:
// break;
// }
},
// 打开筛选框
openSearch() {
this.isShowSearch = !this.isShowSearch;

},
isSelect() {

},
scrolltolower() {
this.loadmore()
},
loadmore() {
if (this.status != 'loadmore') return
this.status = 'loading'
setTimeout(() => {
for (let i = 0; i < 1; i++) {
this.warnList.push({}, {})
}
// 获取到的总条数>=接口总条数
if (this.warnList.length >= 14) {
this.status = 'nomore'
} else {
this.status = 'loadmore'
}
}, 2000)
}
}
}
</script>

<style lang="scss" scoped>
.warningBox {
height: 100%;

.headerBox {
height: 380rpx;
// background: url("@/static/image/earlyWarning/warnBack.png") no-repeat center center / cover;
position: relative;

image {
width: 100%;
height: 100%;
}

.selectModel {
position: absolute;
left: 60rpx;
top: 108rpx;
display: flex;
justify-content: center;
align-items: center;

.modelName {
font-size: 34rpx;
color: #fff;
font-family: PingFang SC;
margin-right: 20rpx;
}

image {
width: 24rpx;
height: 12rpx;
}
}

.selectPopupBox {
padding: 0 10px;
box-sizing: border-box;

.modelLi {
height: 100rpx;
line-height: 100rpx;
text-align: center;
border-bottom: 1px solid #efecec;
}

.active {
color: rgb(35, 136, 255);
}
}
}

.contentBox {
height: calc(100% - 375rpx);

.searchBox {
// height: calc(100% - 360rpx);
position: relative;

.searchLine {
height: 88rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15px;
box-sizing: border-box;
background: #fff;

.leftSearchBox {
display: flex;
align-items: center;
width: calc(100% - 40px);

.searchLabel {
flex-shrink: 1;
color: #333333;
width: 80px;
}

.searchValue {
width: calc(100% - 60px);
margin-left: 10px;
color: #2388FF;
overflow: hidden;
word-wrap: break-word;
white-space: pre-wrap;
// font-size: 14px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
}
}

.searchDialog {
position: absolute;
z-index: 990;
top: 89rpx;
width: 100%;
height: calc(100vh - 375rpx - 100rpx);
font-size: 26rpx;
background: rgba(0, 0, 0, 0.2);

.content {
background: #FFFFFF;
padding: 15px;
box-sizing: border-box;

.demo-layout {
height: 80rpx;
border-radius: 8rpx;
background: #F5F5F5;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
box-sizing: border-box;

.left-layout {
color: #777777;
}

.right-layout {}

.startBox {
color: #777777;
}

text {
color: #777777;
}

.endBox {
color: #777777;
}

.timeIcon {}
}
}

.btnBox {
display: flex;
align-items: center;
margin-top: 15px;

.leftBtn {
width: 50%;
height: 74rpx;
line-height: 74rpx;
border: 1px solid #BABABA;
border-radius: 12rpx;
color: #333333;
text-align: center;

}

.rightBtn {
width: 50%;
height: 74rpx;
line-height: 74rpx;
border: 1px solid #2388FF;
border-radius: 12rpx;
color: #fff;
text-align: center;
background: #2388FF;
margin-left: 15rpx;
}
}
}
}

.tableBox {
height: 100%;
padding: 10px;
box-sizing: border-box;
// height: 600px;
padding-bottom: 50px;


.liBox {
background: #fff;
padding: 20px 15px;
box-sizing: border-box;
border-radius: 20px;
margin-bottom: 10px;

.topCard {
display: flex;

.pic {

image {
width: 160rpx;
height: 160rpx;
border-radius: 4px;
}
}

.rightCard {
margin-left: 20rpx;

.firstCard {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;

.schoolName {
font-size: 32rpx;
color: #333333;
overflow: hidden;
word-wrap: break-word;
white-space: pre-wrap;
// font-size: 14px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}

.statusBox {
width: 140rpx;
flex-shrink: 1;
text-align: center;
height: 50rpx;
line-height: 50rpx;
font-size: 28rpx;
border-radius: 8rpx;
color: #fff;
}

.handle {
background: rgba(15, 175, 118, 0.1);
color: #0FAF76;
}

.nohandle {
background: rgba(239, 45, 45, 0.1);
color: rgba(239, 45, 45, 1);
}
}

.secondCard,
.thirdCard {
display: flex;
align-items: center;
margin-top: 18rpx;

.txt {
font-size: 28rpx;
margin-left: 10rpx;
color: #333333;
}
}
}
}

.midCard {
font-size: 28rpx;

.midContent {
margin-top: 18rpx;
}
}

.btoCard {
border-top: 1px solid rgba(0, 0, 0, 0.1);
margin-top: 30rpx;
padding: 18px 0 0 0;
display: flex;
justify-content: center;
align-items: center;

.btoBox {
width: 33.3%;
display: flex;
justify-content: center;
align-items: center;
position: relative;

image {
width: 40rpx;
height: 40rpx;
margin-right: 15rpx;
}
}

.btoBox:not(:last-child)::before {
content: '';
display: block;
width: 1px;
height: 100%;
background: rgba(0, 0, 0, 0.1);
position: absolute;
right: 0px;
}

.midBox {
.txt {
color: #333333;
}

.disabled {
color: #777777;
}
}
}
}

}
}
}
</style>

+ 21
- 0
monitorMobile/pages/home.vue View File

@@ -0,0 +1,21 @@
<template>
<view>
首页
</view>
</template>

<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>

<style lang="scss" scoped>
</style>
<style>
</style>

+ 22
- 0
monitorMobile/pages/my/index.vue View File

@@ -0,0 +1,22 @@
<template>
<view>
我的
</view>
</template>

<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>

<style>

</style>

BIN
monitorMobile/static/image/add.png View File

Before After
Width: 284  |  Height: 284  |  Size: 31 KiB

BIN
monitorMobile/static/image/confirm.png View File

Before After
Width: 68  |  Height: 68  |  Size: 1.0 KiB

BIN
monitorMobile/static/image/earlyWarning/arrowRight.png View File

Before After
Width: 30  |  Height: 30  |  Size: 298 B

BIN
monitorMobile/static/image/earlyWarning/calendar.png View File

Before After
Width: 30  |  Height: 30  |  Size: 513 B

BIN
monitorMobile/static/image/earlyWarning/delete.png View File

Before After
Width: 34  |  Height: 34  |  Size: 531 B

BIN
monitorMobile/static/image/earlyWarning/detail.png View File

Before After
Width: 34  |  Height: 34  |  Size: 871 B

BIN
monitorMobile/static/image/earlyWarning/down.png View File

Before After
Width: 22  |  Height: 12  |  Size: 198 B

BIN
monitorMobile/static/image/earlyWarning/handle.png View File

Before After
Width: 34  |  Height: 34  |  Size: 758 B

BIN
monitorMobile/static/image/earlyWarning/handleDisabled.png View File

Before After
Width: 34  |  Height: 34  |  Size: 735 B

BIN
monitorMobile/static/image/earlyWarning/majorBack.png View File

Before After
Width: 1500  |  Height: 720  |  Size: 725 KiB

BIN
monitorMobile/static/image/earlyWarning/screen.png View File

Before After
Width: 40  |  Height: 40  |  Size: 570 B

BIN
monitorMobile/static/image/earlyWarning/screenActive.png View File

Before After
Width: 40  |  Height: 40  |  Size: 570 B

BIN
monitorMobile/static/image/earlyWarning/warnBack.png View File

Before After
Width: 1500  |  Height: 720  |  Size: 640 KiB

BIN
monitorMobile/static/image/earlyWarning/warnType.png View File

Before After
Width: 30  |  Height: 30  |  Size: 486 B

BIN
monitorMobile/static/image/earlyWarning/warnVideo.png View File

Before After
Width: 30  |  Height: 30  |  Size: 682 B

BIN
monitorMobile/static/image/home1.png View File

Before After
Width: 80  |  Height: 80  |  Size: 1.0 KiB

BIN
monitorMobile/static/image/peopleNum.png View File

Before After
Width: 68  |  Height: 68  |  Size: 1.3 KiB

BIN
monitorMobile/static/image/see.png View File

Before After
Width: 68  |  Height: 68  |  Size: 1.3 KiB

BIN
monitorMobile/static/image/tabbar/attendanceCall.png View File

Before After
Width: 80  |  Height: 80  |  Size: 1.2 KiB

BIN
monitorMobile/static/image/tabbar/earlyWarning_active.png View File

Before After
Width: 80  |  Height: 80  |  Size: 1.2 KiB

BIN
monitorMobile/static/image/tabbar/home.png View File

Before After
Width: 80  |  Height: 80  |  Size: 926 B

BIN
monitorMobile/static/image/tabbar/my.png View File

Before After
Width: 80  |  Height: 80  |  Size: 1001 B

BIN
monitorMobile/static/image/test/test.png View File

Before After
Width: 320  |  Height: 320  |  Size: 271 KiB

+ 30
- 0
monitorMobile/store/$u.mixin.js View File

@@ -0,0 +1,30 @@
// $u.mixin.js

import { mapState } from 'vuex'
import store from "@/store"

// 尝试将用户在根目录中的store/index.js的vuex的state变量,全部加载到全局变量中
let $uStoreKey = [];
try {
$uStoreKey = store.state ? Object.keys(store.state) : [];
} catch (e) {

}

module.exports = {
mounted() {
// 将vuex方法挂在到$u中
// 使用方法为:如果要修改vuex的state中的user.name变量为"史诗" => this.$u.vuex('user.name', '史诗')
// 如果要修改vuex的state的version变量为1.0.1 => this.$u.vue x('version', '1.0.1')
this.$u.vuex = (name, value) => {
this.$store.commit('$uStore', {
name,
value
})
}
},
computed: {
// 将vuex的state中的所有变量,解构到全局混入的mixin中
...mapState($uStoreKey)
}
}

+ 75
- 0
monitorMobile/store/index.js View File

@@ -0,0 +1,75 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

let lifeData = {};

try {
// 尝试获取本地是否存在lifeData变量,第一次启动APP时是不存在的
lifeData = uni.getStorageSync('lifeData');
} catch (e) {

}

// 需要永久存储,且下次APP启动需要取出的,在state中的变量名
let saveStateKeys = [];

// 保存变量到本地存储中
const saveLifeData = function(key, value) {
// 判断变量名是否在需要存储的数组中
if (saveStateKeys.indexOf(key) != -1) {
// 获取本地存储的lifeData对象,将变量添加到对象中
let tmp = uni.getStorageSync('lifeData');
// 第一次打开APP,不存在lifeData变量,故放一个{}空对象
tmp = tmp ? tmp : {};
tmp[key] = value;
// 执行这一步后,所有需要存储的变量,都挂载在本地的lifeData对象中
uni.setStorageSync(key, value);
uni.setStorageSync('lifeData', tmp);
}
if(key == 'refreshToken') {
uni.setStorageSync('token', {
content: value,
datetime: new Date().getTime()
})
}
}
const store = new Vuex.Store({
// 下面这些值仅为示例,使用过程中请删除
state: {
// 如果上面从本地获取的lifeData对象下有对应的属性,就赋值给state中对应的变量
userInfo: lifeData.userInfo ? lifeData.userInfo : {
avatar: '',
nick_name: '游客',
tenant_id: '暂无'
},
accessToken: lifeData.accessToken ? lifeData.accessToken : '',
isLogin: lifeData.isLogin ? lifeData.isLogin : false,
// 如果version无需保存到本地永久存储,无需lifeData.version方式
version: '1.0.0',
},
mutations: {
$uStore(state, payload) {
// 判断是否多层级调用,state中为对象存在的情况,诸如user.info.score = 1
let nameArr = payload.name.split('.');
let saveKey = '';
let len = nameArr.length;
if (nameArr.length >= 2) {
let obj = state[nameArr[0]];
for (let i = 1; i < len - 1; i++) {
obj = obj[nameArr[i]];
}
obj[nameArr[len - 1]] = payload.value;
saveKey = nameArr[0];
} else {
// 单层级变量,在state就是一个普通变量的情况
state[payload.name] = payload.value;
saveKey = payload.name;
}
// 保存变量到本地,见顶部函数定义
saveLifeData(saveKey, state[saveKey])
}
}
})

export default store

+ 10
- 0
monitorMobile/uni.promisify.adaptor.js View File

@@ -0,0 +1,10 @@
uni.addInterceptor({
returnValue (res) {
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
return res;
}
return new Promise((resolve, reject) => {
res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
});
},
});

+ 78
- 0
monitorMobile/uni.scss View File

@@ -0,0 +1,78 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
*
*/

/**
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/

/* 颜色变量 */

/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;

/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;

/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色

/* 边框颜色 */
$uni-border-color:#c8c7cc;

/* 尺寸变量 */

/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16;

/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;

/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;

/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;

/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;

/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度

/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;

@import 'uview-ui/theme.scss';

+ 4
- 0
monitorMobile/uni_modules/jp-select-plus/changelog.md View File

@@ -0,0 +1,4 @@
## 1.1(2023-08-17)
修复多选显示问题
## 1.0.1(2023-08-17)
1.0

BIN
monitorMobile/uni_modules/jp-select-plus/components/jp-select-plus/arrow.png View File

Before After
Width: 48  |  Height: 48  |  Size: 972 B

+ 682
- 0
monitorMobile/uni_modules/jp-select-plus/components/jp-select-plus/jp-select-plus.vue View File

@@ -0,0 +1,682 @@
<template>
<view class="showData" ref="echartsWrapper" :class="[isLine?'isLine':'']">
<view v-if="isShow" :class="isLineFeed?'showData-field-line':'showData-field-input'" @click="open">
<view class="showData-field-label"
:style="{minWidth:isLineFeed?'':labelWidths,width:isLineFeed?'':labelWidths,color:labelColor}"
v-if="label"><span v-if="required" style="color: red">*</span>{{label}}</view>
<!-- 多选 -->
<view :class="direction=='left'?'textleft':'textR'" :style="{width: inpeWidth}"
class="inputs checkbox showDatas" v-if="checkbox && !clickable">
<view :style="{color: value?valueColor?valueColor:'':'#999',width: inpeWidthLfet}"
:class="isoverflow?'showData-field-pu':''">
<view v-if="ListXz.length>0">
<view v-if="!isJoin">
<view v-for="(item,index) in ListXz" :key="'a'+index">{{KeyType?item[showName]:item}}</view>
</view>
<view v-else>
{{KeyType?ListXz.map(el=>{return el[showName]}).join(','):ListXz.map(el=>{return el}).join(',')}}
</view>
</view>
<view :style="{color: placeholderColor }" v-else>{{placeholder}}</view>
</view>
<view v-if="arrow" class="arrows">
<image src="./arrow.png" style="width: 30rpx;height: 30rpx;"></image>
</view>
</view>
<!-- 单选 -->
<view :style="{width: inpeWidth}" :class="direction=='left'?'textleft':'textR'" class="inputs showDatas"
v-if="!checkbox && !clickable">
<view :style="{color: ListXz.length>0?valueColor?valueColor:'':placeholderColor,width: inpeWidthLfet}"
:class="isoverflow?'showData-field-pu':''">
{{ListXz.length>0?(KeyType?ListXz[0][showName]:ListXz[0]):placeholder}}
</view>
<view v-if="arrow" class="arrows">
<image src="./arrow.png" style="width: 30rpx;height: 30rpx;"></image>
</view>
</view>
<!-- 可以点击 -->
<view :style="{width: inpeWidth}" :class="direction=='left'?'textleft':'textR'" class="inputs showDatas"
v-if="clickable">
<view :style="{color: value?valueColor?valueColor:'':placeholderColor,width: inpeWidthLfet}"
:class="isoverflow?'showData-field-pu':''">{{value?value:placeholder}}</view>
<view v-if="arrow" class="arrows">
<image src="./arrow.png" style="width: 30rpx;height: 30rpx;"></image>
</view>
</view>
</view>
<slot />

<view class="bottomPopup" v-if="showPicker">
<transition name="slide-up" appear>
<view class="popup-content">
<view class="pop-header" v-if="isHeader">
<span class="pop-header-left" @click="onCancel">{{cancelText}}</span>
<span class="pop-header-title">{{title}}</span>
<span class="pop-header-right" :style="{color}" @click="onConfirm">{{confirmText}}</span>
</view>
<view class="pop-header" v-if="!isHeader">
<slot name="popHeader" />
</view>
<view v-if="isSearch">
<view style="background-color: #fff;padding: 15rpx 25rpx;">
<view
style="border-radius: 10rpx;padding: 0 25rpx;;display: flex;justify-content: center;background-color: #f5f5f5;line-height: 65rpx;height: 65rpx;">
<view style="display: flex;justify-content: center;flex: 1;">
<input style="line-height: 65rpx;height: 65rpx;flex: 1;" v-model.trim="key"
:placeholder="headerPlaceholder" />
</view>
<view @click="onSearch" :style="{color}"
style="width: 80rpx;text-align: center;margin-left: 25rpx;">
搜索
</view>
</view>
</view>
</view>
<view v-if="isLoading && popList.length==0" class="pop-main loading">
<loading></loading>
</view>
<view v-else>
<view class="pop-main">
<view v-if="popList.length>0">
<checkbox-group v-if="checkbox" @change="checkboxChange">
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in popList"
:key="KeyType?item[keys]:item">
<view>{{KeyType?item[showName]:item}}</view>
<view>
<checkbox :color="color" :value="KeyType?item[keys]:item"
:checked="getChecked(KeyType?item[keys]:item)" />
</view>
</label>
</checkbox-group>
<radio-group v-else @change="radioChange">
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in popList"
:key="KeyType?item[keys]:item">
<view>{{KeyType?item[showName]:item}}</view>
<view>
<radio :color="color" :value="KeyType?item[keys]:item"
:checked="(KeyType?item[keys]:item) == resultRadio" />
</view>
</label>
</radio-group>
</view>

<view v-else class="noData">
暂无可选数据
</view>
</view>
</view>

</view>
</transition>
</view>
</view>
</template>

<script>
import loading from './loading.vue'
export default {
name: 'showData',
components: {
loading
},
props: {
list: {
type: Array,
default () {
return []
},
},
value: {
type: [String, Array, Number],
default: '',
},
valName: {
type: String,
default: '',
},
keys: {
//需要识别的code标识
type: String,
default: 'code',
},
showName: {
//需要展示标识
type: String,
default: 'name',
},
direction: {
type: String,
default: 'left',
},
clickable: {
type: [Boolean, String],
default: false,
},
isShow: {
type: [Boolean, String],
default: true,
},
isJoin: {
type: [Boolean, String],
default: false,
},
label: {
type: String,
default: '',
},
color: {
type: String,
default: '#00aaff',
},
labelColor: {
type: String,
default: '#646566',
},
placeholder: {
type: String,
default: '请选择',
},
placeholderColor: {
type: String,
default: '#999',
},
labelWidth: {
type: String,
default: '90px',
},
valueColor: {
type: String,
default: '',
},
required: {
type: [Boolean, String],
default: false,
},
isLineFeed: {
type: [Boolean, String],
default: true,
},
isLine: {
//是否换显示线
type: [Boolean, String],
default: true,
},
isoverflow: {
//是否超出隐藏
type: [Boolean, String],
default: true,
},
checkbox: {
//是多选
type: [Boolean, String],
default: false,
},
disabled: {
type: [Boolean, String],
default: false,
},
arrow: {
type: [Boolean, String],
default: true,
},
title: {
type: String,
default: '请选择',
},
cancelText: {
type: String,
default: '取消',
},
confirmText: {
type: String,
default: '确定',
},
headerPlaceholder: {
type: String,
default: '请输入关键字进行搜索',
},
isSearch: {
type: [Boolean, String],
default: false,
},
isHeader: {
type: [Boolean, String],
default: true,
},
isSearchFun: {
type: [Boolean, String],
default: false,
},
alls: {
type: [Boolean, String],
default: false,
},
isLoading: {
type: [Boolean, String],
default: false,
},
},
watch: {
list() {
this.loading = false
this.popList = JSON.parse(JSON.stringify(this.list))
this.setList()
},
value() {
this.popList = JSON.parse(JSON.stringify(this.list))
this.setList()
},
},
// 数据说明
/* list 传进来的数据
* popList 可以选择的数据
* result 当前选中的数据 ,key 数组
* ListJz 确定选择的数据 ,key 数组
* ListXz 确定选择的数据 ,全数组
*
*/
data() {
return {
loading: false,
finished: false,
popList: [],
ListJz: [],
ListXz: [],
primary: "#f39800",
result: [],
KeyType: false,
valueType: false,
valueTypeObject: false,
showPicker: false,
eWidth: 0,
inpeWidth: '',
inpeWidthLfet: '',
labelWidths: '90px',
key: '',
resultRadio: ''
}
},
created() {
this.loading = false
this.popList = JSON.parse(JSON.stringify(this.list))
this.setList()
},
mounted() {},
methods: {
getChecked(code) {
return this.result.some(el => {
return el == code
})
},
checkboxChange(evt) {
this.result = evt.detail.value
console.log(this.result)
},
radioChange(evt) {
this.result = [evt.detail.value]
this.resultRadio = evt.detail.value
},
onSearch() {
if (this.isSearchFun) {
this.$emit('onSearch', this.key)
} else {
if (this.key) {
this.popList = this.list.filter((el) => {
return (this.KeyType ? el[this.showName] : el).indexOf(this.key) != -1
})
} else {
this.popList = JSON.parse(JSON.stringify(this.list))
}
}
},
open() {
if (!this.checkbox) {
if (typeof this.value == 'string' || typeof this.value == 'number') {
this.resultRadio = this.value
} else {
this.resultRadio = this.value[0]
}
} else {
this.result = this.value
}
if (!this.disabled && !this.clickable) {
this.showPicker = true
}
this.$emit('onOpen')
},
close() {
this.showPicker = false
},
setList() {
if (this.popList.length == 0) {
if (this.disabled) {
if (this.value) {
if (this.checkbox) {
this.ListXz = this.value
} else {
this.ListXz = [this.value]
}
} else {
this.ListXz = []
}
}
return
}
if (this.popList.length > 0) {
if (typeof this.popList[0] == 'object') {
this.KeyType = true
} else {
this.KeyType = false
}
}
if (typeof this.value == 'string' || typeof this.value == 'number') {
this.valueType = false
} else {
this.valueType = true
}
if (typeof this.value == 'string' || typeof this.value == 'number') {
this.result = this.value ? [JSON.parse(JSON.stringify(this.value))] : []
} else {
let popList = this.value || []
this.result = popList.map((el) => {
let a = el
if (typeof a == 'object') {
a = el[this.keys]
}
return a
})
}
this.ListJz = JSON.parse(JSON.stringify(this.result))
this.ListXz = []
this.popList.forEach((el, index) => {
let type = this.result.some((a) => {
let elc = this.KeyType ? el[this.keys] : el
return elc == a
})
if (type) {
this.ListXz.push(JSON.parse(JSON.stringify(el)))
}
})
},
opened() {
this.normal = false
},
closed() {
this.showPicker = false
if (this.normal) {
this.ListJz = JSON.parse(JSON.stringify(this.result))
} else {
this.result = JSON.parse(JSON.stringify(this.ListJz))
}
},
onCancel() {
this.normal = false
this.showPicker = false
this.$emit('cancel')
},
onConfirm() {
if (this.required && this.result.length < 1) {
this.$toast('您还未选择')
return
}
this.ListXz = []
this.popList.forEach((el, index) => {
let type = this.result.some((a) => {
let elc = this.KeyType ? el[this.keys] : el
return elc == a
})
if (type) {
this.ListXz.push(el)
}
})
this.normal = true
let firm = null
if (this.valueType) {
//返回数组 valueType
firm = this.result
} else {
if (this.result.length > 0) {
firm = this.result[0]
} else {
firm = ''
}
}
this.showPicker = false
this.$emit('input', this.alls ? this.ListXz : firm)
this.$emit('toConfirm', this.ListXz)

let nameData = this.ListXz.length > 0 ? this.ListXz[0] : ''
let valName = (typeof nameData == 'object') ? nameData[this.showName] : nameData
this.$emit('update:valName', valName)
},
dissatisfactionToggle(index) {
if (!this.checkbox) {
this.result = []
}
this.$refs.dissatisfactionCheckboxes[index].toggle()
},
},
mounted() {
this.eWidth = this.$refs.echartsWrapper.clientWidth
if (this.isLineFeed) {
this.labelWidths = this.eWidth + 'px'
} else {
this.labelWidths = this.labelWidth
}
this.inpeWidth = this.label ?
this.isLineFeed ?
this.eWidth + 'px' :
'calc(' + (this.eWidth - 12 + 'px') + ' - ' + this.labelWidth + ')' :
this.eWidth + 'px'
this.inpeWidthLfet = this.label ?
this.isLineFeed ?
this.eWidth + 'px' :
'calc(' + (this.eWidth - 12 - 20 + 'px') + ' - ' + this.labelWidth + ')' :
this.eWidth - 20 + 'px'
},
}
</script>
<style scoped lang="scss">
.bottomPopup {
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999;
background-color: rgba(0, 0, 0, 0.5);

.popup-content {
position: fixed;
left: 0;
right: 0;
bottom: 52px;
// top: 0;
background-color: #ffffff;
}

.slide-up-enter-active,
.slide-up-leave-active {
transition: all .3s ease;
}

.slide-up-enter,
.slide-up-leave-to {
transform: translateY(100%);
}

.uni-list-cell {
padding: 12rpx 20rpx;
border-bottom: 1px solid #f5f5f5;
display: flex;
justify-content: space-between;
align-items: center;
}

.uni-list-cell:active {
background-color: #f5f5f5;
}
}

.loading {
text-align: center;
line-height: 80px;
}

.textR {
text-align: right;
}

.noData {
text-align: center;
line-height: 40vh;
color: #999;
}

.inputs {
display: flex;
justify-content: space-between;
align-items: center;

.arrows {
width: 20px;
font-size: 16px;
margin-left: 4px;
line-height: 25px;
text-align: right;
display: flex;
justify-content: center;
align-items: center;
color: #969799;
}
}

.checkbox {
line-height: 25px;
// padding: 5px 0px;
}

.showData:active {
background-color: #f9f9f9;
}

.showData {
width: 100%;
position: relative;

.showData-field-input {
line-height: 25px;
display: flex;
justify-content: space-between;
align-items: flex-start;
width: 100%;
padding: 10px 0;

.showData-field-label {
margin-right: 12px;
color: #969799;
}

.showData-field-pu::-webkit-scrollbar {
display: none;
/* Chrome Safari */
}

.showData-field-pu {
padding-right: 5px;
color: #323233;
font-size: 14px;
overflow-y: hidden;
overflow-x: auto;
scrollbar-width: none;
/* firefox */
-ms-overflow-style: none;
/* IE 10+ */
white-space: nowrap;
}
}

.showData-field-line {
padding: 10px 0;
line-height: 25px;
width: 100%;

.showData-field-label {
margin-right: 12px;
color: #969799;
}

.showData-field-pu::-webkit-scrollbar {
display: none;
/* Chrome Safari */
}

.showData-field-pu {
padding-right: 5px;
color: #323233;
font-size: 14px;
overflow-y: hidden;
overflow-x: auto;
scrollbar-width: none;
/* firefox */
-ms-overflow-style: none;
/* IE 10+ */
white-space: nowrap;
}
}

.color96 {
color: #969799;
}
}

.isLine::after {
position: absolute;
content: ' ';
left: 0;
right: 0;
bottom: 0;
border-bottom: 1px solid #ebedf0;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
width: 100%;
}

.pop {
&-header {
height: 44px;
border-bottom: 1px solid #ebedf0;
background-color: #f7f8fa;
align-items: center;
display: flex;
justify-content: center;
font-size: 26rpx;

&-left {
width: 44px;
text-align: center;
color: #666;
}

&-right {
width: 44px;
text-align: center;
}

&-title {
flex: 4;
text-align: center;
color: 32rpx;
padding: 0 5px;
}
}

&-main {
overflow-x: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
height: 40vh;
}
}
</style>

+ 76
- 0
monitorMobile/uni_modules/jp-select-plus/components/jp-select-plus/loading.vue View File

@@ -0,0 +1,76 @@
<template>
<div class="template">
<view class="cartoon" >
<span class="char">拼</span>
<span class="char">命</span>
<span class="char">加</span>
<span class="char">载</span>
<span class="char">中</span>
<span class="char">.</span>
<span class="char">.</span>
<span class="char">.</span>
</view>
</div>
</template>

<style lang="scss" scoped>
.cartoon{
.char {
display: inline-block;
transform: translateY(8px);
width: 20px;
height: 20px;
border-radius: 3px;
animation: bounce 0.5s infinite alternate;
}
.char:nth-child(2) {
animation-delay: 0.1s;
}
.char:nth-child(3) {
animation-delay: 0.2s;
}
.char:nth-child(4) {
animation-delay: 0.3s;
}
.char:nth-child(5) {
animation-delay: 0.4s;
}
.char:nth-child(6) {
animation-delay: 0.5s;
}
.char:nth-child(7) {
animation-delay: 0.6s;
}
.char:nth-child(8) {
animation-delay: 0.7s;
}
@keyframes bounce {
0% {
transform: translateY(8px);
border-radius: 5px;
}
100% {
transform: translateY(-8px);
border-radius: 3px;
}
}
}
.template {
padding: 20px;
text-align: center;

.loader {
margin: 25px;
}
}

</style>

+ 78
- 0
monitorMobile/uni_modules/jp-select-plus/package.json View File

@@ -0,0 +1,78 @@
{
"id": "jp-select-plus",
"displayName": "数据选择器、单选多选组件、弹框选择、可配置搜索",
"version": "1.1",
"description": "本组件是jp-select升级组件,该组件功能更强大,更方便。拥有 单选、多选、搜索、弹框选择、多选拼接展示...采用v-model双向绑定操作,用户使用更加方便",
"keywords": [
"单选多选组件",
"数据选择器",
"弹出选择",
"select",
"搜索选择"
],
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"type": "component-vue"
},
"uni_modules": {
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

+ 86
- 0
monitorMobile/uni_modules/jp-select-plus/pages/index/index.vue View File

@@ -0,0 +1,86 @@
<template>
<view class="content">
<view class="hader">基础用法</view>
<jp-select-plus label="单选不带搜索" placeholder="请选择" v-model="va1" :list="listc"></jp-select-plus>
<jp-select-plus label="单选带搜索设置主题色" color="#f00"placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus>
<jp-select-plus label="多选带搜索-排列展示结果" placeholder="请选择" checkbox isSearch v-model="va2" :list="listc"></jp-select-plus>
<jp-select-plus label="多选带搜索-拼接展示结果" placeholder="请选择" isJoin checkbox isSearch v-model="va2" :list="listc"></jp-select-plus>
<jp-select-plus label="一行选择框" :isLineFeed="false" placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus>
<jp-select-plus label="改变选择主题颜色" placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus>
<view class="hader">进阶用法</view>
<jp-select-plus @onOpen="getList()" @onSearch="getList()" label="点击后才去后端拿数据,展示加载中" isSearchFun isLoading placeholder="请选择" isSearch v-model="va1" :list="list2"></jp-select-plus>
<view class="hader">只使用弹框</view>
<view class="but" @click="toOpen">
点击开启弹框选择数据
</view>
选中的数据:{{va3}}
<jp-select-plus ref="selectPlus" :isShow="false" v-model="va3" :list="listc"></jp-select-plus>
</view>
</template>
<script>
export default {
data() {
return {
va1: '',
va2: [],
va3: '',
listc: [{
code: 'CHN',
name: '中国'
}, {
name: '美国5',
code: 'USA'
}, {
name: '巴西',
code: 'BRA'
}, {
name: '日本',
code: 'JPN'
}, {
name: '英国',
code: 'ENG'
}, {
name: '法国',
code: 'FRA'
}, {
name: '小人国',
code: 'xr1'
}, {
name: '大人国',
code: 'xr2'
}, {
name: '中人国中人国中人国中人国中人国中人国中人国中人国中人国中人国中人国',
code: 'xr3'
}],
list2:[]
}
},
methods: {
toOpen(){
this.$refs.selectPlus.open()
},
getList(){
let that = this
setTimeout(()=>{
that.list2 = that.listc
},2000)
}
}
}
</script>
<style scoped lang="scss">
.content {
padding: 0 20px;
.but{
margin: 10rpx 25rpx;
background-color: #00aaff;
color: #fff;
text-align: center;
line-height: 80rpx;
}
.hader {
line-height: 80rpx;
font-weight: 800;
}
}
</style>

+ 160
- 0
monitorMobile/uni_modules/jp-select-plus/readme.md View File

@@ -0,0 +1,160 @@
## 阿里矢量图-图标组件
> **组件名:al-icon**

### 安装方式

本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。

###本组件是jp-select 升级组件,该组件能满足大多数开发需求
####拥有 单选、多选、搜索、弹框选择、多选拼接展示...采用v-model双向绑定操作,用户使用更加方便

### 用法

```html
<template>
<view class="content">
<view class="hader">基础用法</view>
<jp-select-plus label="单选不带搜索" placeholder="请选择" v-model="va1" :list="listc"></jp-select-plus>
<jp-select-plus label="单选带搜索设置主题色" color="#f00"placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus>
<jp-select-plus label="多选带搜索-排列展示结果" placeholder="请选择" checkbox isSearch v-model="va2" :list="listc"></jp-select-plus>
<jp-select-plus label="多选带搜索-拼接展示结果" placeholder="请选择" isJoin checkbox isSearch v-model="va2" :list="listc"></jp-select-plus>
<jp-select-plus label="一行选择框" :isLineFeed="false" placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus>
<jp-select-plus label="改变选择主题颜色" placeholder="请选择" isSearch v-model="va1" :list="listc"></jp-select-plus>
<view class="hader">进阶用法</view>
<jp-select-plus @onOpen="getList()" @onSearch="getList()" label="点击后才去后端拿数据,展示加载中" isSearchFun isLoading placeholder="请选择" isSearch v-model="va1" :list="list2"></jp-select-plus>
<view class="hader">只使用弹框</view>
<view class="but" @click="toOpen">
点击开启弹框选择数据
</view>
选中的数据:{{va3}}
<jp-select-plus ref="selectPlus" :isShow="false" v-model="va3" :list="listc"></jp-select-plus>
</view>
</template>
<script>
export default {
data() {
return {
va1: '',
va2: [],
va3: '',
listc: [{
code: 'CHN',
name: '中国'
}, {
name: '美国5',
code: 'USA'
}, {
name: '巴西',
code: 'BRA'
}, {
name: '日本',
code: 'JPN'
}, {
name: '英国',
code: 'ENG'
}, {
name: '法国',
code: 'FRA'
}, {
name: '小人国',
code: 'xr1'
}, {
name: '大人国',
code: 'xr2'
}, {
name: '中人国中人国中人国中人国中人国中人国中人国中人国中人国中人国中人国',
code: 'xr3'
}],
list2:[]
}
},
methods: {
toOpen(){
this.$refs.selectPlus.open()
},
getList(){
let that = this
setTimeout(()=>{
that.list2 = that.listc
},2000)
}
}
}
</script>
<style scoped lang="scss">
.content {
padding: 0 20px;
.but{
margin: 10rpx 25rpx;
background-color: #00aaff;
color: #fff;
text-align: center;
line-height: 80rpx;
}
.hader {
line-height: 80rpx;
font-weight: 800;
}
}
</style>
```

## API

### 参数
| 属性名 | 类型 | 默认值 | 说明 |
| | | | |
| list | Array| | 需要选择的数据(如果是对象需要配置 keys 和 showName 具体说明如下 ) |
| keys| String | code | 需要识别的code标识 |
| showName | String | name | 需要展示标识 |
| v-model | | | 双向绑定 |
| value | [String, Array] | | 初始值,多选时必须为数组 |
| label | String | | label名称 |
| labelColor | String | #646566 | label颜色 |
| labelWidth|String| '90px'| label宽度(当选项为一行时生效) |
| placeholder|String| '请选择'| placeholder |
| placeholderColor|String| '#999'| placeholder字体颜色 |
| isLineFeed|Boolean| true| 选项框是否为一行,默认独立开 |
| required|Boolean| false| 是否显示必填 |
| direction|String| left| 文字方向 默认左对齐 |
| color|String|'#00aaff' | 主题色 |
| alls|Boolean|false | 是否数据全部返回 |
| isoverflow|Boolean|false | 超出隐藏 |
| isJoin| Boolean|false | 多选时是否拼接展示 |
| isLine|Boolean| true | 底部是否有线条 |
| disabled|Boolean| fasle | 是否可以选择 |

### 弹框参数
| 属性名 | 类型 | 默认值 | 说明 |
| | | | |
| title | String| 请选择 |弹框名称 |
| cancelText| String | 取消 | 取消文字|
| confirmText | String | 确定 | 确定文字 |
| isSearch | Boolean| fasle | 是否开启头部搜索 |
| isSearchFun | Boolean| fasle | 点击头部搜索是是否调用外部方法 |
| isLoading | Boolean| fasle | 是否显示加载中 |

### 事件

| 事件名 | 类型 | 回调参数 | 说明 |
| | | | |
| input | function |当前选择的数据 key 数组| |
| toConfirm | function | 当前选择的数据 全数据 | 点击确认 |
| onOpen | function |无 | 点击选择框时回调 |
| cancel | function |无 | 点击取消 |
| input | function |无 | e 当前选择的数据 key 数组 |

### 方法

| 方法名| 说明 |
| | |
| open() | 打开弹框 |
| close() | 关闭弹框 |







+ 160
- 0
monitorMobile/uni_modules/uni-datetime-picker/changelog.md View File

@@ -0,0 +1,160 @@
## 2.2.34(2024-04-24)
- 新增 日期点击事件,在点击日期时会触发该事件。
## 2.2.33(2024-04-15)
- 修复 抖音小程序事件传递失效bug
## 2.2.32(2024-02-20)
- 修复 日历的close事件触发异常的bug [详情](https://github.com/dcloudio/uni-ui/issues/844)
## 2.2.31(2024-02-20)
- 修复 h5平台 右边日历的月份默认+1的bug [详情](https://github.com/dcloudio/uni-ui/issues/841)
## 2.2.30(2024-01-31)
- 修复 隐藏“秒”时,在IOS15及以下版本时出现 结束时间在开始时间之前 的bug [详情](https://github.com/dcloudio/uni-ui/issues/788)
## 2.2.29(2024-01-20)
- 新增 show事件,弹窗弹出时触发该事件 [详情](https://github.com/dcloudio/uni-app/issues/4694)
## 2.2.28(2024-01-18)
- 去除 noChange事件,当进行日期范围选择时,若只选了一天,则开始结束日期都为同一天 [详情](https://github.com/dcloudio/uni-ui/issues/815)
## 2.2.27(2024-01-10)
- 优化 增加noChange事件,当进行日期范围选择时,若有空值,则触发该事件 [详情](https://github.com/dcloudio/uni-ui/issues/815)
## 2.2.26(2024-01-08)
- 修复 字节小程序时间选择范围器失效问题 [详情](https://github.com/dcloudio/uni-ui/issues/834)
## 2.2.25(2023-10-18)
- 修复 PC端初次修改时间,开始时间未更新的Bug [详情](https://github.com/dcloudio/uni-ui/issues/737)
## 2.2.24(2023-06-02)
- 修复 部分情况修改时间,开始、结束时间显示异常的Bug [详情](https://ask.dcloud.net.cn/question/171146)
- 优化 当前月可以选择上月、下月的日期的Bug
## 2.2.23(2023-05-02)
- 修复 部分情况修改时间,开始时间未更新的Bug [详情](https://github.com/dcloudio/uni-ui/issues/737)
- 修复 部分平台及设备第一次点击无法显示弹框的Bug
- 修复 ios 日期格式未补零显示及使用异常的Bug [详情](https://ask.dcloud.net.cn/question/162979)
## 2.2.22(2023-03-30)
- 修复 日历 picker 修改年月后,自动选中当月1日的Bug [详情](https://ask.dcloud.net.cn/question/165937)
- 修复 小程序端 低版本 ios NaN的Bug [详情](https://ask.dcloud.net.cn/question/162979)
## 2.2.21(2023-02-20)
- 修复 firefox 浏览器显示区域点击无法拉起日历弹框的Bug [详情](https://ask.dcloud.net.cn/question/163362)
## 2.2.20(2023-02-17)
- 优化 值为空依然选中当天问题
- 优化 提供 default-value 属性支持配置选择器打开时默认显示的时间
- 优化 非范围选择未选择日期时间,点击确认按钮选中当前日期时间
- 优化 字节小程序日期时间范围选择,底部日期换行的Bug
## 2.2.19(2023-02-09)
- 修复 2.2.18 引起范围选择配置 end 选择无效的Bug [详情](https://github.com/dcloudio/uni-ui/issues/686)
## 2.2.18(2023-02-08)
- 修复 移动端范围选择change事件触发异常的Bug [详情](https://github.com/dcloudio/uni-ui/issues/684)
- 优化 PC端输入日期格式错误时返回当前日期时间
- 优化 PC端输入日期时间超出 start、end 限制的Bug
- 优化 移动端日期时间范围用法时间展示不完整问题
## 2.2.17(2023-02-04)
- 修复 小程序端绑定 Date 类型报错的Bug [详情](https://github.com/dcloudio/uni-ui/issues/679)
- 修复 vue3 time-picker 无法显示绑定时分秒的Bug
## 2.2.16(2023-02-02)
- 修复 字节小程序报错的Bug
## 2.2.15(2023-02-02)
- 修复 某些情况切换月份错误的Bug
## 2.2.14(2023-01-30)
- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/162033)
## 2.2.13(2023-01-10)
- 修复 多次加载组件造成内存占用的Bug
## 2.2.12(2022-12-01)
- 修复 vue3 下 i18n 国际化初始值不正确的Bug
## 2.2.11(2022-09-19)
- 修复 支付宝小程序样式错乱的Bug [详情](https://github.com/dcloudio/uni-app/issues/3861)
## 2.2.10(2022-09-19)
- 修复 反向选择日期范围,日期显示异常的Bug [详情](https://ask.dcloud.net.cn/question/153401?item_id=212892&rf=false)
## 2.2.9(2022-09-16)
- 可以使用 uni-scss 控制主题色
## 2.2.8(2022-09-08)
- 修复 close事件无效的Bug
## 2.2.7(2022-09-05)
- 修复 移动端 maskClick 无效的Bug [详情](https://ask.dcloud.net.cn/question/140824)
## 2.2.6(2022-06-30)
- 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致
## 2.2.5(2022-06-24)
- 修复 日历顶部年月及底部确认未国际化的Bug
## 2.2.4(2022-03-31)
- 修复 Vue3 下动态赋值,单选类型未响应的Bug
## 2.2.3(2022-03-28)
- 修复 Vue3 下动态赋值未响应的Bug
## 2.2.2(2021-12-10)
- 修复 clear-icon 属性在小程序平台不生效的Bug
## 2.2.1(2021-12-10)
- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的Bug
## 2.2.0(2021-11-19)
- 优化 组件UI,并提供设计资源 [详情](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移 [https://uniapp.dcloud.io/component/uniui/uni-datetime-picker](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
## 2.1.5(2021-11-09)
- 新增 提供组件设计资源,组件样式调整
## 2.1.4(2021-09-10)
- 修复 hide-second 在移动端的Bug
- 修复 单选赋默认值时,赋值日期未高亮的Bug
- 修复 赋默认值时,移动端未正确显示时间的Bug
## 2.1.3(2021-09-09)
- 新增 hide-second 属性,支持只使用时分,隐藏秒
## 2.1.2(2021-09-03)
- 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
- 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
- 优化 调整字号大小,美化日历界面
- 修复 因国际化导致的 placeholder 失效的Bug
## 2.1.1(2021-08-24)
- 新增 支持国际化
- 优化 范围选择器在 pc 端过宽的问题
## 2.1.0(2021-08-09)
- 新增 适配 vue3
## 2.0.19(2021-08-09)
- 新增 支持作为 uni-forms 子组件相关功能
- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的Bug
## 2.0.18(2021-08-05)
- 修复 type 属性动态赋值无效的Bug
- 修复 ‘确认’按钮被 tabbar 遮盖 bug
- 修复 组件未赋值时范围选左、右日历相同的Bug
## 2.0.17(2021-08-04)
- 修复 范围选未正确显示当前值的Bug
- 修复 h5 平台(移动端)报错 'cale' of undefined 的Bug
## 2.0.16(2021-07-21)
- 新增 return-type 属性支持返回 date 日期对象
## 2.0.15(2021-07-14)
- 修复 单选日期类型,初始赋值后不在当前日历的Bug
- 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效)
- 优化 移动端移除显示框的清空按钮,无实际用途
## 2.0.14(2021-07-14)
- 修复 组件赋值为空,界面未更新的Bug
- 修复 start 和 end 不能动态赋值的Bug
- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的Bug
## 2.0.13(2021-07-08)
- 修复 范围选择不能动态赋值的Bug
## 2.0.12(2021-07-08)
- 修复 范围选择的初始时间在一个月内时,造成无法选择的bug
## 2.0.11(2021-07-08)
- 优化 弹出层在超出视窗边缘定位不准确的问题
## 2.0.10(2021-07-08)
- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的Bug
- 优化 弹出层在超出视窗边缘被遮盖的问题
## 2.0.9(2021-07-07)
- 新增 maskClick 事件
- 修复 特殊情况日历 rpx 布局错误的Bug,rpx -> px
- 修复 范围选择时清空返回值不合理的bug,['', ''] -> []
## 2.0.8(2021-07-07)
- 新增 日期时间显示框支持插槽
## 2.0.7(2021-07-01)
- 优化 添加 uni-icons 依赖
## 2.0.6(2021-05-22)
- 修复 图标在小程序上不显示的Bug
- 优化 重命名引用组件,避免潜在组件命名冲突
## 2.0.5(2021-05-20)
- 优化 代码目录扁平化
## 2.0.4(2021-05-12)
- 新增 组件示例地址
## 2.0.3(2021-05-10)
- 修复 ios 下不识别 '-' 日期格式的Bug
- 优化 pc 下弹出层添加边框和阴影
## 2.0.2(2021-05-08)
- 修复 在 admin 中获取弹出层定位错误的bug
## 2.0.1(2021-05-08)
- 修复 type 属性向下兼容,默认值从 date 变更为 datetime
## 2.0.0(2021-04-30)
- 支持日历形式的日期+时间的范围选择
> 注意:此版本不向后兼容,不再支持单独时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)
## 1.0.6(2021-03-18)
- 新增 hide-second 属性,时间支持仅选择时、分
- 修复 选择跟显示的日期不一样的Bug
- 修复 chang事件触发2次的Bug
- 修复 分、秒 end 范围错误的Bug
- 优化 更好的 nvue 适配

+ 177
- 0
monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue View File

@@ -0,0 +1,177 @@
<template>
<view class="uni-calendar-item__weeks-box" :class="{
'uni-calendar-item--disable':weeks.disable,
'uni-calendar-item--before-checked-x':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked-x':weeks.afterMultiple,
}" @click="choiceDate(weeks)" @mouseenter="handleMousemove(weeks)">
<view class="uni-calendar-item__weeks-box-item" :class="{
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && (calendar.userChecked || !checkHover),
'uni-calendar-item--checked-range-text': checkHover,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
'uni-calendar-item--disable':weeks.disable,
}">
<text v-if="selected && weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
<text class="uni-calendar-item__weeks-box-text uni-calendar-item__weeks-box-text-disable uni-calendar-item--checked-text">{{weeks.date}}</text>
</view>
<view :class="{'uni-calendar-item--today': weeks.isToday}"></view>
</view>
</template>

<script>
export default {
props: {
weeks: {
type: Object,
default () {
return {}
}
},
calendar: {
type: Object,
default: () => {
return {}
}
},
selected: {
type: Array,
default: () => {
return []
}
},
checkHover: {
type: Boolean,
default: false
}
},
methods: {
choiceDate(weeks) {
this.$emit('change', weeks)
},
handleMousemove(weeks) {
this.$emit('handleMouse', weeks)
}
}
}
</script>

<style lang="scss" >
$uni-primary: #007aff !default;

.uni-calendar-item__weeks-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
margin: 1px 0;
position: relative;
}

.uni-calendar-item__weeks-box-text {
font-size: 14px;
// font-family: Lato-Bold, Lato;
font-weight: bold;
color: darken($color: $uni-primary, $amount: 40%);
}

.uni-calendar-item__weeks-box-item {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}


.uni-calendar-item__weeks-box-circle {
position: absolute;
top: 5px;
right: 5px;
width: 8px;
height: 8px;
border-radius: 8px;
background-color: #dd524d;

}

.uni-calendar-item__weeks-box .uni-calendar-item--disable {
cursor: default;
}

.uni-calendar-item--disable .uni-calendar-item__weeks-box-text-disable {
color: #D1D1D1;
}

.uni-calendar-item--today {
position: absolute;
top: 10px;
right: 17%;
background-color: #dd524d;
width:6px;
height: 6px;
border-radius: 50%;
}

.uni-calendar-item--extra {
color: #dd524d;
opacity: 0.8;
}

.uni-calendar-item__weeks-box .uni-calendar-item--checked {
background-color: $uni-primary;
border-radius: 50%;
box-sizing: border-box;
border: 3px solid #fff;
}

.uni-calendar-item--checked .uni-calendar-item--checked-text {
color: #fff;
}

.uni-calendar-item--multiple .uni-calendar-item--checked-range-text {
color: #333;
}

.uni-calendar-item--multiple {
background-color: #F6F7FC;
// color: #fff;
}

.uni-calendar-item--multiple .uni-calendar-item--before-checked,
.uni-calendar-item--multiple .uni-calendar-item--after-checked {
background-color: $uni-primary;
border-radius: 50%;
box-sizing: border-box;
border: 3px solid #F6F7FC;
}

.uni-calendar-item--before-checked .uni-calendar-item--checked-text,
.uni-calendar-item--after-checked .uni-calendar-item--checked-text {
color: #fff;
}

.uni-calendar-item--before-checked-x {
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
box-sizing: border-box;
background-color: #F6F7FC;
}

.uni-calendar-item--after-checked-x {
border-top-right-radius: 50px;
border-bottom-right-radius: 50px;
background-color: #F6F7FC;
}
</style>

+ 947
- 0
monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue View File

@@ -0,0 +1,947 @@
<template>
<view class="uni-calendar" @mouseleave="leaveCale">

<view v-if="!insert && show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}"
@click="maskClick"></view>

<view v-if="insert || show" class="uni-calendar__content"
:class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow, 'uni-calendar__content-mobile': aniMaskShow}">
<view class="uni-calendar__header" :class="{'uni-calendar__header-mobile' :!insert}">

<view class="uni-calendar__header-btn-box" @click.stop="changeMonth('pre')">
<view class="uni-calendar__header-btn uni-calendar--left"></view>
</view>

<picker mode="date" :value="date" fields="month" @change="bindDateChange">
<text
class="uni-calendar__header-text">{{ (nowDate.year||'') + yearText + ( nowDate.month||'') + monthText}}</text>
</picker>

<view class="uni-calendar__header-btn-box" @click.stop="changeMonth('next')">
<view class="uni-calendar__header-btn uni-calendar--right"></view>
</view>

<view v-if="!insert" class="dialog-close" @click="maskClick">
<view class="dialog-close-plus" data-id="close"></view>
<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
</view>
</view>
<view class="uni-calendar__box">

<view v-if="showMonth" class="uni-calendar__box-bg">
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
</view>

<view class="uni-calendar__weeks" style="padding-bottom: 7px;">
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{MONText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{TUEText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{WEDText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{THUText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{FRIText}}</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">{{SATText}}</text>
</view>
</view>

<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" :selected="selected"
:checkHover="range" @change="choiceDate" @handleMouse="handleMouse">
</calendar-item>
</view>
</view>
</view>

<view v-if="!insert && !range && hasTime" class="uni-date-changed uni-calendar--fixed-top"
style="padding: 0 80px;">
<view class="uni-date-changed--time-date">{{tempSingleDate ? tempSingleDate : selectDateText}}</view>
<time-picker type="time" :start="timepickerStartTime" :end="timepickerEndTime" v-model="time"
:disabled="!tempSingleDate" :border="false" :hide-second="hideSecond" class="time-picker-style">
</time-picker>
</view>

<view v-if="!insert && range && hasTime" class="uni-date-changed uni-calendar--fixed-top">
<view class="uni-date-changed--time-start">
<view class="uni-date-changed--time-date">{{tempRange.before ? tempRange.before : startDateText}}
</view>
<time-picker type="time" :start="timepickerStartTime" v-model="timeRange.startTime" :border="false"
:hide-second="hideSecond" :disabled="!tempRange.before" class="time-picker-style">
</time-picker>
</view>
<view style="line-height: 50px;">
<uni-icons type="arrowthinright" color="#999"></uni-icons>
</view>
<view class="uni-date-changed--time-end">
<view class="uni-date-changed--time-date">{{tempRange.after ? tempRange.after : endDateText}}</view>
<time-picker type="time" :end="timepickerEndTime" v-model="timeRange.endTime" :border="false"
:hide-second="hideSecond" :disabled="!tempRange.after" class="time-picker-style">
</time-picker>
</view>
</view>

<view v-if="!insert" class="uni-date-changed uni-date-btn--ok">
<view class="uni-datetime-picker--btn" @click="confirm">{{confirmText}}</view>
</view>
</view>
</view>
</template>

<script>
import {
Calendar,
getDate,
getTime
} from './util.js';
import calendarItem from './calendar-item.vue'
import timePicker from './time-picker.vue'

import {
initVueI18n
} from '@dcloudio/uni-i18n'
import i18nMessages from './i18n/index.js'
const {
t
} = initVueI18n(i18nMessages)

/**
* Calendar 日历
* @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
* @tutorial https://ext.dcloud.net.cn/plugin?id=56
* @property {String} date 自定义当前时间,默认为今天
* @property {String} startDate 日期选择范围-开始日期
* @property {String} endDate 日期选择范围-结束日期
* @property {Boolean} range 范围选择
* @property {Boolean} insert = [true|false] 插入模式,默认为false
* @value true 弹窗模式
* @value false 插入模式
* @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
* @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
* @property {Boolean} showMonth 是否选择月份为背景
* @property {[String} defaultValue 选择器打开时默认显示的时间
* @event {Function} change 日期改变,`insert :ture` 时生效
* @event {Function} confirm 确认选择`insert :false` 时生效
* @event {Function} monthSwitch 切换月份时触发
* @example <uni-calendar :insert="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
*/
export default {
components: {
calendarItem,
timePicker
},

options: {
// #ifdef MP-TOUTIAO
virtualHost: false,
// #endif
// #ifndef MP-TOUTIAO
virtualHost: true
// #endif
},
props: {
date: {
type: String,
default: ''
},
defTime: {
type: [String, Object],
default: ''
},
selectableTimes: {
type: [Object],
default () {
return {}
}
},
selected: {
type: Array,
default () {
return []
}
},
startDate: {
type: String,
default: ''
},
endDate: {
type: String,
default: ''
},
startPlaceholder: {
type: String,
default: ''
},
endPlaceholder: {
type: String,
default: ''
},
range: {
type: Boolean,
default: false
},
hasTime: {
type: Boolean,
default: false
},
insert: {
type: Boolean,
default: true
},
showMonth: {
type: Boolean,
default: true
},
clearDate: {
type: Boolean,
default: true
},
checkHover: {
type: Boolean,
default: true
},
hideSecond: {
type: [Boolean],
default: false
},
pleStatus: {
type: Object,
default () {
return {
before: '',
after: '',
data: [],
fulldate: ''
}
}
},
defaultValue: {
type: [String, Object, Array],
default: ''
}
},
data() {
return {
show: false,
weeks: [],
calendar: {},
nowDate: {},
aniMaskShow: false,
firstEnter: true,
time: '',
timeRange: {
startTime: '',
endTime: ''
},
tempSingleDate: '',
tempRange: {
before: '',
after: ''
}
}
},
watch: {
date: {
immediate: true,
handler(newVal) {
if (!this.range) {
this.tempSingleDate = newVal
setTimeout(() => {
this.init(newVal)
}, 100)
}
}
},
defTime: {
immediate: true,
handler(newVal) {
if (!this.range) {
this.time = newVal
} else {
this.timeRange.startTime = newVal.start
this.timeRange.endTime = newVal.end
}
}
},
startDate(val) {
// 字节小程序 watch 早于 created
if (!this.cale) {
return
}
this.cale.setStartDate(val)
this.cale.setDate(this.nowDate.fullDate)
this.weeks = this.cale.weeks
},
endDate(val) {
// 字节小程序 watch 早于 created
if (!this.cale) {
return
}
this.cale.setEndDate(val)
this.cale.setDate(this.nowDate.fullDate)
this.weeks = this.cale.weeks
},
selected(newVal) {
// 字节小程序 watch 早于 created
if (!this.cale) {
return
}
this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
this.weeks = this.cale.weeks
},
pleStatus: {
immediate: true,
handler(newVal) {
const {
before,
after,
fulldate,
which
} = newVal
this.tempRange.before = before
this.tempRange.after = after
setTimeout(() => {
if (fulldate) {
this.cale.setHoverMultiple(fulldate)
if (before && after) {
this.cale.lastHover = true
if (this.rangeWithinMonth(after, before)) return
this.setDate(before)
} else {
this.cale.setMultiple(fulldate)
this.setDate(this.nowDate.fullDate)
this.calendar.fullDate = ''
this.cale.lastHover = false
}
} else {
// 字节小程序 watch 早于 created
if (!this.cale) {
return
}

this.cale.setDefaultMultiple(before, after)
if (which === 'left' && before) {
this.setDate(before)
this.weeks = this.cale.weeks
} else if (after) {
this.setDate(after)
this.weeks = this.cale.weeks
}
this.cale.lastHover = true
}
}, 16)
}
}
},
computed: {
timepickerStartTime() {
const activeDate = this.range ? this.tempRange.before : this.calendar.fullDate
return activeDate === this.startDate ? this.selectableTimes.start : ''
},
timepickerEndTime() {
const activeDate = this.range ? this.tempRange.after : this.calendar.fullDate
return activeDate === this.endDate ? this.selectableTimes.end : ''
},
/**
* for i18n
*/
selectDateText() {
return t("uni-datetime-picker.selectDate")
},
startDateText() {
return this.startPlaceholder || t("uni-datetime-picker.startDate")
},
endDateText() {
return this.endPlaceholder || t("uni-datetime-picker.endDate")
},
okText() {
return t("uni-datetime-picker.ok")
},
yearText() {
return t("uni-datetime-picker.year")
},
monthText() {
return t("uni-datetime-picker.month")
},
MONText() {
return t("uni-calender.MON")
},
TUEText() {
return t("uni-calender.TUE")
},
WEDText() {
return t("uni-calender.WED")
},
THUText() {
return t("uni-calender.THU")
},
FRIText() {
return t("uni-calender.FRI")
},
SATText() {
return t("uni-calender.SAT")
},
SUNText() {
return t("uni-calender.SUN")
},
confirmText() {
return t("uni-calender.confirm")
},
},
created() {
// 获取日历方法实例
this.cale = new Calendar({
selected: this.selected,
startDate: this.startDate,
endDate: this.endDate,
range: this.range,
})
// 选中某一天
this.init(this.date)
},
methods: {
leaveCale() {
this.firstEnter = true
},
handleMouse(weeks) {
if (weeks.disable) return
if (this.cale.lastHover) return
let {
before,
after
} = this.cale.multipleStatus
if (!before) return
this.calendar = weeks
// 设置范围选
this.cale.setHoverMultiple(this.calendar.fullDate)
this.weeks = this.cale.weeks
// hover时,进入一个日历,更新另一个
if (this.firstEnter) {
this.$emit('firstEnterCale', this.cale.multipleStatus)
this.firstEnter = false
}
},
rangeWithinMonth(A, B) {
const [yearA, monthA] = A.split('-')
const [yearB, monthB] = B.split('-')
return yearA === yearB && monthA === monthB
},
// 蒙版点击事件
maskClick() {
this.close()
this.$emit('maskClose')
},

clearCalender() {
if (this.range) {
this.timeRange.startTime = ''
this.timeRange.endTime = ''
this.tempRange.before = ''
this.tempRange.after = ''
this.cale.multipleStatus.before = ''
this.cale.multipleStatus.after = ''
this.cale.multipleStatus.data = []
this.cale.lastHover = false
} else {
this.time = ''
this.tempSingleDate = ''
}
this.calendar.fullDate = ''
this.setDate(new Date())
},

bindDateChange(e) {
const value = e.detail.value + '-1'
this.setDate(value)
},
/**
* 初始化日期显示
* @param {Object} date
*/
init(date) {
// 字节小程序 watch 早于 created
if (!this.cale) {
return
}
this.cale.setDate(date || new Date())
this.weeks = this.cale.weeks
this.nowDate = this.cale.getInfo(date)
this.calendar = {
...this.nowDate
}
if (!date) {
// 优化date为空默认不选中今天
this.calendar.fullDate = ''
if (this.defaultValue && !this.range) {
// 暂时只支持移动端非范围选择
const defaultDate = new Date(this.defaultValue)
const fullDate = getDate(defaultDate)
const year = defaultDate.getFullYear()
const month = defaultDate.getMonth() + 1
const date = defaultDate.getDate()
const day = defaultDate.getDay()
this.calendar = {
fullDate,
year,
month,
date,
day
},
this.tempSingleDate = fullDate
this.time = getTime(defaultDate, this.hideSecond)
}
}
},
/**
* 打开日历弹窗
*/
open() {
// 弹窗模式并且清理数据
if (this.clearDate && !this.insert) {
this.cale.cleanMultipleStatus()
this.init(this.date)
}
this.show = true
this.$nextTick(() => {
setTimeout(() => {
this.aniMaskShow = true
}, 50)
})
},
/**
* 关闭日历弹窗
*/
close() {
this.aniMaskShow = false
this.$nextTick(() => {
setTimeout(() => {
this.show = false
this.$emit('close')
}, 300)
})
},
/**
* 确认按钮
*/
confirm() {
this.setEmit('confirm')
this.close()
},
/**
* 变化触发
*/
change(isSingleChange) {
if (!this.insert && !isSingleChange) return
this.setEmit('change')
},
/**
* 选择月份触发
*/
monthSwitch() {
let {
year,
month
} = this.nowDate
this.$emit('monthSwitch', {
year,
month: Number(month)
})
},
/**
* 派发事件
* @param {Object} name
*/
setEmit(name) {
if (!this.range) {
if (!this.calendar.fullDate) {
this.calendar = this.cale.getInfo(new Date())
this.tempSingleDate = this.calendar.fullDate
}
if (this.hasTime && !this.time) {
this.time = getTime(new Date(), this.hideSecond)
}
}
let {
year,
month,
date,
fullDate,
extraInfo
} = this.calendar
this.$emit(name, {
range: this.cale.multipleStatus,
year,
month,
date,
time: this.time,
timeRange: this.timeRange,
fulldate: fullDate,
extraInfo: extraInfo || {}
})
},
/**
* 选择天触发
* @param {Object} weeks
*/
choiceDate(weeks) {
if (weeks.disable) return
this.calendar = weeks
this.calendar.userChecked = true
// 设置多选
this.cale.setMultiple(this.calendar.fullDate, true)
this.weeks = this.cale.weeks
this.tempSingleDate = this.calendar.fullDate
const beforeDate = new Date(this.cale.multipleStatus.before).getTime()
const afterDate = new Date(this.cale.multipleStatus.after).getTime()
if (beforeDate > afterDate && afterDate) {
this.tempRange.before = this.cale.multipleStatus.after
this.tempRange.after = this.cale.multipleStatus.before
} else {
this.tempRange.before = this.cale.multipleStatus.before
this.tempRange.after = this.cale.multipleStatus.after
}
this.change(true)
},
changeMonth(type) {
let newDate
if (type === 'pre') {
newDate = this.cale.getPreMonthObj(this.nowDate.fullDate).fullDate
} else if (type === 'next') {
newDate = this.cale.getNextMonthObj(this.nowDate.fullDate).fullDate
}

this.setDate(newDate)
this.monthSwitch()
},
/**
* 设置日期
* @param {Object} date
*/
setDate(date) {
this.cale.setDate(date)
this.weeks = this.cale.weeks
this.nowDate = this.cale.getInfo(date)
}
}
}
</script>

<style lang="scss">
$uni-primary: #007aff !default;

.uni-calendar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}

.uni-calendar__mask {
position: fixed;
bottom: 0;
top: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.4);
transition-property: opacity;
transition-duration: 0.3s;
opacity: 0;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}

.uni-calendar--mask-show {
opacity: 1
}

.uni-calendar--fixed {
position: fixed;
bottom: calc(var(--window-bottom));
left: 0;
right: 0;
transition-property: transform;
transition-duration: 0.3s;
transform: translateY(460px);
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}

.uni-calendar--ani-show {
transform: translateY(0);
}

.uni-calendar__content {
background-color: #fff;
}

.uni-calendar__content-mobile {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
box-shadow: 0px 0px 5px 3px rgba(0, 0, 0, 0.1);
}

.uni-calendar__header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
height: 50px;
}

.uni-calendar__header-mobile {
padding: 10px;
padding-bottom: 0;
}

.uni-calendar--fixed-top {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: space-between;
border-top-color: rgba(0, 0, 0, 0.4);
border-top-style: solid;
border-top-width: 1px;
}

.uni-calendar--fixed-width {
width: 50px;
}

.uni-calendar__backtoday {
position: absolute;
right: 0;
top: 25rpx;
padding: 0 5px;
padding-left: 10px;
height: 25px;
line-height: 25px;
font-size: 12px;
border-top-left-radius: 25px;
border-bottom-left-radius: 25px;
color: #fff;
background-color: #f1f1f1;
}

.uni-calendar__header-text {
text-align: center;
width: 100px;
font-size: 15px;
color: #666;
}

.uni-calendar__button-text {
text-align: center;
width: 100px;
font-size: 14px;
color: $uni-primary;
/* #ifndef APP-NVUE */
letter-spacing: 3px;
/* #endif */
}

.uni-calendar__header-btn-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
}

.uni-calendar__header-btn {
width: 9px;
height: 9px;
border-left-color: #808080;
border-left-style: solid;
border-left-width: 1px;
border-top-color: #555555;
border-top-style: solid;
border-top-width: 1px;
}

.uni-calendar--left {
transform: rotate(-45deg);
}

.uni-calendar--right {
transform: rotate(135deg);
}


.uni-calendar__weeks {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}

.uni-calendar__weeks-item {
flex: 1;
}

.uni-calendar__weeks-day {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
height: 40px;
border-bottom-color: #F5F5F5;
border-bottom-style: solid;
border-bottom-width: 1px;
}

.uni-calendar__weeks-day-text {
font-size: 12px;
color: #B2B2B2;
}

.uni-calendar__box {
position: relative;
// padding: 0 10px;
padding-bottom: 7px;
}

.uni-calendar__box-bg {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}

.uni-calendar__box-bg-text {
font-size: 200px;
font-weight: bold;
color: #999;
opacity: 0.1;
text-align: center;
/* #ifndef APP-NVUE */
line-height: 1;
/* #endif */
}

.uni-date-changed {
padding: 0 10px;
// line-height: 50px;
text-align: center;
color: #333;
border-top-color: #DCDCDC;
;
border-top-style: solid;
border-top-width: 1px;
flex: 1;
}

.uni-date-btn--ok {
padding: 20px 15px;
}

.uni-date-changed--time-start {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
}

.uni-date-changed--time-end {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
}

.uni-date-changed--time-date {
color: #999;
line-height: 50px;
/* #ifdef MP-TOUTIAO */
font-size: 16px;
/* #endif */
margin-right: 5px;
// opacity: 0.6;
}

.time-picker-style {
// width: 62px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center
}

.mr-10 {
margin-right: 10px;
}

.dialog-close {
position: absolute;
top: 0;
right: 0;
bottom: 0;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 0 25px;
margin-top: 10px;
}

.dialog-close-plus {
width: 16px;
height: 2px;
background-color: #737987;
border-radius: 2px;
transform: rotate(45deg);
}

.dialog-close-rotate {
position: absolute;
transform: rotate(-45deg);
}

.uni-datetime-picker--btn {
border-radius: 100px;
height: 40px;
line-height: 40px;
background-color: $uni-primary;
color: #fff;
font-size: 16px;
letter-spacing: 2px;
}

/* #ifndef APP-NVUE */
.uni-datetime-picker--btn:active {
opacity: 0.7;
}

/* #endif */
</style>

+ 22
- 0
monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json View File

@@ -0,0 +1,22 @@
{
"uni-datetime-picker.selectDate": "select date",
"uni-datetime-picker.selectTime": "select time",
"uni-datetime-picker.selectDateTime": "select date and time",
"uni-datetime-picker.startDate": "start date",
"uni-datetime-picker.endDate": "end date",
"uni-datetime-picker.startTime": "start time",
"uni-datetime-picker.endTime": "end time",
"uni-datetime-picker.ok": "ok",
"uni-datetime-picker.clear": "clear",
"uni-datetime-picker.cancel": "cancel",
"uni-datetime-picker.year": "-",
"uni-datetime-picker.month": "",
"uni-calender.MON": "MON",
"uni-calender.TUE": "TUE",
"uni-calender.WED": "WED",
"uni-calender.THU": "THU",
"uni-calender.FRI": "FRI",
"uni-calender.SAT": "SAT",
"uni-calender.SUN": "SUN",
"uni-calender.confirm": "confirm"
}

+ 8
- 0
monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js View File

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

+ 22
- 0
monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json View File

@@ -0,0 +1,22 @@
{
"uni-datetime-picker.selectDate": "选择日期",
"uni-datetime-picker.selectTime": "选择时间",
"uni-datetime-picker.selectDateTime": "选择日期时间",
"uni-datetime-picker.startDate": "开始日期",
"uni-datetime-picker.endDate": "结束日期",
"uni-datetime-picker.startTime": "开始时间",
"uni-datetime-picker.endTime": "结束时间",
"uni-datetime-picker.ok": "确定",
"uni-datetime-picker.clear": "清除",
"uni-datetime-picker.cancel": "取消",
"uni-datetime-picker.year": "年",
"uni-datetime-picker.month": "月",
"uni-calender.SUN": "日",
"uni-calender.MON": "一",
"uni-calender.TUE": "二",
"uni-calender.WED": "三",
"uni-calender.THU": "四",
"uni-calender.FRI": "五",
"uni-calender.SAT": "六",
"uni-calender.confirm": "确认"
}

+ 22
- 0
monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json View File

@@ -0,0 +1,22 @@
{
"uni-datetime-picker.selectDate": "選擇日期",
"uni-datetime-picker.selectTime": "選擇時間",
"uni-datetime-picker.selectDateTime": "選擇日期時間",
"uni-datetime-picker.startDate": "開始日期",
"uni-datetime-picker.endDate": "結束日期",
"uni-datetime-picker.startTime": "開始时间",
"uni-datetime-picker.endTime": "結束时间",
"uni-datetime-picker.ok": "確定",
"uni-datetime-picker.clear": "清除",
"uni-datetime-picker.cancel": "取消",
"uni-datetime-picker.year": "年",
"uni-datetime-picker.month": "月",
"uni-calender.SUN": "日",
"uni-calender.MON": "一",
"uni-calender.TUE": "二",
"uni-calender.WED": "三",
"uni-calender.THU": "四",
"uni-calender.FRI": "五",
"uni-calender.SAT": "六",
"uni-calender.confirm": "確認"
}

+ 940
- 0
monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue View File

@@ -0,0 +1,940 @@
<template>
<view class="uni-datetime-picker">
<view @click="initTimePicker">
<slot>
<view class="uni-datetime-picker-timebox-pointer"
:class="{'uni-datetime-picker-disabled': disabled, 'uni-datetime-picker-timebox': border}">
<text class="uni-datetime-picker-text">{{time}}</text>
<view v-if="!time" class="uni-datetime-picker-time">
<text class="uni-datetime-picker-text">{{selectTimeText}}</text>
</view>
</view>
</slot>
</view>
<view v-if="visible" id="mask" class="uni-datetime-picker-mask" @click="tiggerTimePicker"></view>
<view v-if="visible" class="uni-datetime-picker-popup" :class="[dateShow && timeShow ? '' : 'fix-nvue-height']"
:style="fixNvueBug">
<view class="uni-title">
<text class="uni-datetime-picker-text">{{selectTimeText}}</text>
</view>
<view v-if="dateShow" class="uni-datetime-picker__container-box">
<picker-view class="uni-datetime-picker-view" :indicator-style="indicatorStyle" :value="ymd"
@change="bindDateChange">
<picker-view-column>
<view class="uni-datetime-picker-item" v-for="(item,index) in years" :key="index">
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
</view>
</picker-view-column>
<picker-view-column>
<view class="uni-datetime-picker-item" v-for="(item,index) in months" :key="index">
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
</view>
</picker-view-column>
<picker-view-column>
<view class="uni-datetime-picker-item" v-for="(item,index) in days" :key="index">
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
</view>
</picker-view-column>
</picker-view>
<!-- 兼容 nvue 不支持伪类 -->
<text class="uni-datetime-picker-sign sign-left">-</text>
<text class="uni-datetime-picker-sign sign-right">-</text>
</view>
<view v-if="timeShow" class="uni-datetime-picker__container-box">
<picker-view class="uni-datetime-picker-view" :class="[hideSecond ? 'time-hide-second' : '']"
:indicator-style="indicatorStyle" :value="hms" @change="bindTimeChange">
<picker-view-column>
<view class="uni-datetime-picker-item" v-for="(item,index) in hours" :key="index">
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
</view>
</picker-view-column>
<picker-view-column>
<view class="uni-datetime-picker-item" v-for="(item,index) in minutes" :key="index">
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
</view>
</picker-view-column>
<picker-view-column v-if="!hideSecond">
<view class="uni-datetime-picker-item" v-for="(item,index) in seconds" :key="index">
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
</view>
</picker-view-column>
</picker-view>
<!-- 兼容 nvue 不支持伪类 -->
<text class="uni-datetime-picker-sign" :class="[hideSecond ? 'sign-center' : 'sign-left']">:</text>
<text v-if="!hideSecond" class="uni-datetime-picker-sign sign-right">:</text>
</view>
<view class="uni-datetime-picker-btn">
<view @click="clearTime">
<text class="uni-datetime-picker-btn-text">{{clearText}}</text>
</view>
<view class="uni-datetime-picker-btn-group">
<view class="uni-datetime-picker-cancel" @click="tiggerTimePicker">
<text class="uni-datetime-picker-btn-text">{{cancelText}}</text>
</view>
<view @click="setTime">
<text class="uni-datetime-picker-btn-text">{{okText}}</text>
</view>
</view>
</view>
</view>
</view>
</template>

<script>
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import i18nMessages from './i18n/index.js'
const {
t
} = initVueI18n(i18nMessages)
import {
fixIosDateFormat
} from './util'

/**
* DatetimePicker 时间选择器
* @description 可以同时选择日期和时间的选择器
* @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
* @property {String} type = [datetime | date | time] 显示模式
* @property {Boolean} multiple = [true|false] 是否多选
* @property {String|Number} value 默认值
* @property {String|Number} start 起始日期或时间
* @property {String|Number} end 起始日期或时间
* @property {String} return-type = [timestamp | string]
* @event {Function} change 选中发生变化触发
*/

export default {
name: 'UniDatetimePicker',
data() {
return {
indicatorStyle: `height: 50px;`,
visible: false,
fixNvueBug: {},
dateShow: true,
timeShow: true,
title: '日期和时间',
// 输入框当前时间
time: '',
// 当前的年月日时分秒
year: 1920,
month: 0,
day: 0,
hour: 0,
minute: 0,
second: 0,
// 起始时间
startYear: 1920,
startMonth: 1,
startDay: 1,
startHour: 0,
startMinute: 0,
startSecond: 0,
// 结束时间
endYear: 2120,
endMonth: 12,
endDay: 31,
endHour: 23,
endMinute: 59,
endSecond: 59,
}
},
options: {
// #ifdef MP-TOUTIAO
virtualHost: false,
// #endif
// #ifndef MP-TOUTIAO
virtualHost: true
// #endif
},
props: {
type: {
type: String,
default: 'datetime'
},
value: {
type: [String, Number],
default: ''
},
modelValue: {
type: [String, Number],
default: ''
},
start: {
type: [Number, String],
default: ''
},
end: {
type: [Number, String],
default: ''
},
returnType: {
type: String,
default: 'string'
},
disabled: {
type: [Boolean, String],
default: false
},
border: {
type: [Boolean, String],
default: true
},
hideSecond: {
type: [Boolean, String],
default: false
}
},
watch: {
// #ifndef VUE3
value: {
handler(newVal) {
if (newVal) {
this.parseValue(fixIosDateFormat(newVal))
this.initTime(false)
} else {
this.time = ''
this.parseValue(Date.now())
}
},
immediate: true
},
// #endif
// #ifdef VUE3
modelValue: {
handler(newVal) {
if (newVal) {
this.parseValue(fixIosDateFormat(newVal))
this.initTime(false)
} else {
this.time = ''
this.parseValue(Date.now())
}
},
immediate: true
},
// #endif
type: {
handler(newValue) {
if (newValue === 'date') {
this.dateShow = true
this.timeShow = false
this.title = '日期'
} else if (newValue === 'time') {
this.dateShow = false
this.timeShow = true
this.title = '时间'
} else {
this.dateShow = true
this.timeShow = true
this.title = '日期和时间'
}
},
immediate: true
},
start: {
handler(newVal) {
this.parseDatetimeRange(fixIosDateFormat(newVal), 'start')
},
immediate: true
},
end: {
handler(newVal) {
this.parseDatetimeRange(fixIosDateFormat(newVal), 'end')
},
immediate: true
},

// 月、日、时、分、秒可选范围变化后,检查当前值是否在范围内,不在则当前值重置为可选范围第一项
months(newVal) {
this.checkValue('month', this.month, newVal)
},
days(newVal) {
this.checkValue('day', this.day, newVal)
},
hours(newVal) {
this.checkValue('hour', this.hour, newVal)
},
minutes(newVal) {
this.checkValue('minute', this.minute, newVal)
},
seconds(newVal) {
this.checkValue('second', this.second, newVal)
}
},
computed: {
// 当前年、月、日、时、分、秒选择范围
years() {
return this.getCurrentRange('year')
},

months() {
return this.getCurrentRange('month')
},

days() {
return this.getCurrentRange('day')
},

hours() {
return this.getCurrentRange('hour')
},

minutes() {
return this.getCurrentRange('minute')
},

seconds() {
return this.getCurrentRange('second')
},

// picker 当前值数组
ymd() {
return [this.year - this.minYear, this.month - this.minMonth, this.day - this.minDay]
},
hms() {
return [this.hour - this.minHour, this.minute - this.minMinute, this.second - this.minSecond]
},

// 当前 date 是 start
currentDateIsStart() {
return this.year === this.startYear && this.month === this.startMonth && this.day === this.startDay
},

// 当前 date 是 end
currentDateIsEnd() {
return this.year === this.endYear && this.month === this.endMonth && this.day === this.endDay
},

// 当前年、月、日、时、分、秒的最小值和最大值
minYear() {
return this.startYear
},
maxYear() {
return this.endYear
},
minMonth() {
if (this.year === this.startYear) {
return this.startMonth
} else {
return 1
}
},
maxMonth() {
if (this.year === this.endYear) {
return this.endMonth
} else {
return 12
}
},
minDay() {
if (this.year === this.startYear && this.month === this.startMonth) {
return this.startDay
} else {
return 1
}
},
maxDay() {
if (this.year === this.endYear && this.month === this.endMonth) {
return this.endDay
} else {
return this.daysInMonth(this.year, this.month)
}
},
minHour() {
if (this.type === 'datetime') {
if (this.currentDateIsStart) {
return this.startHour
} else {
return 0
}
}
if (this.type === 'time') {
return this.startHour
}
},
maxHour() {
if (this.type === 'datetime') {
if (this.currentDateIsEnd) {
return this.endHour
} else {
return 23
}
}
if (this.type === 'time') {
return this.endHour
}
},
minMinute() {
if (this.type === 'datetime') {
if (this.currentDateIsStart && this.hour === this.startHour) {
return this.startMinute
} else {
return 0
}
}
if (this.type === 'time') {
if (this.hour === this.startHour) {
return this.startMinute
} else {
return 0
}
}
},
maxMinute() {
if (this.type === 'datetime') {
if (this.currentDateIsEnd && this.hour === this.endHour) {
return this.endMinute
} else {
return 59
}
}
if (this.type === 'time') {
if (this.hour === this.endHour) {
return this.endMinute
} else {
return 59
}
}
},
minSecond() {
if (this.type === 'datetime') {
if (this.currentDateIsStart && this.hour === this.startHour && this.minute === this.startMinute) {
return this.startSecond
} else {
return 0
}
}
if (this.type === 'time') {
if (this.hour === this.startHour && this.minute === this.startMinute) {
return this.startSecond
} else {
return 0
}
}
},
maxSecond() {
if (this.type === 'datetime') {
if (this.currentDateIsEnd && this.hour === this.endHour && this.minute === this.endMinute) {
return this.endSecond
} else {
return 59
}
}
if (this.type === 'time') {
if (this.hour === this.endHour && this.minute === this.endMinute) {
return this.endSecond
} else {
return 59
}
}
},

/**
* for i18n
*/
selectTimeText() {
return t("uni-datetime-picker.selectTime")
},
okText() {
return t("uni-datetime-picker.ok")
},
clearText() {
return t("uni-datetime-picker.clear")
},
cancelText() {
return t("uni-datetime-picker.cancel")
}
},

mounted() {
// #ifdef APP-NVUE
const res = uni.getSystemInfoSync();
this.fixNvueBug = {
top: res.windowHeight / 2,
left: res.windowWidth / 2
}
// #endif
},

methods: {
/**
* @param {Object} item
* 小于 10 在前面加个 0
*/

lessThanTen(item) {
return item < 10 ? '0' + item : item
},

/**
* 解析时分秒字符串,例如:00:00:00
* @param {String} timeString
*/
parseTimeType(timeString) {
if (timeString) {
let timeArr = timeString.split(':')
this.hour = Number(timeArr[0])
this.minute = Number(timeArr[1])
this.second = Number(timeArr[2])
}
},

/**
* 解析选择器初始值,类型可以是字符串、时间戳,例如:2000-10-02、'08:30:00'、 1610695109000
* @param {String | Number} datetime
*/
initPickerValue(datetime) {
let defaultValue = null
if (datetime) {
defaultValue = this.compareValueWithStartAndEnd(datetime, this.start, this.end)
} else {
defaultValue = Date.now()
defaultValue = this.compareValueWithStartAndEnd(defaultValue, this.start, this.end)
}
this.parseValue(defaultValue)
},

/**
* 初始值规则:
* - 用户设置初始值 value
* - 设置了起始时间 start、终止时间 end,并 start < value < end,初始值为 value, 否则初始值为 start
* - 只设置了起始时间 start,并 start < value,初始值为 value,否则初始值为 start
* - 只设置了终止时间 end,并 value < end,初始值为 value,否则初始值为 end
* - 无起始终止时间,则初始值为 value
* - 无初始值 value,则初始值为当前本地时间 Date.now()
* @param {Object} value
* @param {Object} dateBase
*/
compareValueWithStartAndEnd(value, start, end) {
let winner = null
value = this.superTimeStamp(value)
start = this.superTimeStamp(start)
end = this.superTimeStamp(end)

if (start && end) {
if (value < start) {
winner = new Date(start)
} else if (value > end) {
winner = new Date(end)
} else {
winner = new Date(value)
}
} else if (start && !end) {
winner = start <= value ? new Date(value) : new Date(start)
} else if (!start && end) {
winner = value <= end ? new Date(value) : new Date(end)
} else {
winner = new Date(value)
}

return winner
},

/**
* 转换为可比较的时间戳,接受日期、时分秒、时间戳
* @param {Object} value
*/
superTimeStamp(value) {
let dateBase = ''
if (this.type === 'time' && value && typeof value === 'string') {
const now = new Date()
const year = now.getFullYear()
const month = now.getMonth() + 1
const day = now.getDate()
dateBase = year + '/' + month + '/' + day + ' '
}
if (Number(value)) {
value = parseInt(value)
dateBase = 0
}
return this.createTimeStamp(dateBase + value)
},

/**
* 解析默认值 value,字符串、时间戳
* @param {Object} defaultTime
*/
parseValue(value) {
if (!value) {
return
}
if (this.type === 'time' && typeof value === "string") {
this.parseTimeType(value)
} else {
let defaultDate = null
defaultDate = new Date(value)
if (this.type !== 'time') {
this.year = defaultDate.getFullYear()
this.month = defaultDate.getMonth() + 1
this.day = defaultDate.getDate()
}
if (this.type !== 'date') {
this.hour = defaultDate.getHours()
this.minute = defaultDate.getMinutes()
this.second = defaultDate.getSeconds()
}
}
if (this.hideSecond) {
this.second = 0
}
},

/**
* 解析可选择时间范围 start、end,年月日字符串、时间戳
* @param {Object} defaultTime
*/
parseDatetimeRange(point, pointType) {
// 时间为空,则重置为初始值
if (!point) {
if (pointType === 'start') {
this.startYear = 1920
this.startMonth = 1
this.startDay = 1
this.startHour = 0
this.startMinute = 0
this.startSecond = 0
}
if (pointType === 'end') {
this.endYear = 2120
this.endMonth = 12
this.endDay = 31
this.endHour = 23
this.endMinute = 59
this.endSecond = 59
}
return
}
if (this.type === 'time') {
const pointArr = point.split(':')
this[pointType + 'Hour'] = Number(pointArr[0])
this[pointType + 'Minute'] = Number(pointArr[1])
this[pointType + 'Second'] = Number(pointArr[2])
} else {
if (!point) {
pointType === 'start' ? this.startYear = this.year - 60 : this.endYear = this.year + 60
return
}
if (Number(point)) {
point = parseInt(point)
}
// datetime 的 end 没有时分秒, 则不限制
const hasTime = /[0-9]:[0-9]/
if (this.type === 'datetime' && pointType === 'end' && typeof point === 'string' && !hasTime.test(
point)) {
point = point + ' 23:59:59'
}
const pointDate = new Date(point)
this[pointType + 'Year'] = pointDate.getFullYear()
this[pointType + 'Month'] = pointDate.getMonth() + 1
this[pointType + 'Day'] = pointDate.getDate()
if (this.type === 'datetime') {
this[pointType + 'Hour'] = pointDate.getHours()
this[pointType + 'Minute'] = pointDate.getMinutes()
this[pointType + 'Second'] = pointDate.getSeconds()
}
}
},

// 获取 年、月、日、时、分、秒 当前可选范围
getCurrentRange(value) {
const range = []
for (let i = this['min' + this.capitalize(value)]; i <= this['max' + this.capitalize(value)]; i++) {
range.push(i)
}
return range
},

// 字符串首字母大写
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
},

// 检查当前值是否在范围内,不在则当前值重置为可选范围第一项
checkValue(name, value, values) {
if (values.indexOf(value) === -1) {
this[name] = values[0]
}
},

// 每个月的实际天数
daysInMonth(year, month) { // Use 1 for January, 2 for February, etc.
return new Date(year, month, 0).getDate();
},

/**
* 生成时间戳
* @param {Object} time
*/
createTimeStamp(time) {
if (!time) return
if (typeof time === "number") {
return time
} else {
time = time.replace(/-/g, '/')
if (this.type === 'date') {
time = time + ' ' + '00:00:00'
}
return Date.parse(time)
}
},

/**
* 生成日期或时间的字符串
*/
createDomSting() {
const yymmdd = this.year +
'-' +
this.lessThanTen(this.month) +
'-' +
this.lessThanTen(this.day)

let hhmmss = this.lessThanTen(this.hour) +
':' +
this.lessThanTen(this.minute)

if (!this.hideSecond) {
hhmmss = hhmmss + ':' + this.lessThanTen(this.second)
}

if (this.type === 'date') {
return yymmdd
} else if (this.type === 'time') {
return hhmmss
} else {
return yymmdd + ' ' + hhmmss
}
},

/**
* 初始化返回值,并抛出 change 事件
*/
initTime(emit = true) {
this.time = this.createDomSting()
if (!emit) return
if (this.returnType === 'timestamp' && this.type !== 'time') {
this.$emit('change', this.createTimeStamp(this.time))
this.$emit('input', this.createTimeStamp(this.time))
this.$emit('update:modelValue', this.createTimeStamp(this.time))
} else {
this.$emit('change', this.time)
this.$emit('input', this.time)
this.$emit('update:modelValue', this.time)
}
},

/**
* 用户选择日期或时间更新 data
* @param {Object} e
*/
bindDateChange(e) {
const val = e.detail.value
this.year = this.years[val[0]]
this.month = this.months[val[1]]
this.day = this.days[val[2]]
},
bindTimeChange(e) {
const val = e.detail.value
this.hour = this.hours[val[0]]
this.minute = this.minutes[val[1]]
this.second = this.seconds[val[2]]
},

/**
* 初始化弹出层
*/
initTimePicker() {
if (this.disabled) return
const value = fixIosDateFormat(this.time)
this.initPickerValue(value)
this.visible = !this.visible
},

/**
* 触发或关闭弹框
*/
tiggerTimePicker(e) {
this.visible = !this.visible
},

/**
* 用户点击“清空”按钮,清空当前值
*/
clearTime() {
this.time = ''
this.$emit('change', this.time)
this.$emit('input', this.time)
this.$emit('update:modelValue', this.time)
this.tiggerTimePicker()
},

/**
* 用户点击“确定”按钮
*/
setTime() {
this.initTime()
this.tiggerTimePicker()
}
}
}
</script>

<style lang="scss">
$uni-primary: #007aff !default;

.uni-datetime-picker {
/* #ifndef APP-NVUE */
/* width: 100%; */
/* #endif */
}

.uni-datetime-picker-view {
height: 130px;
width: 270px;
/* #ifndef APP-NVUE */
cursor: pointer;
/* #endif */
}

.uni-datetime-picker-item {
height: 50px;
line-height: 50px;
text-align: center;
font-size: 14px;
}

.uni-datetime-picker-btn {
margin-top: 60px;
/* #ifndef APP-NVUE */
display: flex;
cursor: pointer;
/* #endif */
flex-direction: row;
justify-content: space-between;
}

.uni-datetime-picker-btn-text {
font-size: 14px;
color: $uni-primary;
}

.uni-datetime-picker-btn-group {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}

.uni-datetime-picker-cancel {
margin-right: 30px;
}

.uni-datetime-picker-mask {
position: fixed;
bottom: 0px;
top: 0px;
left: 0px;
right: 0px;
background-color: rgba(0, 0, 0, 0.4);
transition-duration: 0.3s;
z-index: 998;
}

.uni-datetime-picker-popup {
border-radius: 8px;
padding: 30px;
width: 270px;
/* #ifdef APP-NVUE */
height: 500px;
/* #endif */
/* #ifdef APP-NVUE */
width: 330px;
/* #endif */
background-color: #fff;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition-duration: 0.3s;
z-index: 999;
}

.fix-nvue-height {
/* #ifdef APP-NVUE */
height: 330px;
/* #endif */
}

.uni-datetime-picker-time {
color: grey;
}

.uni-datetime-picker-column {
height: 50px;
}

.uni-datetime-picker-timebox {

border: 1px solid #E5E5E5;
border-radius: 5px;
padding: 7px 10px;
/* #ifndef APP-NVUE */
box-sizing: border-box;
cursor: pointer;
/* #endif */
}

.uni-datetime-picker-timebox-pointer {
/* #ifndef APP-NVUE */
cursor: pointer;
/* #endif */
}


.uni-datetime-picker-disabled {
opacity: 0.4;
/* #ifdef H5 */
cursor: not-allowed !important;
/* #endif */
}

.uni-datetime-picker-text {
font-size: 14px;
line-height: 50px
}

.uni-datetime-picker-sign {
position: absolute;
top: 53px;
/* 减掉 10px 的元素高度,兼容nvue */
color: #999;
/* #ifdef APP-NVUE */
font-size: 16px;
/* #endif */
}

.sign-left {
left: 86px;
}

.sign-right {
right: 86px;
}

.sign-center {
left: 135px;
}

.uni-datetime-picker__container-box {
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin-top: 40px;
}

.time-hide-second {
width: 180px;
}
</style>

+ 1057
- 0
monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
File diff suppressed because it is too large
View File


+ 421
- 0
monitorMobile/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js View File

@@ -0,0 +1,421 @@
class Calendar {
constructor({
selected,
startDate,
endDate,
range,
} = {}) {
// 当前日期
this.date = this.getDateObj(new Date()) // 当前初入日期
// 打点信息
this.selected = selected || [];
// 起始时间
this.startDate = startDate
// 终止时间
this.endDate = endDate
// 是否范围选择
this.range = range
// 多选状态
this.cleanMultipleStatus()
// 每周日期
this.weeks = {}
this.lastHover = false
}
/**
* 设置日期
* @param {Object} date
*/
setDate(date) {
const selectDate = this.getDateObj(date)
this.getWeeks(selectDate.fullDate)
}

/**
* 清理多选状态
*/
cleanMultipleStatus() {
this.multipleStatus = {
before: '',
after: '',
data: []
}
}

setStartDate(startDate) {
this.startDate = startDate
}

setEndDate(endDate) {
this.endDate = endDate
}

getPreMonthObj(date) {
date = fixIosDateFormat(date)
date = new Date(date)

const oldMonth = date.getMonth()
date.setMonth(oldMonth - 1)
const newMonth = date.getMonth()
if (oldMonth !== 0 && newMonth - oldMonth === 0) {
date.setMonth(newMonth - 1)
}
return this.getDateObj(date)
}
getNextMonthObj(date) {
date = fixIosDateFormat(date)
date = new Date(date)

const oldMonth = date.getMonth()
date.setMonth(oldMonth + 1)
const newMonth = date.getMonth()
if (newMonth - oldMonth > 1) {
date.setMonth(newMonth - 1)
}
return this.getDateObj(date)
}

/**
* 获取指定格式Date对象
*/
getDateObj(date) {
date = fixIosDateFormat(date)
date = new Date(date)

return {
fullDate: getDate(date),
year: date.getFullYear(),
month: addZero(date.getMonth() + 1),
date: addZero(date.getDate()),
day: date.getDay()
}
}

/**
* 获取上一个月日期集合
*/
getPreMonthDays(amount, dateObj) {
const result = []
for (let i = amount - 1; i >= 0; i--) {
const month = dateObj.month - 1
result.push({
date: new Date(dateObj.year, month, -i).getDate(),
month,
disable: true
})
}
return result
}
/**
* 获取本月日期集合
*/
getCurrentMonthDays(amount, dateObj) {
const result = []
const fullDate = this.date.fullDate
for (let i = 1; i <= amount; i++) {
const currentDate = `${dateObj.year}-${dateObj.month}-${addZero(i)}`
const isToday = fullDate === currentDate
// 获取打点信息
const info = this.selected && this.selected.find((item) => {
if (this.dateEqual(currentDate, item.date)) {
return item
}
})

// 日期禁用
let disableBefore = true
let disableAfter = true
if (this.startDate) {
disableBefore = dateCompare(this.startDate, currentDate)
}

if (this.endDate) {
disableAfter = dateCompare(currentDate, this.endDate)
}

let multiples = this.multipleStatus.data
let multiplesStatus = -1
if (this.range && multiples) {
multiplesStatus = multiples.findIndex((item) => {
return this.dateEqual(item, currentDate)
})
}
const checked = multiplesStatus !== -1

result.push({
fullDate: currentDate,
year: dateObj.year,
date: i,
multiple: this.range ? checked : false,
beforeMultiple: this.isLogicBefore(currentDate, this.multipleStatus.before, this.multipleStatus.after),
afterMultiple: this.isLogicAfter(currentDate, this.multipleStatus.before, this.multipleStatus.after),
month: dateObj.month,
disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !dateCompare(
currentDate, this.endDate)),
isToday,
userChecked: false,
extraInfo: info
})
}
return result
}
/**
* 获取下一个月日期集合
*/
_getNextMonthDays(amount, dateObj) {
const result = []
const month = dateObj.month + 1
for (let i = 1; i <= amount; i++) {
result.push({
date: i,
month,
disable: true
})
}
return result
}

/**
* 获取当前日期详情
* @param {Object} date
*/
getInfo(date) {
if (!date) {
date = new Date()
}

return this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate)
}

/**
* 比较时间是否相等
*/
dateEqual(before, after) {
before = new Date(fixIosDateFormat(before))
after = new Date(fixIosDateFormat(after))
return before.valueOf() === after.valueOf()
}

/**
* 比较真实起始日期
*/

isLogicBefore(currentDate, before, after) {
let logicBefore = before
if (before && after) {
logicBefore = dateCompare(before, after) ? before : after
}
return this.dateEqual(logicBefore, currentDate)
}

isLogicAfter(currentDate, before, after) {
let logicAfter = after
if (before && after) {
logicAfter = dateCompare(before, after) ? after : before
}
return this.dateEqual(logicAfter, currentDate)
}

/**
* 获取日期范围内所有日期
* @param {Object} begin
* @param {Object} end
*/
geDateAll(begin, end) {
var arr = []
var ab = begin.split('-')
var ae = end.split('-')
var db = new Date()
db.setFullYear(ab[0], ab[1] - 1, ab[2])
var de = new Date()
de.setFullYear(ae[0], ae[1] - 1, ae[2])
var unixDb = db.getTime() - 24 * 60 * 60 * 1000
var unixDe = de.getTime() - 24 * 60 * 60 * 1000
for (var k = unixDb; k <= unixDe;) {
k = k + 24 * 60 * 60 * 1000
arr.push(this.getDateObj(new Date(parseInt(k))).fullDate)
}
return arr
}

/**
* 获取多选状态
*/
setMultiple(fullDate) {
if (!this.range) return

let {
before,
after
} = this.multipleStatus
if (before && after) {
if (!this.lastHover) {
this.lastHover = true
return
}
this.multipleStatus.before = fullDate
this.multipleStatus.after = ''
this.multipleStatus.data = []
this.multipleStatus.fulldate = ''
this.lastHover = false
} else {
if (!before) {
this.multipleStatus.before = fullDate
this.multipleStatus.after = undefined;
this.lastHover = false
} else {
this.multipleStatus.after = fullDate
if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus
.after);
} else {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus
.before);
}
this.lastHover = true
}
}
this.getWeeks(fullDate)
}

/**
* 鼠标 hover 更新多选状态
*/
setHoverMultiple(fullDate) {
//抖音小程序点击会触发hover事件,需要避免一下
// #ifndef MP-TOUTIAO
if (!this.range || this.lastHover) return
const {
before
} = this.multipleStatus

if (!before) {
this.multipleStatus.before = fullDate
} else {
this.multipleStatus.after = fullDate
if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
} else {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
}
}
this.getWeeks(fullDate)
// #endif

}

/**
* 更新默认值多选状态
*/
setDefaultMultiple(before, after) {
this.multipleStatus.before = before
this.multipleStatus.after = after
if (before && after) {
if (dateCompare(before, after)) {
this.multipleStatus.data = this.geDateAll(before, after);
this.getWeeks(after)
} else {
this.multipleStatus.data = this.geDateAll(after, before);
this.getWeeks(before)
}
}
}

/**
* 获取每周数据
* @param {Object} dateData
*/
getWeeks(dateData) {
const {
year,
month,
} = this.getDateObj(dateData)

const preMonthDayAmount = new Date(year, month - 1, 1).getDay()
const preMonthDays = this.getPreMonthDays(preMonthDayAmount, this.getDateObj(dateData))

const currentMonthDayAmount = new Date(year, month, 0).getDate()
const currentMonthDays = this.getCurrentMonthDays(currentMonthDayAmount, this.getDateObj(dateData))

const nextMonthDayAmount = 42 - preMonthDayAmount - currentMonthDayAmount
const nextMonthDays = this._getNextMonthDays(nextMonthDayAmount, this.getDateObj(dateData))

const calendarDays = [...preMonthDays, ...currentMonthDays, ...nextMonthDays]

const weeks = new Array(6)
for (let i = 0; i < calendarDays.length; i++) {
const index = Math.floor(i / 7)
if (!weeks[index]) {
weeks[index] = new Array(7)
}
weeks[index][i % 7] = calendarDays[i]
}

this.calendar = calendarDays
this.weeks = weeks
}
}

function getDateTime(date, hideSecond) {
return `${getDate(date)} ${getTime(date, hideSecond)}`
}

function getDate(date) {
date = fixIosDateFormat(date)
date = new Date(date)
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
return `${year}-${addZero(month)}-${addZero(day)}`
}

function getTime(date, hideSecond) {
date = fixIosDateFormat(date)
date = new Date(date)
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return hideSecond ? `${addZero(hour)}:${addZero(minute)}` : `${addZero(hour)}:${addZero(minute)}:${addZero(second)}`
}

function addZero(num) {
if (num < 10) {
num = `0${num}`
}
return num
}

function getDefaultSecond(hideSecond) {
return hideSecond ? '00:00' : '00:00:00'
}

function dateCompare(startDate, endDate) {
startDate = new Date(fixIosDateFormat(startDate))
endDate = new Date(fixIosDateFormat(endDate))
return startDate <= endDate
}

function checkDate(date) {
const dateReg = /((19|20)\d{2})(-|\/)\d{1,2}(-|\/)\d{1,2}/g
return date.match(dateReg)
}
//ios低版本15及以下,无法匹配 没有 ’秒‘ 时的情况,所以需要在末尾 秒 加上 问号
const dateTimeReg = /^\d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])( [0-5]?[0-9]:[0-5]?[0-9](:[0-5]?[0-9])?)?$/;

function fixIosDateFormat(value) {
if (typeof value === 'string' && dateTimeReg.test(value)) {
value = value.replace(/-/g, '/')
}
return value
}

export {
Calendar,
getDateTime,
getDate,
getTime,
addZero,
getDefaultSecond,
dateCompare,
checkDate,
fixIosDateFormat
}

+ 88
- 0
monitorMobile/uni_modules/uni-datetime-picker/package.json View File

@@ -0,0 +1,88 @@
{
"id": "uni-datetime-picker",
"displayName": "uni-datetime-picker 日期选择器",
"version": "2.2.34",
"description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择",
"keywords": [
"uni-datetime-picker",
"uni-ui",
"uniui",
"日期时间选择器",
"日期时间"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

+ 21
- 0
monitorMobile/uni_modules/uni-datetime-picker/readme.md View File

@@ -0,0 +1,21 @@


> `重要通知:组件升级更新 2.0.0 后,支持日期+时间范围选择,组件 ui 将使用日历选择日期,ui 变化较大,同时支持 PC 和 移动端。此版本不向后兼容,不再支持单独的时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)。若仍需使用旧版本,可在插件市场下载*非uni_modules版本*,旧版本将不再维护`

## DatetimePicker 时间选择器

> **组件名:uni-datetime-picker**
> 代码块: `uDatetimePicker`


该组件的优势是,支持**时间戳**输入和输出(起始时间、终止时间也支持时间戳),可**同时选择**日期和时间。

若只是需要单独选择日期和时间,不需要时间戳输入和输出,可使用原生的 picker 组件。

**_点击 picker 默认值规则:_**

- 若设置初始值 value, 会显示在 picker 显示框中
- 若无初始值 value,则初始值 value 为当前本地时间 Date.now(), 但不会显示在 picker 显示框中

### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839

+ 42
- 0
monitorMobile/uni_modules/uni-icons/changelog.md View File

@@ -0,0 +1,42 @@
## 2.0.10(2024-06-07)
- 优化 uni-app x 中,size 属性的类型
## 2.0.9(2024-01-12)
fix: 修复图标大小默认值错误的问题
## 2.0.8(2023-12-14)
- 修复 项目未使用 ts 情况下,打包报错的bug
## 2.0.7(2023-12-14)
- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
## 2.0.6(2023-12-11)
- 优化 兼容老版本icon类型,如 top ,bottom 等
## 2.0.5(2023-12-11)
- 优化 兼容老版本icon类型,如 top ,bottom 等
## 2.0.4(2023-12-06)
- 优化 uni-app x 下示例项目图标排序
## 2.0.3(2023-12-06)
- 修复 nvue下引入组件报错的bug
## 2.0.2(2023-12-05)
-优化 size 属性支持单位
## 2.0.1(2023-12-05)
- 新增 uni-app x 支持定义图标
## 1.3.5(2022-01-24)
- 优化 size 属性可以传入不带单位的字符串数值
## 1.3.4(2022-01-24)
- 优化 size 支持其他单位
## 1.3.3(2022-01-17)
- 修复 nvue 有些图标不显示的bug,兼容老版本图标
## 1.3.2(2021-12-01)
- 优化 示例可复制图标名称
## 1.3.1(2021-11-23)
- 优化 兼容旧组件 type 值
## 1.3.0(2021-11-19)
- 新增 更多图标
- 优化 自定义图标使用方式
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
## 1.1.7(2021-11-08)
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.5(2021-05-12)
- 新增 组件示例地址
## 1.1.4(2021-02-05)
- 调整为uni_modules目录规范

+ 91
- 0
monitorMobile/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue View File

@@ -0,0 +1,91 @@
<template>
<text class="uni-icons" :style="styleObj">
<slot>{{unicode}}</slot>
</text>
</template>

<script>
import { fontData, IconsDataItem } from './uniicons_file'

/**
* Icons 图标
* @description 用于展示 icon 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number,String} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: "uni-icons",
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
fontFamily: {
type: String,
default: ''
}
},
data() {
return {};
},
computed: {
unicode() : string {
let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
if (codes !== null) {
return codes.unicode
}
return ''
},
iconSize() : string {
const size = this.size
if (typeof size == 'string') {
const reg = /^[0-9]*$/g
return reg.test(size as string) ? '' + size + 'px' : '' + size;
// return '' + this.size
}
return this.getFontSize(size as number)
},
styleObj() : UTSJSONObject {
if (this.fontFamily !== '') {
return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
}
return { color: this.color, fontSize: this.iconSize }
}
},
created() { },
methods: {
/**
* 字体大小
*/
getFontSize(size : number) : string {
return size + 'px';
},
},
}
</script>

<style scoped>
@font-face {
font-family: UniIconsFontFamily;
src: url('./uniicons.ttf');
}

.uni-icons {
font-family: UniIconsFontFamily;
font-size: 18px;
font-style: normal;
color: #333;
}
</style>

+ 110
- 0
monitorMobile/uni_modules/uni-icons/components/uni-icons/uni-icons.vue View File

@@ -0,0 +1,110 @@
<template>
<!-- #ifdef APP-NVUE -->
<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick">
<slot></slot>
</text>
<!-- #endif -->
</template>

<script>
import { fontData } from './uniicons_file_vue.js';

const getVal = (val) => {
const reg = /^[0-9]*$/g
return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;
}

// #ifdef APP-NVUE
var domModule = weex.requireModule('dom');
import iconUrl from './uniicons.ttf'
domModule.addRule('fontFace', {
'fontFamily': "uniicons",
'src': "url('" + iconUrl + "')"
});
// #endif

/**
* Icons 图标
* @description 用于展示 icons 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: 'UniIcons',
emits: ['click'],
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
customPrefix: {
type: String,
default: ''
},
fontFamily: {
type: String,
default: ''
}
},
data() {
return {
icons: fontData
}
},
computed: {
unicode() {
let code = this.icons.find(v => v.font_class === this.type)
if (code) {
return code.unicode
}
return ''
},
iconSize() {
return getVal(this.size)
},
styleObj() {
if (this.fontFamily !== '') {
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`
}
return `color: ${this.color}; font-size: ${this.iconSize};`
}
},
methods: {
_onClick() {
this.$emit('click')
}
}
}
</script>

<style lang="scss">
/* #ifndef APP-NVUE */
@import './uniicons.css';

@font-face {
font-family: uniicons;
src: url('./uniicons.ttf');
}

/* #endif */
.uni-icons {
font-family: uniicons;
text-decoration: none;
text-align: center;
}
</style>

+ 664
- 0
monitorMobile/uni_modules/uni-icons/components/uni-icons/uniicons.css View File

@@ -0,0 +1,664 @@

.uniui-cart-filled:before {
content: "\e6d0";
}

.uniui-gift-filled:before {
content: "\e6c4";
}

.uniui-color:before {
content: "\e6cf";
}

.uniui-wallet:before {
content: "\e6b1";
}

.uniui-settings-filled:before {
content: "\e6ce";
}

.uniui-auth-filled:before {
content: "\e6cc";
}

.uniui-shop-filled:before {
content: "\e6cd";
}

.uniui-staff-filled:before {
content: "\e6cb";
}

.uniui-vip-filled:before {
content: "\e6c6";
}

.uniui-plus-filled:before {
content: "\e6c7";
}

.uniui-folder-add-filled:before {
content: "\e6c8";
}

.uniui-color-filled:before {
content: "\e6c9";
}

.uniui-tune-filled:before {
content: "\e6ca";
}

.uniui-calendar-filled:before {
content: "\e6c0";
}

.uniui-notification-filled:before {
content: "\e6c1";
}

.uniui-wallet-filled:before {
content: "\e6c2";
}

.uniui-medal-filled:before {
content: "\e6c3";
}

.uniui-fire-filled:before {
content: "\e6c5";
}

.uniui-refreshempty:before {
content: "\e6bf";
}

.uniui-location-filled:before {
content: "\e6af";
}

.uniui-person-filled:before {
content: "\e69d";
}

.uniui-personadd-filled:before {
content: "\e698";
}

.uniui-arrowthinleft:before {
content: "\e6d2";
}

.uniui-arrowthinup:before {
content: "\e6d3";
}

.uniui-arrowthindown:before {
content: "\e6d4";
}

.uniui-back:before {
content: "\e6b9";
}

.uniui-forward:before {
content: "\e6ba";
}

.uniui-arrow-right:before {
content: "\e6bb";
}

.uniui-arrow-left:before {
content: "\e6bc";
}

.uniui-arrow-up:before {
content: "\e6bd";
}

.uniui-arrow-down:before {
content: "\e6be";
}

.uniui-arrowthinright:before {
content: "\e6d1";
}

.uniui-down:before {
content: "\e6b8";
}

.uniui-bottom:before {
content: "\e6b8";
}

.uniui-arrowright:before {
content: "\e6d5";
}

.uniui-right:before {
content: "\e6b5";
}

.uniui-up:before {
content: "\e6b6";
}

.uniui-top:before {
content: "\e6b6";
}

.uniui-left:before {
content: "\e6b7";
}

.uniui-arrowup:before {
content: "\e6d6";
}

.uniui-eye:before {
content: "\e651";
}

.uniui-eye-filled:before {
content: "\e66a";
}

.uniui-eye-slash:before {
content: "\e6b3";
}

.uniui-eye-slash-filled:before {
content: "\e6b4";
}

.uniui-info-filled:before {
content: "\e649";
}

.uniui-reload:before {
content: "\e6b2";
}

.uniui-micoff-filled:before {
content: "\e6b0";
}

.uniui-map-pin-ellipse:before {
content: "\e6ac";
}

.uniui-map-pin:before {
content: "\e6ad";
}

.uniui-location:before {
content: "\e6ae";
}

.uniui-starhalf:before {
content: "\e683";
}

.uniui-star:before {
content: "\e688";
}

.uniui-star-filled:before {
content: "\e68f";
}

.uniui-calendar:before {
content: "\e6a0";
}

.uniui-fire:before {
content: "\e6a1";
}

.uniui-medal:before {
content: "\e6a2";
}

.uniui-font:before {
content: "\e6a3";
}

.uniui-gift:before {
content: "\e6a4";
}

.uniui-link:before {
content: "\e6a5";
}

.uniui-notification:before {
content: "\e6a6";
}

.uniui-staff:before {
content: "\e6a7";
}

.uniui-vip:before {
content: "\e6a8";
}

.uniui-folder-add:before {
content: "\e6a9";
}

.uniui-tune:before {
content: "\e6aa";
}

.uniui-auth:before {
content: "\e6ab";
}

.uniui-person:before {
content: "\e699";
}

.uniui-email-filled:before {
content: "\e69a";
}

.uniui-phone-filled:before {
content: "\e69b";
}

.uniui-phone:before {
content: "\e69c";
}

.uniui-email:before {
content: "\e69e";
}

.uniui-personadd:before {
content: "\e69f";
}

.uniui-chatboxes-filled:before {
content: "\e692";
}

.uniui-contact:before {
content: "\e693";
}

.uniui-chatbubble-filled:before {
content: "\e694";
}

.uniui-contact-filled:before {
content: "\e695";
}

.uniui-chatboxes:before {
content: "\e696";
}

.uniui-chatbubble:before {
content: "\e697";
}

.uniui-upload-filled:before {
content: "\e68e";
}

.uniui-upload:before {
content: "\e690";
}

.uniui-weixin:before {
content: "\e691";
}

.uniui-compose:before {
content: "\e67f";
}

.uniui-qq:before {
content: "\e680";
}

.uniui-download-filled:before {
content: "\e681";
}

.uniui-pyq:before {
content: "\e682";
}

.uniui-sound:before {
content: "\e684";
}

.uniui-trash-filled:before {
content: "\e685";
}

.uniui-sound-filled:before {
content: "\e686";
}

.uniui-trash:before {
content: "\e687";
}

.uniui-videocam-filled:before {
content: "\e689";
}

.uniui-spinner-cycle:before {
content: "\e68a";
}

.uniui-weibo:before {
content: "\e68b";
}

.uniui-videocam:before {
content: "\e68c";
}

.uniui-download:before {
content: "\e68d";
}

.uniui-help:before {
content: "\e679";
}

.uniui-navigate-filled:before {
content: "\e67a";
}

.uniui-plusempty:before {
content: "\e67b";
}

.uniui-smallcircle:before {
content: "\e67c";
}

.uniui-minus-filled:before {
content: "\e67d";
}

.uniui-micoff:before {
content: "\e67e";
}

.uniui-closeempty:before {
content: "\e66c";
}

.uniui-clear:before {
content: "\e66d";
}

.uniui-navigate:before {
content: "\e66e";
}

.uniui-minus:before {
content: "\e66f";
}

.uniui-image:before {
content: "\e670";
}

.uniui-mic:before {
content: "\e671";
}

.uniui-paperplane:before {
content: "\e672";
}

.uniui-close:before {
content: "\e673";
}

.uniui-help-filled:before {
content: "\e674";
}

.uniui-paperplane-filled:before {
content: "\e675";
}

.uniui-plus:before {
content: "\e676";
}

.uniui-mic-filled:before {
content: "\e677";
}

.uniui-image-filled:before {
content: "\e678";
}

.uniui-locked-filled:before {
content: "\e668";
}

.uniui-info:before {
content: "\e669";
}

.uniui-locked:before {
content: "\e66b";
}

.uniui-camera-filled:before {
content: "\e658";
}

.uniui-chat-filled:before {
content: "\e659";
}

.uniui-camera:before {
content: "\e65a";
}

.uniui-circle:before {
content: "\e65b";
}

.uniui-checkmarkempty:before {
content: "\e65c";
}

.uniui-chat:before {
content: "\e65d";
}

.uniui-circle-filled:before {
content: "\e65e";
}

.uniui-flag:before {
content: "\e65f";
}

.uniui-flag-filled:before {
content: "\e660";
}

.uniui-gear-filled:before {
content: "\e661";
}

.uniui-home:before {
content: "\e662";
}

.uniui-home-filled:before {
content: "\e663";
}

.uniui-gear:before {
content: "\e664";
}

.uniui-smallcircle-filled:before {
content: "\e665";
}

.uniui-map-filled:before {
content: "\e666";
}

.uniui-map:before {
content: "\e667";
}

.uniui-refresh-filled:before {
content: "\e656";
}

.uniui-refresh:before {
content: "\e657";
}

.uniui-cloud-upload:before {
content: "\e645";
}

.uniui-cloud-download-filled:before {
content: "\e646";
}

.uniui-cloud-download:before {
content: "\e647";
}

.uniui-cloud-upload-filled:before {
content: "\e648";
}

.uniui-redo:before {
content: "\e64a";
}

.uniui-images-filled:before {
content: "\e64b";
}

.uniui-undo-filled:before {
content: "\e64c";
}

.uniui-more:before {
content: "\e64d";
}

.uniui-more-filled:before {
content: "\e64e";
}

.uniui-undo:before {
content: "\e64f";
}

.uniui-images:before {
content: "\e650";
}

.uniui-paperclip:before {
content: "\e652";
}

.uniui-settings:before {
content: "\e653";
}

.uniui-search:before {
content: "\e654";
}

.uniui-redo-filled:before {
content: "\e655";
}

.uniui-list:before {
content: "\e644";
}

.uniui-mail-open-filled:before {
content: "\e63a";
}

.uniui-hand-down-filled:before {
content: "\e63c";
}

.uniui-hand-down:before {
content: "\e63d";
}

.uniui-hand-up-filled:before {
content: "\e63e";
}

.uniui-hand-up:before {
content: "\e63f";
}

.uniui-heart-filled:before {
content: "\e641";
}

.uniui-mail-open:before {
content: "\e643";
}

.uniui-heart:before {
content: "\e639";
}

.uniui-loop:before {
content: "\e633";
}

.uniui-pulldown:before {
content: "\e632";
}

.uniui-scan:before {
content: "\e62a";
}

.uniui-bars:before {
content: "\e627";
}

.uniui-checkbox:before {
content: "\e62b";
}

.uniui-checkbox-filled:before {
content: "\e62c";
}

.uniui-shop:before {
content: "\e62f";
}

.uniui-headphones:before {
content: "\e630";
}

.uniui-cart:before {
content: "\e631";
}

BIN
monitorMobile/uni_modules/uni-icons/components/uni-icons/uniicons.ttf View File


+ 664
- 0
monitorMobile/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts View File

@@ -0,0 +1,664 @@

export type IconsData = {
id : string
name : string
font_family : string
css_prefix_text : string
description : string
glyphs : Array<IconsDataItem>
}

export type IconsDataItem = {
font_class : string
unicode : string
}


export const fontData = [
{
"font_class": "arrow-down",
"unicode": "\ue6be"
},
{
"font_class": "arrow-left",
"unicode": "\ue6bc"
},
{
"font_class": "arrow-right",
"unicode": "\ue6bb"
},
{
"font_class": "arrow-up",
"unicode": "\ue6bd"
},
{
"font_class": "auth",
"unicode": "\ue6ab"
},
{
"font_class": "auth-filled",
"unicode": "\ue6cc"
},
{
"font_class": "back",
"unicode": "\ue6b9"
},
{
"font_class": "bars",
"unicode": "\ue627"
},
{
"font_class": "calendar",
"unicode": "\ue6a0"
},
{
"font_class": "calendar-filled",
"unicode": "\ue6c0"
},
{
"font_class": "camera",
"unicode": "\ue65a"
},
{
"font_class": "camera-filled",
"unicode": "\ue658"
},
{
"font_class": "cart",
"unicode": "\ue631"
},
{
"font_class": "cart-filled",
"unicode": "\ue6d0"
},
{
"font_class": "chat",
"unicode": "\ue65d"
},
{
"font_class": "chat-filled",
"unicode": "\ue659"
},
{
"font_class": "chatboxes",
"unicode": "\ue696"
},
{
"font_class": "chatboxes-filled",
"unicode": "\ue692"
},
{
"font_class": "chatbubble",
"unicode": "\ue697"
},
{
"font_class": "chatbubble-filled",
"unicode": "\ue694"
},
{
"font_class": "checkbox",
"unicode": "\ue62b"
},
{
"font_class": "checkbox-filled",
"unicode": "\ue62c"
},
{
"font_class": "checkmarkempty",
"unicode": "\ue65c"
},
{
"font_class": "circle",
"unicode": "\ue65b"
},
{
"font_class": "circle-filled",
"unicode": "\ue65e"
},
{
"font_class": "clear",
"unicode": "\ue66d"
},
{
"font_class": "close",
"unicode": "\ue673"
},
{
"font_class": "closeempty",
"unicode": "\ue66c"
},
{
"font_class": "cloud-download",
"unicode": "\ue647"
},
{
"font_class": "cloud-download-filled",
"unicode": "\ue646"
},
{
"font_class": "cloud-upload",
"unicode": "\ue645"
},
{
"font_class": "cloud-upload-filled",
"unicode": "\ue648"
},
{
"font_class": "color",
"unicode": "\ue6cf"
},
{
"font_class": "color-filled",
"unicode": "\ue6c9"
},
{
"font_class": "compose",
"unicode": "\ue67f"
},
{
"font_class": "contact",
"unicode": "\ue693"
},
{
"font_class": "contact-filled",
"unicode": "\ue695"
},
{
"font_class": "down",
"unicode": "\ue6b8"
},
{
"font_class": "bottom",
"unicode": "\ue6b8"
},
{
"font_class": "download",
"unicode": "\ue68d"
},
{
"font_class": "download-filled",
"unicode": "\ue681"
},
{
"font_class": "email",
"unicode": "\ue69e"
},
{
"font_class": "email-filled",
"unicode": "\ue69a"
},
{
"font_class": "eye",
"unicode": "\ue651"
},
{
"font_class": "eye-filled",
"unicode": "\ue66a"
},
{
"font_class": "eye-slash",
"unicode": "\ue6b3"
},
{
"font_class": "eye-slash-filled",
"unicode": "\ue6b4"
},
{
"font_class": "fire",
"unicode": "\ue6a1"
},
{
"font_class": "fire-filled",
"unicode": "\ue6c5"
},
{
"font_class": "flag",
"unicode": "\ue65f"
},
{
"font_class": "flag-filled",
"unicode": "\ue660"
},
{
"font_class": "folder-add",
"unicode": "\ue6a9"
},
{
"font_class": "folder-add-filled",
"unicode": "\ue6c8"
},
{
"font_class": "font",
"unicode": "\ue6a3"
},
{
"font_class": "forward",
"unicode": "\ue6ba"
},
{
"font_class": "gear",
"unicode": "\ue664"
},
{
"font_class": "gear-filled",
"unicode": "\ue661"
},
{
"font_class": "gift",
"unicode": "\ue6a4"
},
{
"font_class": "gift-filled",
"unicode": "\ue6c4"
},
{
"font_class": "hand-down",
"unicode": "\ue63d"
},
{
"font_class": "hand-down-filled",
"unicode": "\ue63c"
},
{
"font_class": "hand-up",
"unicode": "\ue63f"
},
{
"font_class": "hand-up-filled",
"unicode": "\ue63e"
},
{
"font_class": "headphones",
"unicode": "\ue630"
},
{
"font_class": "heart",
"unicode": "\ue639"
},
{
"font_class": "heart-filled",
"unicode": "\ue641"
},
{
"font_class": "help",
"unicode": "\ue679"
},
{
"font_class": "help-filled",
"unicode": "\ue674"
},
{
"font_class": "home",
"unicode": "\ue662"
},
{
"font_class": "home-filled",
"unicode": "\ue663"
},
{
"font_class": "image",
"unicode": "\ue670"
},
{
"font_class": "image-filled",
"unicode": "\ue678"
},
{
"font_class": "images",
"unicode": "\ue650"
},
{
"font_class": "images-filled",
"unicode": "\ue64b"
},
{
"font_class": "info",
"unicode": "\ue669"
},
{
"font_class": "info-filled",
"unicode": "\ue649"
},
{
"font_class": "left",
"unicode": "\ue6b7"
},
{
"font_class": "link",
"unicode": "\ue6a5"
},
{
"font_class": "list",
"unicode": "\ue644"
},
{
"font_class": "location",
"unicode": "\ue6ae"
},
{
"font_class": "location-filled",
"unicode": "\ue6af"
},
{
"font_class": "locked",
"unicode": "\ue66b"
},
{
"font_class": "locked-filled",
"unicode": "\ue668"
},
{
"font_class": "loop",
"unicode": "\ue633"
},
{
"font_class": "mail-open",
"unicode": "\ue643"
},
{
"font_class": "mail-open-filled",
"unicode": "\ue63a"
},
{
"font_class": "map",
"unicode": "\ue667"
},
{
"font_class": "map-filled",
"unicode": "\ue666"
},
{
"font_class": "map-pin",
"unicode": "\ue6ad"
},
{
"font_class": "map-pin-ellipse",
"unicode": "\ue6ac"
},
{
"font_class": "medal",
"unicode": "\ue6a2"
},
{
"font_class": "medal-filled",
"unicode": "\ue6c3"
},
{
"font_class": "mic",
"unicode": "\ue671"
},
{
"font_class": "mic-filled",
"unicode": "\ue677"
},
{
"font_class": "micoff",
"unicode": "\ue67e"
},
{
"font_class": "micoff-filled",
"unicode": "\ue6b0"
},
{
"font_class": "minus",
"unicode": "\ue66f"
},
{
"font_class": "minus-filled",
"unicode": "\ue67d"
},
{
"font_class": "more",
"unicode": "\ue64d"
},
{
"font_class": "more-filled",
"unicode": "\ue64e"
},
{
"font_class": "navigate",
"unicode": "\ue66e"
},
{
"font_class": "navigate-filled",
"unicode": "\ue67a"
},
{
"font_class": "notification",
"unicode": "\ue6a6"
},
{
"font_class": "notification-filled",
"unicode": "\ue6c1"
},
{
"font_class": "paperclip",
"unicode": "\ue652"
},
{
"font_class": "paperplane",
"unicode": "\ue672"
},
{
"font_class": "paperplane-filled",
"unicode": "\ue675"
},
{
"font_class": "person",
"unicode": "\ue699"
},
{
"font_class": "person-filled",
"unicode": "\ue69d"
},
{
"font_class": "personadd",
"unicode": "\ue69f"
},
{
"font_class": "personadd-filled",
"unicode": "\ue698"
},
{
"font_class": "personadd-filled-copy",
"unicode": "\ue6d1"
},
{
"font_class": "phone",
"unicode": "\ue69c"
},
{
"font_class": "phone-filled",
"unicode": "\ue69b"
},
{
"font_class": "plus",
"unicode": "\ue676"
},
{
"font_class": "plus-filled",
"unicode": "\ue6c7"
},
{
"font_class": "plusempty",
"unicode": "\ue67b"
},
{
"font_class": "pulldown",
"unicode": "\ue632"
},
{
"font_class": "pyq",
"unicode": "\ue682"
},
{
"font_class": "qq",
"unicode": "\ue680"
},
{
"font_class": "redo",
"unicode": "\ue64a"
},
{
"font_class": "redo-filled",
"unicode": "\ue655"
},
{
"font_class": "refresh",
"unicode": "\ue657"
},
{
"font_class": "refresh-filled",
"unicode": "\ue656"
},
{
"font_class": "refreshempty",
"unicode": "\ue6bf"
},
{
"font_class": "reload",
"unicode": "\ue6b2"
},
{
"font_class": "right",
"unicode": "\ue6b5"
},
{
"font_class": "scan",
"unicode": "\ue62a"
},
{
"font_class": "search",
"unicode": "\ue654"
},
{
"font_class": "settings",
"unicode": "\ue653"
},
{
"font_class": "settings-filled",
"unicode": "\ue6ce"
},
{
"font_class": "shop",
"unicode": "\ue62f"
},
{
"font_class": "shop-filled",
"unicode": "\ue6cd"
},
{
"font_class": "smallcircle",
"unicode": "\ue67c"
},
{
"font_class": "smallcircle-filled",
"unicode": "\ue665"
},
{
"font_class": "sound",
"unicode": "\ue684"
},
{
"font_class": "sound-filled",
"unicode": "\ue686"
},
{
"font_class": "spinner-cycle",
"unicode": "\ue68a"
},
{
"font_class": "staff",
"unicode": "\ue6a7"
},
{
"font_class": "staff-filled",
"unicode": "\ue6cb"
},
{
"font_class": "star",
"unicode": "\ue688"
},
{
"font_class": "star-filled",
"unicode": "\ue68f"
},
{
"font_class": "starhalf",
"unicode": "\ue683"
},
{
"font_class": "trash",
"unicode": "\ue687"
},
{
"font_class": "trash-filled",
"unicode": "\ue685"
},
{
"font_class": "tune",
"unicode": "\ue6aa"
},
{
"font_class": "tune-filled",
"unicode": "\ue6ca"
},
{
"font_class": "undo",
"unicode": "\ue64f"
},
{
"font_class": "undo-filled",
"unicode": "\ue64c"
},
{
"font_class": "up",
"unicode": "\ue6b6"
},
{
"font_class": "top",
"unicode": "\ue6b6"
},
{
"font_class": "upload",
"unicode": "\ue690"
},
{
"font_class": "upload-filled",
"unicode": "\ue68e"
},
{
"font_class": "videocam",
"unicode": "\ue68c"
},
{
"font_class": "videocam-filled",
"unicode": "\ue689"
},
{
"font_class": "vip",
"unicode": "\ue6a8"
},
{
"font_class": "vip-filled",
"unicode": "\ue6c6"
},
{
"font_class": "wallet",
"unicode": "\ue6b1"
},
{
"font_class": "wallet-filled",
"unicode": "\ue6c2"
},
{
"font_class": "weibo",
"unicode": "\ue68b"
},
{
"font_class": "weixin",
"unicode": "\ue691"
}
] as IconsDataItem[]

// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

+ 649
- 0
monitorMobile/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js View File

@@ -0,0 +1,649 @@

export const fontData = [
{
"font_class": "arrow-down",
"unicode": "\ue6be"
},
{
"font_class": "arrow-left",
"unicode": "\ue6bc"
},
{
"font_class": "arrow-right",
"unicode": "\ue6bb"
},
{
"font_class": "arrow-up",
"unicode": "\ue6bd"
},
{
"font_class": "auth",
"unicode": "\ue6ab"
},
{
"font_class": "auth-filled",
"unicode": "\ue6cc"
},
{
"font_class": "back",
"unicode": "\ue6b9"
},
{
"font_class": "bars",
"unicode": "\ue627"
},
{
"font_class": "calendar",
"unicode": "\ue6a0"
},
{
"font_class": "calendar-filled",
"unicode": "\ue6c0"
},
{
"font_class": "camera",
"unicode": "\ue65a"
},
{
"font_class": "camera-filled",
"unicode": "\ue658"
},
{
"font_class": "cart",
"unicode": "\ue631"
},
{
"font_class": "cart-filled",
"unicode": "\ue6d0"
},
{
"font_class": "chat",
"unicode": "\ue65d"
},
{
"font_class": "chat-filled",
"unicode": "\ue659"
},
{
"font_class": "chatboxes",
"unicode": "\ue696"
},
{
"font_class": "chatboxes-filled",
"unicode": "\ue692"
},
{
"font_class": "chatbubble",
"unicode": "\ue697"
},
{
"font_class": "chatbubble-filled",
"unicode": "\ue694"
},
{
"font_class": "checkbox",
"unicode": "\ue62b"
},
{
"font_class": "checkbox-filled",
"unicode": "\ue62c"
},
{
"font_class": "checkmarkempty",
"unicode": "\ue65c"
},
{
"font_class": "circle",
"unicode": "\ue65b"
},
{
"font_class": "circle-filled",
"unicode": "\ue65e"
},
{
"font_class": "clear",
"unicode": "\ue66d"
},
{
"font_class": "close",
"unicode": "\ue673"
},
{
"font_class": "closeempty",
"unicode": "\ue66c"
},
{
"font_class": "cloud-download",
"unicode": "\ue647"
},
{
"font_class": "cloud-download-filled",
"unicode": "\ue646"
},
{
"font_class": "cloud-upload",
"unicode": "\ue645"
},
{
"font_class": "cloud-upload-filled",
"unicode": "\ue648"
},
{
"font_class": "color",
"unicode": "\ue6cf"
},
{
"font_class": "color-filled",
"unicode": "\ue6c9"
},
{
"font_class": "compose",
"unicode": "\ue67f"
},
{
"font_class": "contact",
"unicode": "\ue693"
},
{
"font_class": "contact-filled",
"unicode": "\ue695"
},
{
"font_class": "down",
"unicode": "\ue6b8"
},
{
"font_class": "bottom",
"unicode": "\ue6b8"
},
{
"font_class": "download",
"unicode": "\ue68d"
},
{
"font_class": "download-filled",
"unicode": "\ue681"
},
{
"font_class": "email",
"unicode": "\ue69e"
},
{
"font_class": "email-filled",
"unicode": "\ue69a"
},
{
"font_class": "eye",
"unicode": "\ue651"
},
{
"font_class": "eye-filled",
"unicode": "\ue66a"
},
{
"font_class": "eye-slash",
"unicode": "\ue6b3"
},
{
"font_class": "eye-slash-filled",
"unicode": "\ue6b4"
},
{
"font_class": "fire",
"unicode": "\ue6a1"
},
{
"font_class": "fire-filled",
"unicode": "\ue6c5"
},
{
"font_class": "flag",
"unicode": "\ue65f"
},
{
"font_class": "flag-filled",
"unicode": "\ue660"
},
{
"font_class": "folder-add",
"unicode": "\ue6a9"
},
{
"font_class": "folder-add-filled",
"unicode": "\ue6c8"
},
{
"font_class": "font",
"unicode": "\ue6a3"
},
{
"font_class": "forward",
"unicode": "\ue6ba"
},
{
"font_class": "gear",
"unicode": "\ue664"
},
{
"font_class": "gear-filled",
"unicode": "\ue661"
},
{
"font_class": "gift",
"unicode": "\ue6a4"
},
{
"font_class": "gift-filled",
"unicode": "\ue6c4"
},
{
"font_class": "hand-down",
"unicode": "\ue63d"
},
{
"font_class": "hand-down-filled",
"unicode": "\ue63c"
},
{
"font_class": "hand-up",
"unicode": "\ue63f"
},
{
"font_class": "hand-up-filled",
"unicode": "\ue63e"
},
{
"font_class": "headphones",
"unicode": "\ue630"
},
{
"font_class": "heart",
"unicode": "\ue639"
},
{
"font_class": "heart-filled",
"unicode": "\ue641"
},
{
"font_class": "help",
"unicode": "\ue679"
},
{
"font_class": "help-filled",
"unicode": "\ue674"
},
{
"font_class": "home",
"unicode": "\ue662"
},
{
"font_class": "home-filled",
"unicode": "\ue663"
},
{
"font_class": "image",
"unicode": "\ue670"
},
{
"font_class": "image-filled",
"unicode": "\ue678"
},
{
"font_class": "images",
"unicode": "\ue650"
},
{
"font_class": "images-filled",
"unicode": "\ue64b"
},
{
"font_class": "info",
"unicode": "\ue669"
},
{
"font_class": "info-filled",
"unicode": "\ue649"
},
{
"font_class": "left",
"unicode": "\ue6b7"
},
{
"font_class": "link",
"unicode": "\ue6a5"
},
{
"font_class": "list",
"unicode": "\ue644"
},
{
"font_class": "location",
"unicode": "\ue6ae"
},
{
"font_class": "location-filled",
"unicode": "\ue6af"
},
{
"font_class": "locked",
"unicode": "\ue66b"
},
{
"font_class": "locked-filled",
"unicode": "\ue668"
},
{
"font_class": "loop",
"unicode": "\ue633"
},
{
"font_class": "mail-open",
"unicode": "\ue643"
},
{
"font_class": "mail-open-filled",
"unicode": "\ue63a"
},
{
"font_class": "map",
"unicode": "\ue667"
},
{
"font_class": "map-filled",
"unicode": "\ue666"
},
{
"font_class": "map-pin",
"unicode": "\ue6ad"
},
{
"font_class": "map-pin-ellipse",
"unicode": "\ue6ac"
},
{
"font_class": "medal",
"unicode": "\ue6a2"
},
{
"font_class": "medal-filled",
"unicode": "\ue6c3"
},
{
"font_class": "mic",
"unicode": "\ue671"
},
{
"font_class": "mic-filled",
"unicode": "\ue677"
},
{
"font_class": "micoff",
"unicode": "\ue67e"
},
{
"font_class": "micoff-filled",
"unicode": "\ue6b0"
},
{
"font_class": "minus",
"unicode": "\ue66f"
},
{
"font_class": "minus-filled",
"unicode": "\ue67d"
},
{
"font_class": "more",
"unicode": "\ue64d"
},
{
"font_class": "more-filled",
"unicode": "\ue64e"
},
{
"font_class": "navigate",
"unicode": "\ue66e"
},
{
"font_class": "navigate-filled",
"unicode": "\ue67a"
},
{
"font_class": "notification",
"unicode": "\ue6a6"
},
{
"font_class": "notification-filled",
"unicode": "\ue6c1"
},
{
"font_class": "paperclip",
"unicode": "\ue652"
},
{
"font_class": "paperplane",
"unicode": "\ue672"
},
{
"font_class": "paperplane-filled",
"unicode": "\ue675"
},
{
"font_class": "person",
"unicode": "\ue699"
},
{
"font_class": "person-filled",
"unicode": "\ue69d"
},
{
"font_class": "personadd",
"unicode": "\ue69f"
},
{
"font_class": "personadd-filled",
"unicode": "\ue698"
},
{
"font_class": "personadd-filled-copy",
"unicode": "\ue6d1"
},
{
"font_class": "phone",
"unicode": "\ue69c"
},
{
"font_class": "phone-filled",
"unicode": "\ue69b"
},
{
"font_class": "plus",
"unicode": "\ue676"
},
{
"font_class": "plus-filled",
"unicode": "\ue6c7"
},
{
"font_class": "plusempty",
"unicode": "\ue67b"
},
{
"font_class": "pulldown",
"unicode": "\ue632"
},
{
"font_class": "pyq",
"unicode": "\ue682"
},
{
"font_class": "qq",
"unicode": "\ue680"
},
{
"font_class": "redo",
"unicode": "\ue64a"
},
{
"font_class": "redo-filled",
"unicode": "\ue655"
},
{
"font_class": "refresh",
"unicode": "\ue657"
},
{
"font_class": "refresh-filled",
"unicode": "\ue656"
},
{
"font_class": "refreshempty",
"unicode": "\ue6bf"
},
{
"font_class": "reload",
"unicode": "\ue6b2"
},
{
"font_class": "right",
"unicode": "\ue6b5"
},
{
"font_class": "scan",
"unicode": "\ue62a"
},
{
"font_class": "search",
"unicode": "\ue654"
},
{
"font_class": "settings",
"unicode": "\ue653"
},
{
"font_class": "settings-filled",
"unicode": "\ue6ce"
},
{
"font_class": "shop",
"unicode": "\ue62f"
},
{
"font_class": "shop-filled",
"unicode": "\ue6cd"
},
{
"font_class": "smallcircle",
"unicode": "\ue67c"
},
{
"font_class": "smallcircle-filled",
"unicode": "\ue665"
},
{
"font_class": "sound",
"unicode": "\ue684"
},
{
"font_class": "sound-filled",
"unicode": "\ue686"
},
{
"font_class": "spinner-cycle",
"unicode": "\ue68a"
},
{
"font_class": "staff",
"unicode": "\ue6a7"
},
{
"font_class": "staff-filled",
"unicode": "\ue6cb"
},
{
"font_class": "star",
"unicode": "\ue688"
},
{
"font_class": "star-filled",
"unicode": "\ue68f"
},
{
"font_class": "starhalf",
"unicode": "\ue683"
},
{
"font_class": "trash",
"unicode": "\ue687"
},
{
"font_class": "trash-filled",
"unicode": "\ue685"
},
{
"font_class": "tune",
"unicode": "\ue6aa"
},
{
"font_class": "tune-filled",
"unicode": "\ue6ca"
},
{
"font_class": "undo",
"unicode": "\ue64f"
},
{
"font_class": "undo-filled",
"unicode": "\ue64c"
},
{
"font_class": "up",
"unicode": "\ue6b6"
},
{
"font_class": "top",
"unicode": "\ue6b6"
},
{
"font_class": "upload",
"unicode": "\ue690"
},
{
"font_class": "upload-filled",
"unicode": "\ue68e"
},
{
"font_class": "videocam",
"unicode": "\ue68c"
},
{
"font_class": "videocam-filled",
"unicode": "\ue689"
},
{
"font_class": "vip",
"unicode": "\ue6a8"
},
{
"font_class": "vip-filled",
"unicode": "\ue6c6"
},
{
"font_class": "wallet",
"unicode": "\ue6b1"
},
{
"font_class": "wallet-filled",
"unicode": "\ue6c2"
},
{
"font_class": "weibo",
"unicode": "\ue68b"
},
{
"font_class": "weixin",
"unicode": "\ue691"
}
]

// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

+ 89
- 0
monitorMobile/uni_modules/uni-icons/package.json View File

@@ -0,0 +1,89 @@
{
"id": "uni-icons",
"displayName": "uni-icons 图标",
"version": "2.0.10",
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
"keywords": [
"uni-ui",
"uniui",
"icon",
"图标"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.2.14"
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y",
"app-uvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "y",
"快手": "y",
"飞书": "y",
"京东": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

+ 8
- 0
monitorMobile/uni_modules/uni-icons/readme.md View File

@@ -0,0 +1,8 @@
## Icons 图标
> **组件名:uni-icons**
> 代码块: `uIcons`

用于展示 icons 图标 。

### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839

+ 8
- 0
monitorMobile/uni_modules/uni-scss/changelog.md View File

@@ -0,0 +1,8 @@
## 1.0.3(2022-01-21)
- 优化 组件示例
## 1.0.2(2021-11-22)
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
## 1.0.1(2021-11-22)
- 修复 vue3中scss语法兼容问题
## 1.0.0(2021-11-18)
- init

+ 1
- 0
monitorMobile/uni_modules/uni-scss/index.scss View File

@@ -0,0 +1 @@
@import './styles/index.scss';

+ 82
- 0
monitorMobile/uni_modules/uni-scss/package.json View File

@@ -0,0 +1,82 @@
{
"id": "uni-scss",
"displayName": "uni-scss 辅助样式",
"version": "1.0.3",
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
"keywords": [
"uni-scss",
"uni-ui",
"辅助样式"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"category": [
"JS SDK",
"通用 SDK"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "n",
"联盟": "n"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

+ 4
- 0
monitorMobile/uni_modules/uni-scss/readme.md View File

@@ -0,0 +1,4 @@
`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。

### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839

+ 7
- 0
monitorMobile/uni_modules/uni-scss/styles/index.scss View File

@@ -0,0 +1,7 @@
@import './setting/_variables.scss';
@import './setting/_border.scss';
@import './setting/_color.scss';
@import './setting/_space.scss';
@import './setting/_radius.scss';
@import './setting/_text.scss';
@import './setting/_styles.scss';

+ 3
- 0
monitorMobile/uni_modules/uni-scss/styles/setting/_border.scss View File

@@ -0,0 +1,3 @@
.uni-border {
border: 1px $uni-border-1 solid;
}

+ 66
- 0
monitorMobile/uni_modules/uni-scss/styles/setting/_color.scss View File

@@ -0,0 +1,66 @@

// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
// @mixin get-styles($k,$c) {
// @if $k == size or $k == weight{
// font-#{$k}:#{$c}
// }@else{
// #{$k}:#{$c}
// }
// }
$uni-ui-color:(
// 主色
primary: $uni-primary,
primary-disable: $uni-primary-disable,
primary-light: $uni-primary-light,
// 辅助色
success: $uni-success,
success-disable: $uni-success-disable,
success-light: $uni-success-light,
warning: $uni-warning,
warning-disable: $uni-warning-disable,
warning-light: $uni-warning-light,
error: $uni-error,
error-disable: $uni-error-disable,
error-light: $uni-error-light,
info: $uni-info,
info-disable: $uni-info-disable,
info-light: $uni-info-light,
// 中性色
main-color: $uni-main-color,
base-color: $uni-base-color,
secondary-color: $uni-secondary-color,
extra-color: $uni-extra-color,
// 背景色
bg-color: $uni-bg-color,
// 边框颜色
border-1: $uni-border-1,
border-2: $uni-border-2,
border-3: $uni-border-3,
border-4: $uni-border-4,
// 黑色
black:$uni-black,
// 白色
white:$uni-white,
// 透明
transparent:$uni-transparent
) !default;
@each $key, $child in $uni-ui-color {
.uni-#{"" + $key} {
color: $child;
}
.uni-#{"" + $key}-bg {
background-color: $child;
}
}
.uni-shadow-sm {
box-shadow: $uni-shadow-sm;
}
.uni-shadow-base {
box-shadow: $uni-shadow-base;
}
.uni-shadow-lg {
box-shadow: $uni-shadow-lg;
}
.uni-mask {
background-color:$uni-mask;
}

+ 55
- 0
monitorMobile/uni_modules/uni-scss/styles/setting/_radius.scss View File

@@ -0,0 +1,55 @@
@mixin radius($r,$d:null ,$important: false){
$radius-value:map-get($uni-radius, $r) if($important, !important, null);
// Key exists within the $uni-radius variable
@if (map-has-key($uni-radius, $r) and $d){
@if $d == t {
border-top-left-radius:$radius-value;
border-top-right-radius:$radius-value;
}@else if $d == r {
border-top-right-radius:$radius-value;
border-bottom-right-radius:$radius-value;
}@else if $d == b {
border-bottom-left-radius:$radius-value;
border-bottom-right-radius:$radius-value;
}@else if $d == l {
border-top-left-radius:$radius-value;
border-bottom-left-radius:$radius-value;
}@else if $d == tl {
border-top-left-radius:$radius-value;
}@else if $d == tr {
border-top-right-radius:$radius-value;
}@else if $d == br {
border-bottom-right-radius:$radius-value;
}@else if $d == bl {
border-bottom-left-radius:$radius-value;
}
}@else{
border-radius:$radius-value;
}
}

@each $key, $child in $uni-radius {
@if($key){
.uni-radius-#{"" + $key} {
@include radius($key)
}
}@else{
.uni-radius {
@include radius($key)
}
}
}

@each $direction in t, r, b, l,tl, tr, br, bl {
@each $key, $child in $uni-radius {
@if($key){
.uni-radius-#{"" + $direction}-#{"" + $key} {
@include radius($key,$direction,false)
}
}@else{
.uni-radius-#{$direction} {
@include radius($key,$direction,false)
}
}
}
}

+ 56
- 0
monitorMobile/uni_modules/uni-scss/styles/setting/_space.scss View File

@@ -0,0 +1,56 @@

@mixin fn($space,$direction,$size,$n) {
@if $n {
#{$space}-#{$direction}: #{$size*$uni-space-root}px
} @else {
#{$space}-#{$direction}: #{-$size*$uni-space-root}px
}
}
@mixin get-styles($direction,$i,$space,$n){
@if $direction == t {
@include fn($space, top,$i,$n);
}
@if $direction == r {
@include fn($space, right,$i,$n);
}
@if $direction == b {
@include fn($space, bottom,$i,$n);
}
@if $direction == l {
@include fn($space, left,$i,$n);
}
@if $direction == x {
@include fn($space, left,$i,$n);
@include fn($space, right,$i,$n);
}
@if $direction == y {
@include fn($space, top,$i,$n);
@include fn($space, bottom,$i,$n);
}
@if $direction == a {
@if $n {
#{$space}:#{$i*$uni-space-root}px;
} @else {
#{$space}:#{-$i*$uni-space-root}px;
}
}
}

@each $orientation in m,p {
$space: margin;
@if $orientation == m {
$space: margin;
} @else {
$space: padding;
}
@for $i from 0 through 16 {
@each $direction in t, r, b, l, x, y, a {
.uni-#{$orientation}#{$direction}-#{$i} {
@include get-styles($direction,$i,$space,true);
}
.uni-#{$orientation}#{$direction}-n#{$i} {
@include get-styles($direction,$i,$space,false);
}
}
}
}

+ 167
- 0
monitorMobile/uni_modules/uni-scss/styles/setting/_styles.scss View File

@@ -0,0 +1,167 @@
/* #ifndef APP-NVUE */

$-color-white:#fff;
$-color-black:#000;
@mixin base-style($color) {
color: #fff;
background-color: $color;
border-color: mix($-color-black, $color, 8%);
&:not([hover-class]):active {
background: mix($-color-black, $color, 10%);
border-color: mix($-color-black, $color, 20%);
color: $-color-white;
outline: none;
}
}
@mixin is-color($color) {
@include base-style($color);
&[loading] {
@include base-style($color);
&::before {
margin-right:5px;
}
}
&[disabled] {
&,
&[loading],
&:not([hover-class]):active {
color: $-color-white;
border-color: mix(darken($color,10%), $-color-white);
background-color: mix($color, $-color-white);
}
}

}
@mixin base-plain-style($color) {
color:$color;
background-color: mix($-color-white, $color, 90%);
border-color: mix($-color-white, $color, 70%);
&:not([hover-class]):active {
background: mix($-color-white, $color, 80%);
color: $color;
outline: none;
border-color: mix($-color-white, $color, 50%);
}
}
@mixin is-plain($color){
&[plain] {
@include base-plain-style($color);
&[loading] {
@include base-plain-style($color);
&::before {
margin-right:5px;
}
}
&[disabled] {
&,
&:active {
color: mix($-color-white, $color, 40%);
background-color: mix($-color-white, $color, 90%);
border-color: mix($-color-white, $color, 80%);
}
}
}
}


.uni-btn {
margin: 5px;
color: #393939;
border:1px solid #ccc;
font-size: 16px;
font-weight: 200;
background-color: #F9F9F9;
// TODO 暂时处理边框隐藏一边的问题
overflow: visible;
&::after{
border: none;
}

&:not([type]),&[type=default] {
color: #999;
&[loading] {
background: none;
&::before {
margin-right:5px;
}
}



&[disabled]{
color: mix($-color-white, #999, 60%);
&,
&[loading],
&:active {
color: mix($-color-white, #999, 60%);
background-color: mix($-color-white,$-color-black , 98%);
border-color: mix($-color-white, #999, 85%);
}
}

&[plain] {
color: #999;
background: none;
border-color: $uni-border-1;
&:not([hover-class]):active {
background: none;
color: mix($-color-white, $-color-black, 80%);
border-color: mix($-color-white, $-color-black, 90%);
outline: none;
}
&[disabled]{
&,
&[loading],
&:active {
background: none;
color: mix($-color-white, #999, 60%);
border-color: mix($-color-white, #999, 85%);
}
}
}
}

&:not([hover-class]):active {
color: mix($-color-white, $-color-black, 50%);
}

&[size=mini] {
font-size: 16px;
font-weight: 200;
border-radius: 8px;
}



&.uni-btn-small {
font-size: 14px;
}
&.uni-btn-mini {
font-size: 12px;
}

&.uni-btn-radius {
border-radius: 999px;
}
&[type=primary] {
@include is-color($uni-primary);
@include is-plain($uni-primary)
}
&[type=success] {
@include is-color($uni-success);
@include is-plain($uni-success)
}
&[type=error] {
@include is-color($uni-error);
@include is-plain($uni-error)
}
&[type=warning] {
@include is-color($uni-warning);
@include is-plain($uni-warning)
}
&[type=info] {
@include is-color($uni-info);
@include is-plain($uni-info)
}
}
/* #endif */

+ 24
- 0
monitorMobile/uni_modules/uni-scss/styles/setting/_text.scss View File

@@ -0,0 +1,24 @@
@mixin get-styles($k,$c) {
@if $k == size or $k == weight{
font-#{$k}:#{$c}
}@else{
#{$k}:#{$c}
}
}

@each $key, $child in $uni-headings {
/* #ifndef APP-NVUE */
.uni-#{$key} {
@each $k, $c in $child {
@include get-styles($k,$c)
}
}
/* #endif */
/* #ifdef APP-NVUE */
.container .uni-#{$key} {
@each $k, $c in $child {
@include get-styles($k,$c)
}
}
/* #endif */
}

+ 146
- 0
monitorMobile/uni_modules/uni-scss/styles/setting/_variables.scss View File

@@ -0,0 +1,146 @@
// @use "sass:math";
@import '../tools/functions.scss';
// 间距基础倍数
$uni-space-root: 2 !default;
// 边框半径默认值
$uni-radius-root:5px !default;
$uni-radius: () !default;
// 边框半径断点
$uni-radius: map-deep-merge(
(
0: 0,
// TODO 当前版本暂时不支持 sm 属性
// 'sm': math.div($uni-radius-root, 2),
null: $uni-radius-root,
'lg': $uni-radius-root * 2,
'xl': $uni-radius-root * 6,
'pill': 9999px,
'circle': 50%
),
$uni-radius
);
// 字体家族
$body-font-family: 'Roboto', sans-serif !default;
// 文本
$heading-font-family: $body-font-family !default;
$uni-headings: () !default;
$letterSpacing: -0.01562em;
$uni-headings: map-deep-merge(
(
'h1': (
size: 32px,
weight: 300,
line-height: 50px,
// letter-spacing:-0.01562em
),
'h2': (
size: 28px,
weight: 300,
line-height: 40px,
// letter-spacing: -0.00833em
),
'h3': (
size: 24px,
weight: 400,
line-height: 32px,
// letter-spacing: normal
),
'h4': (
size: 20px,
weight: 400,
line-height: 30px,
// letter-spacing: 0.00735em
),
'h5': (
size: 16px,
weight: 400,
line-height: 24px,
// letter-spacing: normal
),
'h6': (
size: 14px,
weight: 500,
line-height: 18px,
// letter-spacing: 0.0125em
),
'subtitle': (
size: 12px,
weight: 400,
line-height: 20px,
// letter-spacing: 0.00937em
),
'body': (
font-size: 14px,
font-weight: 400,
line-height: 22px,
// letter-spacing: 0.03125em
),
'caption': (
'size': 12px,
'weight': 400,
'line-height': 20px,
// 'letter-spacing': 0.03333em,
// 'text-transform': false
)
),
$uni-headings
);



// 主色
$uni-primary: #2979ff !default;
$uni-primary-disable:lighten($uni-primary,20%) !default;
$uni-primary-light: lighten($uni-primary,25%) !default;

// 辅助色
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
$uni-success: #18bc37 !default;
$uni-success-disable:lighten($uni-success,20%) !default;
$uni-success-light: lighten($uni-success,25%) !default;

$uni-warning: #f3a73f !default;
$uni-warning-disable:lighten($uni-warning,20%) !default;
$uni-warning-light: lighten($uni-warning,25%) !default;

$uni-error: #e43d33 !default;
$uni-error-disable:lighten($uni-error,20%) !default;
$uni-error-light: lighten($uni-error,25%) !default;

$uni-info: #8f939c !default;
$uni-info-disable:lighten($uni-info,20%) !default;
$uni-info-light: lighten($uni-info,25%) !default;

// 中性色
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
$uni-main-color: #3a3a3a !default; // 主要文字
$uni-base-color: #6a6a6a !default; // 常规文字
$uni-secondary-color: #909399 !default; // 次要文字
$uni-extra-color: #c7c7c7 !default; // 辅助说明

// 边框颜色
$uni-border-1: #F0F0F0 !default;
$uni-border-2: #EDEDED !default;
$uni-border-3: #DCDCDC !default;
$uni-border-4: #B9B9B9 !default;

// 常规色
$uni-black: #000000 !default;
$uni-white: #ffffff !default;
$uni-transparent: rgba($color: #000000, $alpha: 0) !default;

// 背景色
$uni-bg-color: #f7f7f7 !default;

/* 水平间距 */
$uni-spacing-sm: 8px !default;
$uni-spacing-base: 15px !default;
$uni-spacing-lg: 30px !default;

// 阴影
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;

// 蒙版
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;

+ 19
- 0
monitorMobile/uni_modules/uni-scss/styles/tools/functions.scss View File

@@ -0,0 +1,19 @@
// 合并 map
@function map-deep-merge($parent-map, $child-map){
$result: $parent-map;
@each $key, $child in $child-map {
$parent-has-key: map-has-key($result, $key);
$parent-value: map-get($result, $key);
$parent-type: type-of($parent-value);
$child-type: type-of($child);
$parent-is-map: $parent-type == map;
$child-is-map: $child-type == map;
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
$result: map-merge($result, ( $key: $child ));
}@else {
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
}
}
@return $result;
};

+ 31
- 0
monitorMobile/uni_modules/uni-scss/theme.scss View File

@@ -0,0 +1,31 @@
// 间距基础倍数
$uni-space-root: 2;
// 边框半径默认值
$uni-radius-root:5px;
// 主色
$uni-primary: #2979ff;
// 辅助色
$uni-success: #4cd964;
// 警告色
$uni-warning: #f0ad4e;
// 错误色
$uni-error: #dd524d;
// 描述色
$uni-info: #909399;
// 中性色
$uni-main-color: #303133;
$uni-base-color: #606266;
$uni-secondary-color: #909399;
$uni-extra-color: #C0C4CC;
// 背景色
$uni-bg-color: #f5f5f5;
// 边框颜色
$uni-border-1: #DCDFE6;
$uni-border-2: #E4E7ED;
$uni-border-3: #EBEEF5;
$uni-border-4: #F2F6FC;

// 常规色
$uni-black: #000000;
$uni-white: #ffffff;
$uni-transparent: rgba($color: #000000, $alpha: 0);

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

||||||
x
 
000:0
Loading…
Cancel
Save