wzh пре 2 година
родитељ
комит
3a0a4e398b

+ 8 - 0
api/device/device.js

@@ -146,4 +146,12 @@ export function getDeviceRunTime(deviceid){
         method: 'get',
     })
 }
+//获取所有runtime事件排序
+export function getAllDeviceRunTime(){
+    let url = '/iot/device/rankRunTime'
+    return request({
+        url: url,
+        method: 'get',
+    })
+}
 

+ 33 - 0
api/user/user.js

@@ -32,3 +32,36 @@ export function getUserListByDept(deptId,username){
     })
 }
 
+//新增用户
+export function addUser(user){
+    return request({
+        url:'/system/user',
+        data:user,
+        method: 'post'
+    })
+}
+//编辑用户
+export function editUser(user){
+    return request({
+        url:'/system/user',
+        data:user,
+        method: 'put'
+    })
+}
+
+//重置密码
+export function resetPwd(user){
+    return request({
+        url:'/system/user/resetPwd',
+        data:user,
+        method: 'put'
+    })
+}
+
+//删除用户
+export function deleteUser(id){
+    return request({
+        url:'/system/user/'+id,
+        method: 'delete'
+    })
+}

+ 6 - 0
pages.json

@@ -138,6 +138,12 @@
       "style": {
         "navigationBarTitleText": "注销记录"
       }
+    },
+    {
+      "path": "pages/device/rank",
+      "style": {
+        "navigationBarTitleText": "排行榜"
+      }
     }
   ],
   "tabBar": {

+ 124 - 0
pages/device/rank.vue

@@ -0,0 +1,124 @@
+<template>
+  <view class="work-container">
+    <view style="margin-top: 10px">
+      <uni-table border stripe emptyText="暂无更多数据" >
+        <!-- 表头行 -->
+        <uni-tr>
+          <uni-th align="center" width="100">排名</uni-th>
+          <uni-th align="center" width="100">运行时长</uni-th>
+          <uni-th align="center" width="100">设备名称</uni-th>
+        </uni-tr>
+        <!-- 表格数据行 -->
+        <uni-tr v-for="(item,index) in rankList">
+          <uni-td align="center">{{index+1 }}</uni-td>
+          <uni-td align="center">{{ item.logValue }}</uni-td>
+          <uni-td align="center">{{item.deviceName}}</uni-td>
+        </uni-tr>
+
+
+      </uni-table>
+    </view>
+  </view>
+</template>
+
+<script>
+import {getAllDeviceRunTime} from '@/api/device/device';
+export default {
+  data() {
+    return {
+      rankList:[]
+    }
+  },
+  onLoad(){
+    this.getRank();
+  },
+  methods: {
+      getRank(){
+        let self = this;
+        getAllDeviceRunTime().then(res=>{
+          self.rankList = res.data;
+        })
+      },
+  }
+}
+</script>
+
+<style lang="scss">
+/* #ifndef APP-NVUE */
+.u-collapse-content{
+  display: flex;
+  flex-direction: column;
+}
+page {
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+  background-color: #fff;
+  min-height: 100%;
+  height: auto;
+}
+
+view {
+  font-size: 14px;
+  line-height: inherit;
+}
+
+/* #endif */
+
+.text {
+  text-align: center;
+  font-size: 26rpx;
+  margin-top: 10rpx;
+}
+
+.grid-item-box {
+  flex: 1;
+  /* #ifndef APP-NVUE */
+  display: flex;
+  /* #endif */
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 15px 0;
+}
+
+.uni-margin-wrap {
+  width: 690rpx;
+  width: 100%;
+;
+}
+
+.swiper {
+  height: 300rpx;
+}
+
+.swiper-box {
+  height: 150px;
+}
+
+.swiper-item {
+  /* #ifndef APP-NVUE */
+  display: flex;
+  /* #endif */
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  color: #fff;
+  height: 300rpx;
+  line-height: 300rpx;
+}
+
+@media screen and (min-width: 500px) {
+  .uni-swiper-dot-box {
+    width: 400px;
+    /* #ifndef APP-NVUE */
+    margin: 0 auto;
+    /* #endif */
+    margin-top: 8px;
+  }
+
+  .image {
+    width: 100%;
+  }
+}
+</style>

+ 6 - 0
pages/mine/index.vue

@@ -9,6 +9,7 @@
           </view>
           <image v-if="avatar" @click="handleToAvatar" :src="avatar" class="cu-avatar xl round" mode="widthFix">
           </image>
+
           <view v-if="!name" @click="handleToLogin" class="login-tip">
             点击登录
           </view>
@@ -22,6 +23,10 @@
           <text>个人信息</text>
           <view class="iconfont icon-right"></view>
         </view>
+
+      </view>
+      <view v-if="user != null"  class="login-tip" style="text-align: center;">
+        {{ user.dept.deptName }}
       </view>
     </view>
 
@@ -82,6 +87,7 @@
   export default {
     data() {
       return {
+        user:this.$store.state.user.user,
         name: this.$store.state.user.name,
         version: getApp().globalData.config.appInfo.version
       }

+ 212 - 3
pages/user/list.vue

@@ -6,39 +6,248 @@
     <view style="margin-top: 10px">
       <uni-list :border="true">
         <!-- 显示圆形头像 -->
-        <view v-for="item in userList">
+        <view style="position: relative" v-for="item in userList">
 
           <uni-list-chat v-if="item.avatar != ''"  :avatar-circle="true" :title="item.nickName" :avatar="item.avatar" :note="item.phonenumber" :time="item.createTime" ></uni-list-chat>
           <uni-list-chat  v-else :avatar-circle="true" :title="item.nickName" avatar="/static/images/device/user.png" :note="item.phonenumber" :time="item.createTime" ></uni-list-chat>
 
+          <view v-if="isCanEdit()" @click="modifyUser(item)" style="position: absolute;right: 120rpx;bottom: 20rpx;font-size: 12px;z-index: 999">修改</view>
+          <view v-if="isCanEdit()" @click="delUser(item)" style="position: absolute;right: 40rpx;bottom: 20rpx;font-size: 12px;z-index: 999">删除</view>
+          <view  style="position: absolute;right: 270rpx;bottom: 10px;font-size: 12px">
+            <u-tag v-if="item.status == 1" text="禁用" plain size="mini" type="warning"></u-tag>
+            <u-tag v-if="item.status == 0" text="启用" plain size="mini" type="success"></u-tag>
+          </view>
         </view>
 
 
       </uni-list>
+
+      <view v-if="isCanEdit()" style="position: absolute;bottom: 0px;text-align: center;width: 100%">
+        <u-button type="primary" text="新增用户" @click="newUser"></u-button>
+      </view>
+
+      <u-modal  :show="showAdd || showEdit" title="编辑用户" @cancel="closeDlg" :showCancelButton="true"  @confirm="doAddUser" >
+        <view class="slot-content">
+          <u--form
+              labelPosition="left"
+              :model="model1"
+              :rules="rules"
+              ref="uForm"
+          >
+            <u-form-item
+                label="昵称"
+                prop="chooseUser.nickName"
+                borderBottom
+                ref="item1"
+                labelWidth="auto"
+            >
+              <u--input
+                  v-model="chooseUser.nickName"
+                  border="none"
+              ></u--input>
+            </u-form-item>
+
+            <u-form-item
+                label="手机号"
+                prop="chooseUser.phonenumber"
+                borderBottom
+                ref="item1"
+                labelWidth="auto"
+            >
+              <u--input
+                  v-model="chooseUser.phonenumber"
+                  border="none"
+              ></u--input>
+            </u-form-item>
+
+            <u-form-item
+                label="密码"
+                prop="chooseUser.password"
+                borderBottom
+                ref="item1"
+                labelWidth="auto"
+            >
+              <u--input v-if="showAdd"
+                        v-model="chooseUser.password"
+                        border="none"
+              ></u--input>
+
+             <view style="width:100rpx"  v-if="showEdit">
+               <u-button width="100rpx" type="warning" size="mini" @click="resetPwd()" text="重置密码"></u-button>
+             </view>
+            </u-form-item>
+
+            <u-form-item
+                label="登录账号"
+                borderBottom
+                ref="item1"
+                labelWidth="auto"
+            >
+              <u--input
+                  v-model="chooseUser.phonenumber"
+                  border="none"
+                  disabled
+              ></u--input>
+            </u-form-item>
+            <u-form-item
+                label="状态"
+                prop="chooseUser.password"
+                borderBottom
+                ref="item1"
+                labelWidth="auto"
+            >
+              <u-radio-group
+                  v-model="statusValue"
+                  placement="row"
+              >
+                <u-radio
+                    v-for="(item, index) in statusList"
+                    :key="index"
+                    :label="item.name"
+                    :name="item.name"
+                    @change="statusChange"
+                >
+                </u-radio>
+              </u-radio-group>
+            </u-form-item>
+          </u--form>
+
+        </view>
+      </u-modal>
     </view>
   </view>
 </template>
 
 <script>
 import authObj from '@/plugins/auth.js';
-import {getDeptList,getUserListByDept} from '@/api/user/user';
+import {getDeptList,getUserListByDept,addUser,editUser,resetPwd,deleteUser} from '@/api/user/user';
 import UText from "../../uni_modules/uview-ui/components/u-text/u-text";
+import UButton from "../../uni_modules/uview-ui/components/u-button/u-button";
 export default {
-  components: {UText},
+  components: {UButton, UText},
   data() {
       return {
+        statusList:[{  name: '启用',
+          disabled: false
+        },
+          {
+            name: '禁用',
+            disabled: false
+          }],
+        statusValue: '启用',
         userList:[],
         search:{
           userName:""
         },
         deptId:0,
+        showEdit:false,
+        showAdd:false,
+        chooseUser:{},
+        rules: {
+          'chooseUser.nickName': {
+            type: 'string',
+            required: true,
+            message: '请填写姓名',
+            trigger: ['blur', 'change']
+          },
+          'chooseUser.phonenumber': {
+            type: 'number',
+            len: 11,
+            required: true,
+            message: '请选择男或女',
+            trigger: ['blur', 'change'],
+          },
+        },
       }
     },
   onLoad(opt){
     this.deptId = opt.deptId;
+    if(this.deptId == 'undefined'){
+      this.deptId = 0;
+    }
     this.getUser();
   },
     methods: {
+      isCanEdit(){
+        return authObj.authRoleAdmin(["companymgr",'admin'])
+      },
+      delUser(user){
+        let self = this;
+        uni.showModal({
+          title: '提示',
+          content: '确认要删除该用户么?',
+          success: function (res) {
+            if (res.confirm) {
+              deleteUser(user.userId).then(res=>{
+                self.$modal.showToast("操作成功");
+                self.getUser();
+              });
+            } else if (res.cancel) {
+              console.log('用户点击取消');
+            }
+          }
+        });
+
+      },
+      modifyUser(user){
+        this.chooseUser = user;
+        this.showEdit = true;
+      },
+      statusChange(e){
+        console.log(e);
+      },
+      closeDlg(){
+        this.showEdit = false;
+        this.showAdd = false;
+        this.chooseUser = {};
+      },
+     newUser(){
+       this.showAdd = true;
+     },
+      doAddUser(){
+        let self = this;
+        this.chooseUser.postIds=[];
+        this.chooseUser.roleIds=[];
+        if(this.statusValue == '启用'){
+          this.chooseUser.status = 0;
+        }else{
+          this.chooseUser.status = 1;
+        }
+        this.chooseUser.userName = this.chooseUser.phonenumber;
+        if(this.showAdd){
+          addUser(this.chooseUser).then(res=>{
+            self.getUser()
+            self.closeDlg();
+          });
+        }
+        if(this.showEdit){
+          editUser(this.chooseUser).then(res=>{
+            self.getUser()
+            self.closeDlg();
+          });
+        }
+
+      },
+      resetPwd(){
+        this.showEdit = false;
+        let self = this;
+        let userId = this.chooseUser.userId;
+        uni.showModal({
+          title: '提示',
+          editable:true,
+          placeholderText: '请输入新密码',
+          success: function (res) {
+            if (res.confirm) {
+              resetPwd({userId:userId,password:res.content}).then(res=>{
+               self.$modal.showToast("操作成功");
+             })
+            } else if (res.cancel) {
+              console.log('用户点击取消');
+            }
+          }
+        });
+
+      },
       searchDept(){
         this.getUser();
       },

+ 39 - 4
pages/work/index.vue

@@ -21,7 +21,13 @@
             <text class="text">客户列表</text>
           </view>
         </uni-grid-item>
-        <uni-grid-item v-if="hasRole(['companymgr'])">
+        <uni-grid-item v-if="isCompanyUser()">
+          <view class="grid-item-box" @click="goPage('deptuser')">
+            <u--image :showLoading="true" src="/static/images/icons/user.png" width="50rpx" height="50rpx" ></u--image>
+            <text class="text">用户管理</text>
+          </view>
+        </uni-grid-item>
+        <uni-grid-item v-if="isCompanyUser()">
           <view class="grid-item-box" @click="goPage('device')">
             <u--image :showLoading="true" src="/static/images/icons/device.png" width="50rpx" height="50rpx" ></u--image>
             <text class="text">设备列表</text>
@@ -41,7 +47,7 @@
         </uni-grid-item>
 
 
-        <uni-grid-item v-if="hasRole(['companymgr'])">
+        <uni-grid-item v-if="isCompanyUser()">
           <view class="grid-item-box" @click="scanCode()">
             <u--image :showLoading="true" src="/static/images/icons/scan.png" width="50rpx" height="50rpx" ></u--image>
             <text class="text">用户绑定</text>
@@ -55,14 +61,14 @@
           </view>
         </uni-grid-item>
 
-        <uni-grid-item v-if="hasRole(['companymgr'])">
+        <uni-grid-item v-if="isCompanyUser()">
           <view class="grid-item-box" @click="goPage('alert')">
             <u--image :showLoading="true" src="/static/images/icons/alert.png" width="50rpx" height="50rpx" ></u--image>
             <text class="text">设备告警</text>
           </view>
         </uni-grid-item>
 
-        <uni-grid-item v-if="hasRole(['companymgr'])">
+        <uni-grid-item v-if="isCompanyUser()">
           <view class="grid-item-box" @click="goPage('error')">
             <u--image :showLoading="true" src="/static/images/icons/error.png" width="50rpx" height="50rpx" ></u--image>
             <text class="text">异常列表</text>
@@ -76,6 +82,13 @@
           </view>
         </uni-grid-item>
 
+        <uni-grid-item>
+          <view class="grid-item-box" @click="goPage('time')">
+            <u--image :showLoading="true" src="/static/images/icons/rank.png" width="50rpx" height="50rpx" ></u--image>
+            <text class="text">时长排名</text>
+          </view>
+        </uni-grid-item>
+
       </uni-grid>
 
       <u-modal :show="show" :title="dlgTitle" @cancel="cancel" :showCancelButton="true" @confirm="bingDevice" >
@@ -100,6 +113,7 @@ export default {
   components: {UImage},
   data() {
       return {
+        deptId:0,
         dlgTitle:"",
         current: 0,
         swiperDotIndex: 0,
@@ -117,6 +131,13 @@ export default {
         ]
       }
     },
+  onLoad(){
+    if(this.isCompanyUser()){
+      this.deptId = this.$store.state.user.user.deptId;
+      console.log( this.deptId );
+    }
+
+  },
     methods: {
       bingDevice(){
           this.show = false;
@@ -139,6 +160,9 @@ export default {
       hasRole(role){
         return authObj.authRoleAdmin(role);
       },
+      isCompanyUser(){
+        return authObj.authRoleAdmin(["companymgr"]) || authObj.authRoleAdmin(["companyuser"]);
+      },
       changeSwiper(e) {
         this.current = e.detail.current
       },
@@ -195,6 +219,11 @@ export default {
       },
 
       goPage(path){
+        if('deptuser' == path){
+          uni.navigateTo({
+            url: '/pages/user/list?deptId='+this.deptId
+          });
+        }
         if('device' == path){
           uni.navigateTo({
             url: '/pages/device/index'
@@ -231,6 +260,12 @@ export default {
           });
         }
 
+        if('time' == path){
+          uni.navigateTo({
+            url: '/pages/device/rank'
+          });
+        }
+
       }
     }
   }

BIN
static/images/icons/rank.png


+ 7 - 1
store/modules/user.js

@@ -13,7 +13,8 @@ const user = {
     avatar: storage.get(constant.avatar),
     roles: storage.get(constant.roles),
     permissions: storage.get(constant.permissions),
-    id:storage.get(constant.id)
+    id:storage.get(constant.id),
+    user:storage.get("vuex_user")
   },
 
   mutations: {
@@ -39,6 +40,10 @@ const user = {
     SET_ID: (state, id) => {
       state.id = id
       storage.set(constant.id, id)
+    },
+    SET_USER: (state, user) => {
+      state.user = user
+      storage.set("vuex_user", user)
     }
   },
 
@@ -74,6 +79,7 @@ const user = {
           } else {
             commit('SET_ROLES', ['ROLE_DEFAULT'])
           }
+          commit('SET_USER',user)
           commit('SET_ID', userId)
           commit('SET_NAME', username)
           commit('SET_AVATAR', avatar)

+ 67 - 33
uni_modules/uni-datetime-picker/changelog.md

@@ -1,41 +1,75 @@
+## 2.2.23(2023-05-02)
+- 修复 部分情况修改时间,开始时间未更新 [详情](https://github.com/dcloudio/uni-ui/issues/737)
+- 修复 部分平台及设备第一次点击无法显示弹框
+- 修复 ios 日期格式未补零显示及使用异常 [详情](https://ask.dcloud.net.cn/question/162979)
+## 2.2.22(2023-03-30)
+- 修复 日历 picker 修改年月后,自动选中当月1日 [详情](https://ask.dcloud.net.cn/question/165937)
+- 修复 小程序端 低版本 ios NaN [详情](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 属性支持配置选择器打开时默认显示的时间
+- 优化 非范围选择未选择日期时间,点击确认按钮选中当前日期时间
+- 优化 字节小程序日期时间范围选择,底部日期换行问题
+## 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)
-- 修复,支付宝小程序样式错乱,[详情](https://github.com/dcloudio/uni-app/issues/3861)
+- 修复 支付宝小程序样式错乱的Bug [详情](https://github.com/dcloudio/uni-app/issues/3861)
 ## 2.2.10(2022-09-19)
-- 修复,反向选择日期范围,日期显示异常,[详情](https://ask.dcloud.net.cn/question/153401?item_id=212892&rf=false)
+- 修复 反向选择日期范围,日期显示异常的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
+- 修复 close事件无效的Bug
 ## 2.2.7(2022-09-05)
-- 修复 移动端 maskClick 无效的 bug,详见:[https://ask.dcloud.net.cn/question/140824?item_id=209458&rf=false](https://ask.dcloud.net.cn/question/140824?item_id=209458&rf=false)
+- 修复 移动端 maskClick 无效的Bug [详情](https://ask.dcloud.net.cn/question/140824)
 ## 2.2.6(2022-06-30)
 - 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致
 ## 2.2.5(2022-06-24)
-- 修复 日历顶部年月及底部确认未国际化 bug
+- 修复 日历顶部年月及底部确认未国际化的Bug
 ## 2.2.4(2022-03-31)
-- 修复 Vue3 下动态赋值,单选类型未响应的 bug
+- 修复 Vue3 下动态赋值,单选类型未响应的Bug
 ## 2.2.3(2022-03-28)
-- 修复 Vue3 下动态赋值未响应的 bug
+- 修复 Vue3 下动态赋值未响应的Bug
 ## 2.2.2(2021-12-10)
-- 修复 clear-icon 属性在小程序平台不生效的 bug
+- 修复 clear-icon 属性在小程序平台不生效的Bug
 ## 2.2.1(2021-12-10)
-- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的 bug
+- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的Bug
 ## 2.2.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-datetime-picker](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
-## 2.1.5(2021-11-09) 
+- 优化 组件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
+- 修复 hide-second 在移动端的Bug
+- 修复 单选赋默认值时,赋值日期未高亮的Bug
+- 修复 赋默认值时,移动端未正确显示时间的Bug
 ## 2.1.3(2021-09-09)
 - 新增 hide-second 属性,支持只使用时分,隐藏秒
 ## 2.1.2(2021-09-03)
 - 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
 - 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
 - 优化 调整字号大小,美化日历界面
-- 修复 因国际化导致的 placeholder 失效的 bug
+- 修复 因国际化导致的 placeholder 失效的Bug
 ## 2.1.1(2021-08-24)
 - 新增 支持国际化
 - 优化 范围选择器在 pc 端过宽的问题
@@ -43,50 +77,50 @@
 - 新增 适配 vue3
 ## 2.0.19(2021-08-09)
 - 新增 支持作为 uni-forms 子组件相关功能
-- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug
+- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的Bug
 ## 2.0.18(2021-08-05)
-- 修复 type 属性动态赋值无效的 bug
+- 修复 type 属性动态赋值无效的Bug
 - 修复 ‘确认’按钮被 tabbar 遮盖 bug
-- 修复 组件未赋值时范围选左、右日历相同的 bug
+- 修复 组件未赋值时范围选左、右日历相同的Bug
 ## 2.0.17(2021-08-04)
-- 修复 范围选未正确显示当前值的 bug
-- 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug
+- 修复 范围选未正确显示当前值的Bug
+- 修复 h5 平台(移动端)报错 'cale' of undefined 的Bug
 ## 2.0.16(2021-07-21)
 - 新增 return-type 属性支持返回 date 日期对象
 ## 2.0.15(2021-07-14)
-- 修复 单选日期类型,初始赋值后不在当前日历的 bug
+- 修复 单选日期类型,初始赋值后不在当前日历的Bug
 - 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效)
 - 优化 移动端移除显示框的清空按钮,无实际用途
 ## 2.0.14(2021-07-14)
-- 修复 组件赋值为空,界面未更新的 bug
-- 修复 start 和 end 不能动态赋值的 bug
-- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的 bug
+- 修复 组件赋值为空,界面未更新的Bug
+- 修复 start 和 end 不能动态赋值的Bug
+- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的Bug
 ## 2.0.13(2021-07-08)
-- 修复 范围选择不能动态赋值的 bug
+- 修复 范围选择不能动态赋值的Bug
 ## 2.0.12(2021-07-08)
 - 修复 范围选择的初始时间在一个月内时,造成无法选择的bug
 ## 2.0.11(2021-07-08)
 - 优化 弹出层在超出视窗边缘定位不准确的问题
 ## 2.0.10(2021-07-08)
-- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的 bug
+- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的Bug
 - 优化 弹出层在超出视窗边缘被遮盖的问题
 ## 2.0.9(2021-07-07)
 - 新增 maskClick 事件
-- 修复 特殊情况日历 rpx 布局错误的 bug,rpx -> px
+- 修复 特殊情况日历 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
+- 修复 图标在小程序上不显示的Bug
 - 优化 重命名引用组件,避免潜在组件命名冲突
 ## 2.0.5(2021-05-20)
 - 优化 代码目录扁平化
 ## 2.0.4(2021-05-12)
 - 新增 组件示例地址
 ## 2.0.3(2021-05-10)
-- 修复 ios 下不识别 '-' 日期格式的 bug
+- 修复 ios 下不识别 '-' 日期格式的Bug
 - 优化 pc 下弹出层添加边框和阴影
 ## 2.0.2(2021-05-08)
 - 修复 在 admin 中获取弹出层定位错误的bug
@@ -97,7 +131,7 @@
  > 注意:此版本不向后兼容,不再支持单独时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)
 ## 1.0.6(2021-03-18)
 - 新增 hide-second 属性,时间支持仅选择时、分
-- 修复 选择跟显示的日期不一样的 bug
-- 修复 chang事件触发2次的 bug
-- 修复 分、秒 end 范围错误的 bug
+- 修复 选择跟显示的日期不一样的Bug
+- 修复 chang事件触发2次的Bug
+- 修复 分、秒 end 范围错误的Bug
 - 优化 更好的 nvue 适配

+ 5 - 15
uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue

@@ -13,10 +13,10 @@
 				'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 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--isDay': weeks.isDay}"></view>
+		<view :class="{'uni-calendar-item--today': weeks.isToday}"></view>
 	</view>
 </template>
 
@@ -41,10 +41,6 @@
 					return []
 				}
 			},
-			lunar: {
-				type: Boolean,
-				default: false
-			},
 			checkHover: {
 				type: Boolean,
 				default: false
@@ -61,8 +57,8 @@
 	}
 </script>
 
-<style lang="scss" >
-	$uni-primary: #007aff !default;
+<style lang="scss" >
+	$uni-primary: #007aff !default;
 
 	.uni-calendar-item__weeks-box {
 		flex: 1;
@@ -83,11 +79,6 @@
 		color: darken($color: $uni-primary, $amount: 40%);
 	}
 
-	.uni-calendar-item__weeks-lunar-text {
-		font-size: 12px;
-		color: #333;
-	}
-
 	.uni-calendar-item__weeks-box-item {
 		position: relative;
 		/* #ifndef APP-NVUE */
@@ -116,7 +107,6 @@
 	}
 
 	.uni-calendar-item__weeks-box .uni-calendar-item--disable {
-		// background-color: rgba(249, 249, 249, $uni-opacity-disabled);
 		cursor: default;
 	}
 
@@ -124,7 +114,7 @@
 		color: #D1D1D1;
 	}
 
-	.uni-calendar-item--isDay {
+	.uni-calendar-item--today {
 		position: absolute;
 		top: 10px;
 		right: 17%;

+ 154 - 140
uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue

@@ -1,31 +1,37 @@
 <template>
 	<view class="uni-calendar" @mouseleave="leaveCale">
-		<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}"
-			@click="clean();maskClick()"></view>
+
+		<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 v-if="left" class="uni-calendar__header-btn-box" @click.stop="pre">
+
+				<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 v-if="right" class="uni-calendar__header-btn-box" @click.stop="next">
+
+				<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="clean">
+
+				<view v-if="!insert" class="dialog-close" @click="close">
 					<view class="dialog-close-plus" data-id="close"></view>
 					<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
 				</view>
-
-				<!-- <text class="uni-calendar__backtoday" @click="backtoday">回到今天</text> -->
 			</view>
 			<view class="uni-calendar__box">
+
 				<view v-if="showMonth" class="uni-calendar__box-bg">
 					<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
 				</view>
+
 				<view class="uni-calendar__weeks" style="padding-bottom: 7px;">
 					<view class="uni-calendar__weeks-day">
 						<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
@@ -49,45 +55,45 @@
 						<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" :lunar="lunar" :checkHover="range" @change="choiceDate"
+							:selected="selected" :checkHover="range" @change="choiceDate"
 							@handleMouse="handleMouse">
 						</calendar-item>
 					</view>
 				</view>
 			</view>
-			<view v-if="!insert && !range && typeHasTime" class="uni-date-changed uni-calendar--fixed-top"
+
+			<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="reactStartTime" :end="reactEndTime" v-model="time"
+				<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 && typeHasTime" class="uni-date-changed uni-calendar--fixed-top">
+			<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="reactStartTime" v-model="timeRange.startTime" :border="false"
+					<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;">
+				</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="reactEndTime" v-model="timeRange.endTime" :border="false"
+					<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-calendar__header-btn-box">
-					<text class="uni-calendar__button-text uni-calendar--fixed-width">{{okText}}</text>
-				</view> -->
 				<view class="uni-datetime-picker--btn" @click="confirm">{{confirmText}}</view>
 			</view>
 		</view>
@@ -95,22 +101,19 @@
 </template>
 
 <script>
-	import Calendar from './util.js';
+	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 messages from './i18n/index.js'
-	const {
-		t
-	} = initVueI18n(messages)
+
+	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 {Boolean} lunar 显示农历
 	 * @property {String} startDate 日期选择范围-开始日期
 	 * @property {String} endDate 日期选择范围-结束日期
 	 * @property {Boolean} range 范围选择
@@ -120,10 +123,11 @@
 	 * @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":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
+	 * @example <uni-calendar :insert="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
 	 */
 	export default {
 		components: {
@@ -151,10 +155,6 @@
 					return []
 				}
 			},
-			lunar: {
-				type: Boolean,
-				default: false
-			},
 			startDate: {
 				type: String,
 				default: ''
@@ -163,11 +163,19 @@
 				type: String,
 				default: ''
 			},
+      startPlaceholder: {
+        type: String,
+				default: ''
+			},
+			endPlaceholder: {
+				type: String,
+				default: ''
+			},
 			range: {
 				type: Boolean,
 				default: false
 			},
-			typeHasTime: {
+			hasTime: {
 				type: Boolean,
 				default: false
 			},
@@ -183,14 +191,6 @@
 				type: Boolean,
 				default: true
 			},
-			left: {
-				type: Boolean,
-				default: true
-			},
-			right: {
-				type: Boolean,
-				default: true
-			},
 			checkHover: {
 				type: Boolean,
 				default: true
@@ -209,14 +209,18 @@
 						fulldate: ''
 					}
 				}
-			}
+			},
+      defaultValue: {
+        type: [String, Object, Array],
+        default: ''
+      }
 		},
 		data() {
 			return {
 				show: false,
 				weeks: [],
 				calendar: {},
-				nowDate: '',
+				nowDate: {},
 				aniMaskShow: false,
 				firstEnter: true,
 				time: '',
@@ -228,13 +232,14 @@
 				tempRange: {
 					before: '',
 					after: ''
-				}
+				},
+        isPhone: false
 			}
 		},
 		watch: {
 			date: {
 				immediate: true,
-				handler(newVal, oldVal) {
+				handler(newVal) {
 					if (!this.range) {
 						this.tempSingleDate = newVal
 						setTimeout(() => {
@@ -245,33 +250,44 @@
 			},
 			defTime: {
 				immediate: true,
-				handler(newVal, oldVal) {
+				handler(newVal) {
 					if (!this.range) {
 						this.time = newVal
 					} else {
-						// console.log('-----', newVal);
 						this.timeRange.startTime = newVal.start
 						this.timeRange.endTime = newVal.end
 					}
 				}
 			},
 			startDate(val) {
-				this.cale.resetSatrtDate(val)
+				// 字节小程序 watch 早于 created
+				if(!this.cale){
+					return
+				}
+				this.cale.setStartDate(val)
 				this.cale.setDate(this.nowDate.fullDate)
 				this.weeks = this.cale.weeks
 			},
 			endDate(val) {
-				this.cale.resetEndDate(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, oldVal) {
+				handler(newVal) {
 					const {
 						before,
 						after,
@@ -294,11 +310,16 @@
 								this.cale.lastHover = false
 							}
 						} else {
+              // 字节小程序 watch 早于 created
+              if(!this.cale){
+                return
+              }
+
 							this.cale.setDefaultMultiple(before, after)
-							if (which === 'left') {
+							if (which === 'left' && before) {
 								this.setDate(before)
 								this.weeks = this.cale.weeks
-							} else {
+							} else if(after) {
 								this.setDate(after)
 								this.weeks = this.cale.weeks
 							}
@@ -309,15 +330,13 @@
 			}
 		},
 		computed: {
-			reactStartTime() {
+			timepickerStartTime() {
 				const activeDate = this.range ? this.tempRange.before : this.calendar.fullDate
-				const res = activeDate === this.startDate ? this.selectableTimes.start : ''
-				return res
+				return activeDate === this.startDate ? this.selectableTimes.start : ''
 			},
-			reactEndTime() {
+			timepickerEndTime() {
 				const activeDate = this.range ? this.tempRange.after : this.calendar.fullDate
-				const res = activeDate === this.endDate ? this.selectableTimes.end : ''
-				return res
+				return activeDate === this.endDate ? this.selectableTimes.end : ''
 			},
 			/**
 			 * for i18n
@@ -368,18 +387,22 @@
 		created() {
 			// 获取日历方法实例
 			this.cale = new Calendar({
-				// date: new Date(),
 				selected: this.selected,
 				startDate: this.startDate,
 				endDate: this.endDate,
 				range: this.range,
-				// multipleStatus: this.pleStatus
 			})
 			// 选中某一天
-			// this.cale.setDate(this.date)
 			this.init(this.date)
-			// this.setDay
 		},
+    mounted(){
+      if(typeof navigator !== "undefined"){
+        this.isPhone = navigator.userAgent.toLowerCase().indexOf('mobile') !== -1
+        return
+      }
+      const { windowWidth } = uni.getSystemInfoSync()
+      this.isPhone = windowWidth <= 500
+    },
 		methods: {
 			leaveCale() {
 				this.firstEnter = true
@@ -407,14 +430,9 @@
 				const [yearB, monthB] = B.split('-')
 				return yearA === yearB && monthA === monthB
 			},
-
-			// 取消穿透
-			clean() {
-				this.close()
-			},
-
 			// 蒙版点击事件
 			maskClick() {
+        this.close()
 				this.$emit('maskClose')
 			},
 
@@ -433,33 +451,49 @@
 					this.tempSingleDate = ''
 				}
 				this.calendar.fullDate = ''
-				this.setDate()
+				this.setDate(new Date())
 			},
 
 			bindDateChange(e) {
 				const value = e.detail.value + '-1'
-				this.init(value)
+				this.setDate(value)
 			},
 			/**
 			 * 初始化日期显示
 			 * @param {Object} date
 			 */
 			init(date) {
-				this.cale.setDate(date)
+        // 字节小程序 watch 早于 created
+				if(!this.cale){
+					return
+				}
+				this.cale.setDate(date || new Date())
 				this.weeks = this.cale.weeks
-				this.nowDate = this.calendar = this.cale.getInfo(date)
-			},
-			// choiceDate(weeks) {
-			// 	if (weeks.disable) return
-			// 	this.calendar = weeks
-			// 	// 设置多选
-			// 	this.cale.setMultiple(this.calendar.fullDate, true)
-			// 	this.weeks = this.cale.weeks
-			// 	this.tempSingleDate = this.calendar.fullDate
-			// 	this.tempRange.before = this.cale.multipleStatus.before
-			// 	this.tempRange.after = this.cale.multipleStatus.after
-			// 	this.change()
-			// },
+				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)
+          }
+        }
+			},
 			/**
 			 * 打开日历弹窗
 			 */
@@ -467,7 +501,6 @@
 				// 弹窗模式并且清理数据
 				if (this.clearDate && !this.insert) {
 					this.cale.cleanMultipleStatus()
-					// this.cale.setDate(this.date)
 					this.init(this.date)
 				}
 				this.show = true
@@ -521,12 +554,20 @@
 			 * @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,
-					lunar,
 					extraInfo
 				} = this.calendar
 				this.$emit(name, {
@@ -537,7 +578,6 @@
 					time: this.time,
 					timeRange: this.timeRange,
 					fulldate: fullDate,
-					lunar,
 					extraInfo: extraInfo || {}
 				})
 			},
@@ -545,66 +585,37 @@
 			 * 选择天触发
 			 * @param {Object} weeks
 			 */
-			choiceDate(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 beforeStatus = this.cale.multipleStatus.before
-				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()
-			},
-			/**
-			 * 回到今天
-			 */
-			backtoday() {
-				let date = this.cale.getDate(new Date()).fullDate
-				// this.cale.setDate(date)
-				this.init(date)
-				this.change()
-			},
-			/**
-			 * 比较时间大小
-			 */
-			dateCompare(startDate, endDate) {
-				// 计算截止时间
-				startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
-				// 计算详细项的截止时间
-				endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
-				if (startDate <= endDate) {
-					return true
+				this.tempSingleDate = this.calendar.fullDate
+				const beforeDate = new Date(this.cale.multipleStatus.before).getTime()
+				const afterDate = new Date(this.cale.multipleStatus.after).getTime()
+        // 这里返回的 before after 为什么要做替换?导致PC端如果开始结束日期都是今天,第一次选择开始日期早于今天,开始日期不更新
+				if (beforeDate > afterDate && afterDate && !this.isPhone) {
+					this.tempRange.before = this.cale.multipleStatus.after
+					this.tempRange.after = this.cale.multipleStatus.before
 				} else {
-					return false
+					this.tempRange.before = this.cale.multipleStatus.before
+					this.tempRange.after = this.cale.multipleStatus.after
 				}
+				this.change()
 			},
-			/**
-			 * 上个月
-			 */
-			pre() {
-				const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
-				this.setDate(preDate)
-				this.monthSwitch()
+      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
+        }
 
-			},
-			/**
-			 * 下个月
-			 */
-			next() {
-				const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
-				this.setDate(nextDate)
+        this.setDate(newDate)
 				this.monthSwitch()
-			},
+      },
 			/**
 			 * 设置日期
 			 * @param {Object} date
@@ -618,8 +629,8 @@
 	}
 </script>
 
-<style lang="scss" >
-	$uni-primary: #007aff !default;
+<style lang="scss" >
+	$uni-primary: #007aff !default;
 
 	.uni-calendar {
 		/* #ifndef APP-NVUE */
@@ -854,14 +865,17 @@
 
 	.uni-date-changed--time-end {
 		/* #ifndef APP-NVUE */
-		display: flex;
+    display: flex;
 		/* #endif */
 		align-items: center;
 	}
 
 	.uni-date-changed--time-date {
-		color: #999;
+    color: #999;
 		line-height: 50px;
+    /* #ifdef MP-TOUTIAO */
+    font-size: 16px;
+    /* #endif */
 		margin-right: 5px;
 		// opacity: 0.6;
 	}

+ 3 - 3
uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json

@@ -1,15 +1,15 @@
 {
 	"uni-datetime-picker.selectDate": "select date",
 	"uni-datetime-picker.selectTime": "select time",
-	"uni-datetime-picker.selectDateTime": "select datetime",
+	"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.cancel": "cancel",
+	"uni-datetime-picker.year": "-",
 	"uni-datetime-picker.month": "",
 	"uni-calender.MON": "MON",
 	"uni-calender.TUE": "TUE",

+ 16 - 28
uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue

@@ -77,21 +77,14 @@
 				</view>
 			</view>
 		</view>
-		<!-- #ifdef H5 -->
-		<!-- <keypress v-if="visible" @esc="tiggerTimePicker" @enter="setTime" /> -->
-		<!-- #endif -->
 	</view>
 </template>
 
 <script>
-	// #ifdef H5
-	import keypress from './keypress'
-	// #endif
-	import {
-		initVueI18n
-	} from '@dcloudio/uni-i18n'
-	import messages from './i18n/index.js'
-	const {	t	} = initVueI18n(messages)
+	import { initVueI18n } from '@dcloudio/uni-i18n'
+	import i18nMessages from './i18n/index.js'
+	const {	t	} = initVueI18n(i18nMessages)
+  import { fixIosDateFormat } from './util'
 
 	/**
 	 * DatetimePicker 时间选择器
@@ -108,11 +101,6 @@
 
 	export default {
 		name: 'UniDatetimePicker',
-		components: {
-			// #ifdef H5
-			keypress
-			// #endif
-		},
 		data() {
 			return {
 				indicatorStyle: `height: 50px;`,
@@ -187,12 +175,12 @@
 		watch: {
 			// #ifndef VUE3
 			value: {
-				handler(newVal, oldVal) {
-					if (newVal) {
-						this.parseValue(this.fixIosDateFormat(newVal)) //兼容 iOS、safari 日期格式
+				handler(newVal) {
+          if (newVal) {
+            this.parseValue(fixIosDateFormat(newVal))
 						this.initTime(false)
 					} else {
-						this.time = ''
+            this.time = ''
 						this.parseValue(Date.now())
 					}
 				},
@@ -201,9 +189,9 @@
 			// #endif
 			// #ifdef VUE3
 			modelValue: {
-				handler(newVal, oldVal) {
-					if (newVal) {
-						this.parseValue(this.fixIosDateFormat(newVal)) //兼容 iOS、safari 日期格式
+        handler(newVal) {
+          if (newVal) {
+						this.parseValue(fixIosDateFormat(newVal))
 						this.initTime(false)
 					} else {
 						this.time = ''
@@ -233,13 +221,13 @@
 			},
 			start: {
 				handler(newVal) {
-					this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'start') //兼容 iOS、safari 日期格式
+					this.parseDatetimeRange(fixIosDateFormat(newVal), 'start')
 				},
 				immediate: true
 			},
 			end: {
 				handler(newVal) {
-					this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'end') //兼容 iOS、safari 日期格式
+					this.parseDatetimeRange(fixIosDateFormat(newVal), 'end')
 				},
 				immediate: true
 			},
@@ -543,7 +531,7 @@
 					const day = now.getDate()
 					dateBase = year + '/' + month + '/' + day + ' '
 				}
-				if (Number(value) && typeof value !== NaN) {
+				if (Number(value)) {
 					value = parseInt(value)
 					dateBase = 0
 				}
@@ -614,7 +602,7 @@
 						pointType === 'start' ? this.startYear = this.year - 60 : this.endYear = this.year + 60
 						return
 					}
-					if (Number(point) && Number(point) !== NaN) {
+					if (Number(point)) {
 						point = parseInt(point)
 					}
 					// datetime 的 end 没有时分秒, 则不限制
@@ -752,7 +740,7 @@
 			 */
 			initTimePicker() {
 				if (this.disabled) return
-				const value = this.fixIosDateFormat(this.value)
+				const value = fixIosDateFormat(this.time)
 				this.initPickerValue(value)
 				this.visible = !this.visible
 			},

Разлика између датотеке није приказан због своје велике величине
+ 352 - 335
uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue


+ 200 - 207
uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js

@@ -1,27 +1,24 @@
 class Calendar {
 	constructor({
-		date,
 		selected,
 		startDate,
 		endDate,
 		range,
-		// multipleStatus
 	} = {}) {
 		// 当前日期
-		this.date = this.getDate(new Date()) // 当前初入日期
+		this.date = this.getDateObj(new Date()) // 当前初入日期
 		// 打点信息
 		this.selected = selected || [];
-		// 范围开始
+		// 起始时间
 		this.startDate = startDate
-		// 范围结束
+		// 终止时间
 		this.endDate = endDate
+    // 是否范围选择
 		this.range = range
 		// 多选状态
 		this.cleanMultipleStatus()
 		// 每周日期
 		this.weeks = {}
-		// this._getWeek(this.date.fullDate)
-		// this.multipleStatus = multipleStatus
 		this.lastHover = false
 	}
 	/**
@@ -29,8 +26,8 @@ class Calendar {
 	 * @param {Object} date
 	 */
 	setDate(date) {
-		this.selectDate = this.getDate(date)
-		this._getWeek(this.selectDate.fullDate)
+		const selectDate = this.getDateObj(date)
+		this.getWeeks(selectDate.fullDate)
 	}
 
 	/**
@@ -44,93 +41,82 @@ class Calendar {
 		}
 	}
 
-	/**
-	 * 重置开始日期
-	 */
-	resetSatrtDate(startDate) {
-		// 范围开始
+	setStartDate(startDate) {
 		this.startDate = startDate
-
 	}
 
-	/**
-	 * 重置结束日期
-	 */
-	resetEndDate(endDate) {
-		// 范围结束
+	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对象
 	 */
-	getDate(date, AddDayCount = 0, str = 'day') {
-		if (!date) {
-			date = new Date()
-		}
-		if (typeof date !== 'object') {
-			date = date.replace(/-/g, '/')
-		}
-		const dd = new Date(date)
-		switch (str) {
-			case 'day':
-				dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
-				break
-			case 'month':
-				if (dd.getDate() === 31) {
-					dd.setDate(dd.getDate() + AddDayCount)
-				} else {
-					dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
-				}
-				break
-			case 'year':
-				dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
-				break
-		}
-		const y = dd.getFullYear()
-		const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
-		const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
+	getDateObj(date) {
+    date = fixIosDateFormat(date)
+    date = new Date(date)
+
 		return {
-			fullDate: y + '-' + m + '-' + d,
-			year: y,
-			month: m,
-			date: d,
-			day: dd.getDay()
+			fullDate: getDate(date),
+      year: date.getFullYear(),
+      month: addZero(date.getMonth() + 1),
+      date: addZero(date.getDate()),
+      day: date.getDay()
 		}
 	}
 
-
 	/**
-	 * 获取上月剩余天数
+	 * 获取上一个月日期集合
 	 */
-	_getLastMonthDays(firstDay, full) {
-		let dateArr = []
-		for (let i = firstDay; i > 0; i--) {
-			const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
-			dateArr.push({
-				date: beforeDate,
-				month: full.month - 1,
+	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 dateArr
+		return result
 	}
 	/**
-	 * 获取本月天数
+	 * 获取本月日期集合
 	 */
-	_currentMonthDys(dateData, full) {
-		let dateArr = []
-		let fullDate = this.date.fullDate
-		for (let i = 1; i <= dateData; i++) {
-			let isinfo = false
-			let nowDate = full.year + '-' + (full.month < 10 ?
-				full.month : full.month) + '-' + (i < 10 ?
-				'0' + i : i)
-			// 是否今天
-			let isDay = fullDate === nowDate
+	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
 			// 获取打点信息
-			let info = this.selected && this.selected.find((item) => {
-				if (this.dateEqual(nowDate, item.date)) {
+			const info = this.selected && this.selected.find((item) => {
+				if (this.dateEqual(currentDate, item.date)) {
 					return item
 				}
 			})
@@ -139,62 +125,52 @@ class Calendar {
 			let disableBefore = true
 			let disableAfter = true
 			if (this.startDate) {
-				// let dateCompBefore = this.dateCompare(this.startDate, fullDate)
-				// disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
-				disableBefore = this.dateCompare(this.startDate, nowDate)
+				disableBefore = dateCompare(this.startDate, currentDate)
 			}
 
 			if (this.endDate) {
-				// let dateCompAfter = this.dateCompare(fullDate, this.endDate)
-				// disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
-				disableAfter = this.dateCompare(nowDate, this.endDate)
+				disableAfter = dateCompare(currentDate, this.endDate)
 			}
+
 			let multiples = this.multipleStatus.data
-			let checked = false
 			let multiplesStatus = -1
-			if (this.range) {
-				if (multiples) {
-					multiplesStatus = multiples.findIndex((item) => {
-						return this.dateEqual(item, nowDate)
-					})
-				}
-				if (multiplesStatus !== -1) {
-					checked = true
-				}
-			}
-			let data = {
-				fullDate: nowDate,
-				year: full.year,
-				date: i,
-				multiple: this.range ? checked : false,
-				beforeMultiple: this.isLogicBefore(nowDate, this.multipleStatus.before, this.multipleStatus.after),
-				afterMultiple: this.isLogicAfter(nowDate, this.multipleStatus.before, this.multipleStatus.after),
-				month: full.month,
-				disable: !(disableBefore && disableAfter),
-				isDay,
-				userChecked: false
-			}
-			if (info) {
-				data.extraInfo = info
+			if (this.range && multiples) {
+        multiplesStatus = multiples.findIndex((item) => {
+          return this.dateEqual(item, currentDate)
+        })
 			}
+      const checked = multiplesStatus !== -1
 
-			dateArr.push(data)
+			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 dateArr
+		return result
 	}
 	/**
-	 * 获取下月天数
+	 * 获取下一个月日期集合
 	 */
-	_getNextMonthDays(surplus, full) {
-		let dateArr = []
-		for (let i = 1; i < surplus + 1; i++) {
-			dateArr.push({
+	_getNextMonthDays(amount, dateObj) {
+		const result = []
+    const month = dateObj.month + 1
+		for (let i = 1; i <= amount; i++) {
+			result.push({
 				date: i,
-				month: Number(full.month) + 1,
+				month,
 				disable: true
 			})
 		}
-		return dateArr
+		return result
 	}
 
 	/**
@@ -205,59 +181,38 @@ class Calendar {
 		if (!date) {
 			date = new Date()
 		}
-		const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
-		return dateInfo
-	}
 
-	/**
-	 * 比较时间大小
-	 */
-	dateCompare(startDate, endDate) {
-		// 计算截止时间
-		startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
-		// 计算详细项的截止时间
-		endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
-		if (startDate <= endDate) {
-			return true
-		} else {
-			return false
-		}
+		return this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate)
 	}
 
 	/**
 	 * 比较时间是否相等
 	 */
 	dateEqual(before, after) {
-		// 计算截止时间
-		before = new Date(before.replace('-', '/').replace('-', '/'))
-		// 计算详细项的截止时间
-		after = new Date(after.replace('-', '/').replace('-', '/'))
-		if (before.getTime() - after.getTime() === 0) {
-			return true
-		} else {
-			return false
-		}
+		before = new Date(fixIosDateFormat(before))
+		after = new Date(fixIosDateFormat(after))
+		return before.valueOf() === after.valueOf()
 	}
-
+
 	/**
 	 *  比较真实起始日期
 	 */
-
-	isLogicBefore(currentDay, before, after) {
-		let logicBefore = before
-		if (before && after) {
-			logicBefore = this.dateCompare(before, after) ? before : after
-		}
-		return this.dateEqual(logicBefore, currentDay)
+
+	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)
 	}
-
-	isLogicAfter(currentDay, before, after) {
-		let logicAfter = after
-		if (before && after) {
-			logicAfter = this.dateCompare(before, after) ? after : before
-		}
-		return this.dateEqual(logicAfter, currentDay)
-	}
 
 	/**
 	 * 获取日期范围内所有日期
@@ -276,7 +231,7 @@ class Calendar {
 		var unixDe = de.getTime() - 24 * 60 * 60 * 1000
 		for (var k = unixDb; k <= unixDe;) {
 			k = k + 24 * 60 * 60 * 1000
-			arr.push(this.getDate(new Date(parseInt(k))).fullDate)
+			arr.push(this.getDateObj(new Date(parseInt(k))).fullDate)
 		}
 		return arr
 	}
@@ -285,11 +240,12 @@ class Calendar {
 	 *  获取多选状态
 	 */
 	setMultiple(fullDate) {
+    if (!this.range) return
+
 		let {
 			before,
 			after
-		} = this.multipleStatus
-		if (!this.range) return
+		} = this.multipleStatus
 		if (before && after) {
 			if (!this.lastHover) {
 				this.lastHover = true
@@ -302,46 +258,42 @@ class Calendar {
 			this.lastHover = false
 		} else {
 			if (!before) {
-				this.multipleStatus.before = fullDate
+				this.multipleStatus.before = fullDate
 				this.lastHover = false
 			} else {
 				this.multipleStatus.after = fullDate
-				if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+				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._getWeek(fullDate)
+		this.getWeeks(fullDate)
 	}
 
 	/**
 	 *  鼠标 hover 更新多选状态
 	 */
 	setHoverMultiple(fullDate) {
-		let {
-			before,
-			after
-		} = this.multipleStatus
+    if (!this.range || this.lastHover) return
 
-		if (!this.range) return
-		if (this.lastHover) return
+		const { before } = this.multipleStatus
 
 		if (!before) {
 			this.multipleStatus.before = fullDate
 		} else {
 			this.multipleStatus.after = fullDate
-			if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+			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._getWeek(fullDate)
+		this.getWeeks(fullDate)
 	}
 
 	/**
@@ -351,12 +303,12 @@ class Calendar {
 		this.multipleStatus.before = before
 		this.multipleStatus.after = after
 		if (before && after) {
-			if (this.dateCompare(before, after)) {
+			if (dateCompare(before, after)) {
 				this.multipleStatus.data = this.geDateAll(before, after);
-				this._getWeek(after)
+				this.getWeeks(after)
 			} else {
 				this.multipleStatus.data = this.geDateAll(after, before);
-				this._getWeek(before)
+				this.getWeeks(before)
 			}
 		}
 	}
@@ -365,46 +317,87 @@ class Calendar {
 	 * 获取每周数据
 	 * @param {Object} dateData
 	 */
-	_getWeek(dateData) {
+	getWeeks(dateData) {
 		const {
-			fullDate,
 			year,
 			month,
-			date,
-			day
-		} = this.getDate(dateData)
-		let firstDay = new Date(year, month - 1, 1).getDay()
-		let currentDay = new Date(year, month, 0).getDate()
-		let dates = {
-			lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
-			currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
-			nextMonthDays: [], // 下个月开始几天
-			weeks: []
-		}
-		let canlender = []
-		const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
-		dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
-		canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
-		let weeks = {}
-		// 拼接数组  上个月开始几天 + 本月天数+ 下个月开始几天
-		for (let i = 0; i < canlender.length; i++) {
-			if (i % 7 === 0) {
-				weeks[parseInt(i / 7)] = new Array(7)
-			}
-			weeks[parseInt(i / 7)][i % 7] = canlender[i]
+		} = this.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.canlender = canlender
+
+		this.calendar = calendarDays
 		this.weeks = weeks
 	}
+}
 
-	//静态方法
-	// static init(date) {
-	// 	if (!this.instance) {
-	// 		this.instance = new Calendar(date);
-	// 	}
-	// 	return this.instance;
-	// }
+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)
+}
+
+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 default Calendar
+export {Calendar, getDateTime, getDate, getTime, addZero, getDefaultSecond, dateCompare, checkDate, fixIosDateFormat}

+ 1 - 1
uni_modules/uni-datetime-picker/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-datetime-picker",
   "displayName": "uni-datetime-picker 日期选择器",
-  "version": "2.2.11",
+  "version": "2.2.23",
   "description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择",
   "keywords": [
     "uni-datetime-picker",

+ 4 - 0
uni_modules/uni-table/changelog.md

@@ -1,3 +1,7 @@
+## 1.2.3(2023-03-28)
+- 修复 在vue3模式下可能会出现错误的问题
+## 1.2.2(2022-11-29)
+- 优化 主题样式
 ## 1.2.1(2022-06-06)
 - 修复 微信小程序存在无使用组件的问题
 ## 1.2.0(2021-11-19)

+ 3 - 3
uni_modules/uni-table/components/uni-table/uni-table.vue

@@ -3,9 +3,9 @@
 		<!-- #ifdef H5 -->
 		<table class="uni-table" border="0" cellpadding="0" cellspacing="0" :class="{ 'table--stripe': stripe }" :style="{ 'min-width': minWidth + 'px' }">
 			<slot></slot>
-			<view v-if="noData" class="uni-table-loading">
-				<view class="uni-table-text" :class="{ 'empty-border': border }">{{ emptyText }}</view>
-			</view>
+			<tr v-if="noData" class="uni-table-loading">
+				<td class="uni-table-text" :class="{ 'empty-border': border }">{{ emptyText }}</td>
+			</tr>
 			<view v-if="loading" class="uni-table-mask" :class="{ 'empty-border': border }"><div class="uni-table--loader"></div></view>
 		</table>
 		<!-- #endif -->

+ 16 - 8
uni_modules/uni-table/components/uni-th/filter-dropdown.vue

@@ -112,6 +112,12 @@
 						value: 'value'
 					}
 				}
+			},
+			filterDefaultValue: {
+				type: [Array,String],
+				default () {
+					return ""
+				}
 			}
 		},
 		computed: {
@@ -157,7 +163,7 @@
 				enabled: true,
 				isOpened: false,
 				dataList: [],
-				filterValue: '',
+				filterValue: this.filterDefaultValue,
 				checkedValues: [],
 				gtValue: '',
 				ltValue: '',
@@ -286,6 +292,8 @@
 </script>
 
 <style lang="scss">
+	$uni-primary: #1890ff !default;
+	
 	.flex-r {
 		display: flex;
 		flex-direction: row;
@@ -315,8 +323,8 @@
 	}
 
 	.icon-select.active {
-		background-color: #1890ff;
-		border-top-color: #1890ff;
+		background-color: $uni-primary;
+		border-top-color: $uni-primary;
 	}
 
 	.icon-search {
@@ -343,11 +351,11 @@
 	}
 
 	.icon-search.active .icon-search-0 {
-		border-color: #1890ff;
+		border-color: $uni-primary;
 	}
 
 	.icon-search.active .icon-search-1 {
-		background-color: #1890ff;
+		background-color: $uni-primary;
 	}
 
 	.icon-calendar {
@@ -387,14 +395,14 @@
 	}
 
 	.icon-calendar.active {
-		color: #1890ff;
+		color: $uni-primary;
 	}
 
 	.icon-calendar.active .icon-calendar-0,
 	.icon-calendar.active .icon-calendar-1,
 	.icon-calendar.active .icon-calendar-0:before,
 	.icon-calendar.active .icon-calendar-0:after {
-		background-color: #1890ff;
+		background-color: $uni-primary;
 	}
 
 	.uni-filter-dropdown {
@@ -497,7 +505,7 @@
 	}
 
 	.btn-submit {
-		background-color: #1890ff;
+		background-color: $uni-primary;
 		color: #ffffff;
 	}
 </style>

+ 62 - 55
uni_modules/uni-table/components/uni-th/uni-th.vue

@@ -1,6 +1,6 @@
 <template>
 	<!-- #ifdef H5 -->
-	<th :rowspan="rowspan" :colspan="colspan" class="uni-table-th" :class="{ 'table--border': border }" :style="{ width: customWidth + 'px', 'text-align': align }">
+	<th :rowspan="rowspan" :colspan="colspan" class="uni-table-th" :class="{ 'table--border': border }" :style="{ width: customWidth + 'px', 'text-align': align }">
 		<view class="uni-table-th-row">
 			<view class="uni-table-th-content" :style="{ 'justify-content': contentAlign }" @click="sort">
 				<slot></slot>
@@ -8,8 +8,8 @@
 					<text class="arrow up" :class="{ active: ascending }" @click.stop="ascendingFn"></text>
 					<text class="arrow down" :class="{ active: descending }" @click.stop="descendingFn"></text>
 				</view>
-			</view>
-			<dropdown v-if="filterType || filterData.length" :filterData="filterData" :filterType="filterType" @change="ondropdown"></dropdown>
+			</view>
+			<dropdown v-if="filterType || filterData.length" :filterDefaultValue="filterDefaultValue" :filterData="filterData" :filterType="filterType" @change="ondropdown"></dropdown>
 		</view>
 	</th>
 	<!-- #endif -->
@@ -18,35 +18,35 @@
 	<!-- #endif -->
 </template>
 
-<script>
-	// #ifdef H5
-	import dropdown from './filter-dropdown.vue'
-	// #endif
+<script>
+	// #ifdef H5
+	import dropdown from './filter-dropdown.vue'
+	// #endif
 /**
  * Th 表头
  * @description 表格内的表头单元格组件
  * @tutorial https://ext.dcloud.net.cn/plugin?id=3270
- * @property {Number | String} 	width 	单元格宽度(支持纯数字、携带单位px或rpx)
+ * @property {Number | String} 	width 	单元格宽度(支持纯数字、携带单位px或rpx)
  * @property {Boolean} 	sortable 					是否启用排序
  * @property {Number} 	align = [left|center|right]	单元格对齐方式
  * @value left   	单元格文字左侧对齐
  * @value center	单元格文字居中
- * @value right		单元格文字右侧对齐
- * @property {Array}	filterData 筛选数据
- * @property {String}	filterType	[search|select] 筛选类型
+ * @value right		单元格文字右侧对齐
+ * @property {Array}	filterData 筛选数据
+ * @property {String}	filterType	[search|select] 筛选类型
  * @value search	关键字搜素
- * @value select	条件选择
+ * @value select	条件选择
  * @event {Function} sort-change 排序触发事件
  */
 export default {
 	name: 'uniTh',
 	options: {
 		virtualHost: true
-	},
-	components: {
-		// #ifdef H5
-		dropdown
-		// #endif
+	},
+	components: {
+		// #ifdef H5
+		dropdown
+		// #endif
 	},
 	emits:['sort-change','filter-change'],
 	props: {
@@ -79,6 +79,12 @@ export default {
 			default () {
 				return []
 			}
+		},
+		filterDefaultValue: {
+			type: [Array,String],
+			default () {
+				return ""
+			}
 		}
 	},
 	data() {
@@ -88,30 +94,30 @@ export default {
 			descending: false
 		}
 	},
-	computed: {
-		// 根据props中的width属性 自动匹配当前th的宽度(px)
-		customWidth(){
-			if(typeof this.width === 'number'){
-				return this.width
-			} else if(typeof this.width === 'string') {
-				let regexHaveUnitPx = new RegExp(/^[1-9][0-9]*px$/g)
-				let regexHaveUnitRpx = new RegExp(/^[1-9][0-9]*rpx$/g)
-				let regexHaveNotUnit = new RegExp(/^[1-9][0-9]*$/g)
-				if (this.width.match(regexHaveUnitPx) !== null) { // 携带了 px
-					return this.width.replace('px', '')
-				} else if (this.width.match(regexHaveUnitRpx) !== null) { // 携带了 rpx
-					let numberRpx = Number(this.width.replace('rpx', ''))
-					let widthCoe = uni.getSystemInfoSync().screenWidth / 750
-					return Math.round(numberRpx * widthCoe)
-				} else if (this.width.match(regexHaveNotUnit) !== null) { // 未携带 rpx或px 的纯数字 String
-					return this.width
-				} else { // 不符合格式
-					return ''
-				}
-			} else {
-				return ''
-			}
-		},
+	computed: {
+		// 根据props中的width属性 自动匹配当前th的宽度(px)
+		customWidth(){
+			if(typeof this.width === 'number'){
+				return this.width
+			} else if(typeof this.width === 'string') {
+				let regexHaveUnitPx = new RegExp(/^[1-9][0-9]*px$/g)
+				let regexHaveUnitRpx = new RegExp(/^[1-9][0-9]*rpx$/g)
+				let regexHaveNotUnit = new RegExp(/^[1-9][0-9]*$/g)
+				if (this.width.match(regexHaveUnitPx) !== null) { // 携带了 px
+					return this.width.replace('px', '')
+				} else if (this.width.match(regexHaveUnitRpx) !== null) { // 携带了 rpx
+					let numberRpx = Number(this.width.replace('rpx', ''))
+					let widthCoe = uni.getSystemInfoSync().screenWidth / 750
+					return Math.round(numberRpx * widthCoe)
+				} else if (this.width.match(regexHaveNotUnit) !== null) { // 未携带 rpx或px 的纯数字 String
+					return this.width
+				} else { // 不符合格式
+					return ''
+				}
+			} else {
+				return ''
+			}
+		},
 		contentAlign() {
 			let align = 'left'
 			switch (this.align) {
@@ -177,9 +183,9 @@ export default {
 				}
 				return item
 			})
-		},
-		ondropdown(e) {
-			this.$emit("filter-change", e)
+		},
+		ondropdown(e) {
+			this.$emit("filter-change", e)
 		},
 		/**
 		 * 获取父元素实例
@@ -200,6 +206,7 @@ export default {
 
 <style lang="scss">
 $border-color: #ebeef5;
+$uni-primary: #007aff !default;
 
 .uni-table-th {
 	padding: 12px 10px;
@@ -211,13 +218,13 @@ $border-color: #ebeef5;
 	font-weight: bold;
 	color: #909399;
 	border-bottom: 1px $border-color solid;
-}
-
-.uni-table-th-row {
-	/* #ifndef APP-NVUE */
-	display: flex;
-	/* #endif */
-	flex-direction: row;
+}
+
+.uni-table-th-row {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: row;
 }
 
 .table--border {
@@ -225,7 +232,7 @@ $border-color: #ebeef5;
 }
 .uni-table-th-content {
 	display: flex;
-	align-items: center;
+	align-items: center;
 	flex: 1;
 }
 .arrow-box {
@@ -254,7 +261,7 @@ $border-color: #ebeef5;
 	}
 	&.active {
 		::after {
-			background-color: #007aff;
+			background-color: $uni-primary;
 		}
 	}
 }
@@ -271,8 +278,8 @@ $border-color: #ebeef5;
 	}
 	&.active {
 		::after {
-			background-color: #007aff;
+			background-color: $uni-primary;
 		}
 	}
 }
-</style>
+</style>

+ 7 - 7
uni_modules/uni-table/components/uni-tr/table-checkbox.vue

@@ -76,8 +76,8 @@
 	}
 </script>
 
-<style lang="scss">
-	$checked-color: #007aff;
+<style lang="scss">
+	$uni-primary: #007aff !default;
 	$border-color: #DCDFE6;
 	$disable:0.4;
 
@@ -125,8 +125,8 @@
 			}
 
 			&.checkbox--indeterminate {
-				border-color: $checked-color;
-				background-color: $checked-color;
+				border-color: $uni-primary;
+				background-color: $uni-primary;
 
 				.checkbox__inner-icon {
 					position: absolute;
@@ -147,7 +147,7 @@
 				}
 			}
 			&:hover{
-				border-color: $checked-color;
+				border-color: $uni-primary;
 			}
 			// 禁用
 			&.is-disable {
@@ -160,8 +160,8 @@
 
 			// 选中
 			&.is-checked {
-				border-color: $checked-color;
-				background-color: $checked-color;
+				border-color: $uni-primary;
+				background-color: $uni-primary;
 
 				.checkbox__inner-icon {
 					opacity: 1;

+ 4 - 7
uni_modules/uni-table/package.json

@@ -1,7 +1,7 @@
 {
   "id": "uni-table",
   "displayName": "uni-table 表格",
-  "version": "1.2.1",
+  "version": "1.2.3",
   "description": "表格组件,多用于展示多条结构类似的数据,如",
   "keywords": [
     "uni-ui",
@@ -16,11 +16,7 @@
   "directories": {
     "example": "../../temps/example_temps"
   },
-  "dcloudext": {
-    "category": [
-      "前端组件",
-      "通用组件"
-    ],
+"dcloudext": {
     "sale": {
       "regular": {
         "price": "0.00"
@@ -37,7 +33,8 @@
       "data": "无",
       "permissions": "无"
     },
-    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
   },
   "uni_modules": {
     "dependencies": ["uni-scss","uni-datetime-picker"],