@ -0,0 +1,111 @@ |
|||||
|
# uni-templete使用说明 |
||||
|
|
||||
|
## 环境准备 |
||||
|
|
||||
|
+ 使用HbuilderX作为构建开发环境, 主要使用HX的编译环境, 也可以使用vscode编码 + HX编译的搭配 |
||||
|
+ HX需要安装插件 |
||||
|
+ es6编译 |
||||
|
+ Eslint-js |
||||
|
+ Eslint-plugin-vue |
||||
|
+ git |
||||
|
+ prettier |
||||
|
+ **Scss/sass编译** |
||||
|
+ 微信小程序开发工具 |
||||
|
+ appId申请 |
||||
|
|
||||
|
## 目录说明 |
||||
|
|
||||
|
+ **api** |
||||
|
|
||||
|
+ api接口统一管理文件夹,不允许在组件中直接定义api地址,必须在api文件夹下进行统一管理 |
||||
|
+ 不同的模块,分成不同的js文件进行管理 |
||||
|
+ 采用`export const signin = params => http.post('/api/xxx', params);`格式,封装请求方法及请求地址,方便统一管理 |
||||
|
|
||||
|
+ **colorui** colorui样式库引入,如果不需要直接删除,注意删除app.vue里的引用 |
||||
|
|
||||
|
+ **common** 存放公用的css js font等文件,工具类js建议封装到utils文件里 |
||||
|
|
||||
|
+ **components** |
||||
|
|
||||
|
+ 组件存放文件夹 |
||||
|
+ 统一格式 `组件/组件.vue ` 文件夹与组件同名,在页面或组件中引入就不用再`import`和在`components`注册了 |
||||
|
+ 如果是某个组件特用的子组件,确定不公用的情况下,建议封装到 `组件/components`文件夹里 |
||||
|
|
||||
|
+ **config** 配置信息文件,一些复杂对象或复杂数组的配置信息,不要在组件内直接定义,公用的建议提到config文件夹下(分模块管理),确定非公用的直接写到组件的文件夹内部即可 |
||||
|
|
||||
|
+ **pages** 页面存放目录 |
||||
|
|
||||
|
+ **plugins** 插件,request插件是封装的类似axios请求处理插件,跟axios用法一致,**注意返回值**:成功的返回对象是res.data.data,失败的返回值是res.data.msg,可根据后台接口对应修改。请求做了header里的token处理 |
||||
|
|
||||
|
+ **static** 存放静态文件 |
||||
|
|
||||
|
+ **store** vuex文件,注意分模块处理,参考模板中的user,组件中使用store文件时,优先使用mapState等解构方法 |
||||
|
|
||||
|
+ **utils** 公用工具类,注意分模块,如:`ui.js` `time.js` ` query.js`等 |
||||
|
|
||||
|
+ **.eslintrc.js** eslint代码格式检测配置文件 |
||||
|
|
||||
|
+ **.gitignore** 上传git仓库忽略的文件 |
||||
|
|
||||
|
+ **.prettierrc** prettier自动格式化代码风格的插件配置文件 |
||||
|
|
||||
|
+ App.vue 入口文件 |
||||
|
|
||||
|
+ Main.js 入口文件 |
||||
|
|
||||
|
+ **Manifest.json** 项目配置文件 |
||||
|
|
||||
|
+ **package.json** 项目中有使用到npm包,初始时先运行`npm i` |
||||
|
|
||||
|
+ **uni.scss** scss样式遍历定义文件,在组件中可直接使用其变量而不需要导入 |
||||
|
|
||||
|
+ **Vue.config.js** vue配置文件,定义了常用的alias,使用时尽量使用alias的绝对路径代替相对路径,如:`api/user.js`代替`./api/user.js` |
||||
|
|
||||
|
```js |
||||
|
'~': __dirname, |
||||
|
config: resolve('config'), |
||||
|
api: resolve('api'), |
||||
|
store: resolve('store'), |
||||
|
components: resolve('components'), |
||||
|
pages: resolve('pages'), |
||||
|
common: resolve('common'), |
||||
|
plugins: resolve('plugins'), |
||||
|
utils: resolve('utils'), |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
|
||||
|
## scss |
||||
|
|
||||
|
+ 使用scss代替css样式 |
||||
|
+ HX必须要安装`scss插件` |
||||
|
+ 项目开发前应该先定义好uni.scss里的变量,统一引用这里的变量,有利用界面风格统一及后期维护 |
||||
|
|
||||
|
[官方文档uni.scss](https://uniapp.dcloud.io/collocation/uni-scss) |
||||
|
|
||||
|
## 约定 |
||||
|
|
||||
|
+ Package.json里内置了时间处理插件`moment.js`,统一使用`moment.js`进行时间处理 |
||||
|
|
||||
|
+ 使用scss进行样式开发 |
||||
|
|
||||
|
+ 样式变量(颜色,字体大小,间距等)统一定义到`uni.scss`文件里 |
||||
|
|
||||
|
+ 尽量使用alias定义的绝对路径代替相对路径,如:`api/user.js`代替`./api/user.js` |
||||
|
|
||||
|
+ 保持代码风格统一,建议使用vscode + prettier插件,自动格式化代码 |
||||
|
|
||||
|
+ 代码提交前,进行lint检测,不允许有eslint未通过提交的情况 |
||||
|
|
||||
|
+ `components`里的组件统一格式 `组件/组件.vue ` 文件夹与组件同名,在页面或组件中引入就不用再`import`和在`components`注册了 |
||||
|
|
||||
|
+ 页面及组件中分割出来的子组件,确定不公用的情况下,建议封装到 `组件/components`文件夹里 |
||||
|
|
||||
|
+ 一些复杂对象或复杂数组的配置信息,不要在组件内直接定义,公用的建议提到config文件夹下(分模块管理),确定非公用的直接写到组件的文件夹内部即可 |
||||
|
|
||||
|
+ api 参考上文目录说明中的api项 |
||||
|
|
||||
|
+ git提交规范参考前端规范里的代码提交规范 |
||||
|
|
||||
|
https://kdocs.cn/l/saAjmwvzT?f=130 |
||||
|
[文档] 1-前端技术规范-v1.0-20200618.docx |
@ -0,0 +1,5 @@ |
|||||
|
const proxyUrl = '/tall/v1.0'; |
||||
|
import { http } from 'plugins/request/index'; |
||||
|
|
||||
|
// 请求统一使用如下格式
|
||||
|
// export const signin = params => http.post('/api/xxx', params);
|
@ -1,24 +0,0 @@ |
|||||
// 定义过滤器 时间戳转化
|
|
||||
export function formatDate(date, fmt) { |
|
||||
if (/(y+)/.test(fmt)) { |
|
||||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); |
|
||||
} |
|
||||
let o = { |
|
||||
'M+': date.getMonth() + 1, |
|
||||
'd+': date.getDate(), |
|
||||
'h+': date.getHours(), |
|
||||
'm+': date.getMinutes(), |
|
||||
's+': date.getSeconds() |
|
||||
}; |
|
||||
for (let k in o) { |
|
||||
if (new RegExp(`(${k})`).test(fmt)) { |
|
||||
let str = o[k] + ''; |
|
||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str)); |
|
||||
} |
|
||||
} |
|
||||
return fmt; |
|
||||
}; |
|
||||
|
|
||||
function padLeftZero(str) { |
|
||||
return ('00' + str).substr(str.length); |
|
||||
}; |
|
@ -1,34 +0,0 @@ |
|||||
/** |
|
||||
* 显示模态框 |
|
||||
* @param {string} msg |
|
||||
* @param {boolean} showCancel |
|
||||
* @param {string} confirmText |
|
||||
*/ |
|
||||
export const showModal = (msg, showCancel = false, confirmText = '知道了') => |
|
||||
uni.showModal({ |
|
||||
title: '提示', |
|
||||
content: msg, |
|
||||
showCancel, |
|
||||
confirmText, |
|
||||
confirmColor: '#1890ff', |
|
||||
}); |
|
||||
|
|
||||
/** |
|
||||
* 显示toast |
|
||||
* @param {string} msg |
|
||||
*/ |
|
||||
export const showToast = msg => |
|
||||
uni.showToast({ |
|
||||
title: msg, |
|
||||
icon: 'none', |
|
||||
duration: 3000, |
|
||||
}); |
|
||||
|
|
||||
// 显示加载动画
|
|
||||
export const showLoading = (msg = '努力加载中...') => uni.showLoading({ title: msg }); |
|
||||
|
|
||||
// 隐藏加载动画
|
|
||||
export const hideLoading = () => |
|
||||
setTimeout(() => { |
|
||||
uni.hideLoading(); |
|
||||
}, 1000); |
|
@ -1,88 +0,0 @@ |
|||||
@font-face {font-family: "iconfont"; |
|
||||
src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAooAAsAAAAAFQgAAAnYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCFRgqZFJQeATYCJANQCyoABCAFhG0HgWobnBEzo/aLcspA9l8mcGMo9gb0lUEcr9BhQpCSJK7HqIWTDrU0ai135rQs5oP3fGb0CRKyhu0ftp9rggfS63uD5Ada/eogdCKqqwD2ZlHBHV1m9swEwI9zny/tMO+Ok/bGKNSBGvEHUgPCxiaWhgQFYUbzj6f96t+fCg1iXjqwWSZlB2ZsBvG6E9seoJ5h0HHmFST4/WyWc+spmo2Vac96be8R9iNBZjMMkQIIGNzvW31yLkQdOjwUUqTE2Ze9vW+y88GJe0ItE0lEcUsXSWQJhW4lF36G1+/VCeVRDb4PPh0C8KhGE0S3Hv2G4aAhloBe82bPnIwTCKEzcgWO1064q0bswMKRG+UZYLv++eINrYQDEktBbjpoRvdpdEop/1crsqiNkxrMnAQO9wIFNAE0iJeJpY9RDm+ihZc0UHMKqpHgD49S0jDNpYw5bs6a6+a+eWRemLflbuWp5f9ZlpV7zJwx7+30ZrqkUlCN5tagllnHrNcZNIp4sHRm/oNXgYNLDo88PgEFQiIQNlgEKLHcnIcUDqEhDSEUpDmIGNJZEBLMMQgLzHEIAeYMhA3mLEQFmOsQDph7EC6Y+xA5MI8gPDAvIPJg3kD4YN5CBFDuFqCg7akQIAT7PwwhAqAoBzYAOoD2IPwekrFLShSMw0K9twgVOvDwFgEy0U2DXMsoSAqJbpRLigWdqyHWKQq3he3UFwo1RIA6FrvjYF3MkfIg1MxfJYClKCxukMe0qtEFfOoScXGx1tC9sZok+Swrpun8Lm7UJREUrDwfcd7+NJ1MMJR7ke6OFzAhjhflRNKdgy6FLCujS3ETgQ1q3GyNTGfbq/3cHf4lQZWRFJGmyHgggMqwnJZmlcMkTVETL1fRp4MCOfToAZA3B5a9y4adTCe/jgefSKoqwQPg/u/hZ/8WxL3jIqPCqrO9qGe5gg3UiTTfNA6+q1OKPsuGIdzDhhNJB4t1B8PRhacMkBrFkMCjpUvlx583xa1fn9SHHzei69/f72ro/ryZZt0Mb3QhsWtNWMzzxmUu6LTtIXgdzXctHWslW3z+xBNMr9FH9UwspgSL3vjJDF0BoD5dtmQXJWYiUKcXp90MIfQhQupRGHPDMqidH2lwUX0nWGmHbjSLaHRhPb6QPF+caNnUwsGH9Mj7bbnplo3XfFZ/DTIymMqFgxoHGOcFiUQwcI7LAZ8MalxLQoeVb8ibuMympVYDEV+yWJHRthPbiLDMj6PrGkcQwdLgrrrhOcYievRX+ghPvTTxVa1I0FHX8eD44kF2ACJ6ZcXwJn9B/d5nzraZFGlpcTqILnRODFa5cBTpInFnph/h2DP1ZIA34kEC9+PCftifTNowhyj6Tjb3Rz35MwRVxWa41+nHbWDWZZcefDpyrr3LjZYeeDIil1hUN4kfyvHcs37EFpt8VvM9sKquTSkNXzTp21KXYzlcvrjJ10nLm60pU4xtrNT+xcX9+OX3ev1mGtfC+kHu84se37Xpne/qaLn0tlOG54vqwsp4G+cIH/BFfB7Hrk8hFwMUxdW/f7+Fo+fIm3L1YEiUVit8p7UMtNQmp+CPEWShe0dcKnM7Yj2d72DlwL8jEFuJBWnWK4W3Xy3dpeGcOsUR7tkIA/EQuDXwMWe3T34gGuDAL1srsLe2F5zj24OImJQJfvOi/U/8Z/q5VS7hiX04w+B9MxlSyLVnnh820bgWhgROmKA2V4+fEBgCa425+/7+2ScU988fLn6ZP3+5zq3bru8uv8WjKPmW6UOOl4D/GqUkxCLO7XSKSHzTgFNES8CYMQEthPScm0tLAwRuIoAiv3VLANj4dq7t2ouOw3Ger3Du3Jtk7pwPvjyFY0jtpDwMtrHXSqlSKa1YHzEVn82MH88IN3uP4CX4mOojUFqqVHgfKw7SYTQ092Kyskq8mhlSyBXm0Wuz4upcHW+CeeQ8cLOH/kjgnczGSkgraLgR0h9oqIDJOmXWwEBHB0VIxEFYQ5by6VPfMoLavu0TgVD/sd1dWrWFes4cB16glQepJz0tCWzCkMozlTebSN0T0VLRQt7uiY6kqyppF4CzT6yMqjsSBTRfOR6PZly6pmnylPhOv/iIH8BfrHP2EhyRs85FDY1FOA93bFtHCskrjgwHLfsRDSlIu9HQaaWTNYSC3U1uokIH+o28m9WI5Vqn3sgaJNtsMXEg8Yz1QqzRJWvzdWn3UcbvjQiD2+5LHOrMbxsQRu+NR/Gk1zdnNdFvp7z9NYj/I+OtTTwf77m4rouDv5pDYwJ6eCmIUplBOwql8HoCIq07bcDlw+7CnZl4tCVpoGpYwu0hhJcg+hG2F/Lh4KZBYQgdQHKPfzRa6FLoD/YP77fNpj5+xEtk2x8UXGbCLpsytYRdzp4+lV0WhZWeK0xlFTKs1NAIdaVWqEP5s2daBEQgjVCDIhwikFagE90nDf4jhIEz3c6A9YZqr4xAVmoxc+hCnoQbGxsVFUtyJHnrdO7WKZOV6rXarQZj/28fa+OhP60/kG2sh3Cbn6Y16o2zD+hj94sqI/v9saNCKVoqDFCpwOUsqNWLBUE6mYbJMMLiDikdmKpIpThw4lIsTZ/GKUTVIpsucABvy6qaX5f+1H5I77vjQP6X1EK1D86w2Au/mLP9YH9Ebo3UUJ3OfQAg4d67x+DylGpw1/H9vGzXWkfFVh93krm7bu5K+rVnefYRkFI7lFD/2pNaqUZl/7NzxlKdINspSi3JuvRntUA1AKgV8oG1y31dV003AnVZfi/x5D9Ik/fHw/eOkv8hWy83tSAJgQmsFTieXRT1dPo/dTVqfWoSE+P2b47/t6v26bpf2zHup75+0ALAQUIsYYD8VwpoyNAy191JwkV9dfD9ZP+DswzUeHmRzb/Zdck9uhf8V4rm+W9WDqXC7F+ip+QBSQVVgcKhjq4TmwALnzbAxqEj8GhMz3v7FJiPQmgXaMRaCwgSzgJJxAWgSLih68QXwKKSd8AmEQp4jBCtD+lTb/3h8pWhBb1a7lUwVCyLyqXd+wuuJc1+p17+B66hVs3G03DrJwrYxC3qxs1FrLJMWX1Yz4aUSA1MKxgZe5FhMZnYpFuODeXR5UjJ0CLX75XlfsdgqNjjy2Xkx3/BtaQ5Y9Lbjn/gGs5fmRmbFtA/RSk0aV8G1o2bEySt4iOZsvKBJBJtImVIvtIKRsZ8hYZhYYIWs0XFuH1PfgsINt+U5BGKDxGGEwwmi19UXzGH4vL4Hz5++vzF6ZK4B59IyOAzH6oQ74+ZKF8bDxO7um6acdwq+CKFAuM1y7GnjHOjmffU5Mj+ZCccnJfjBCsXNmnX2ZDS8ZBafdqi9G0V/sWDcxUp4DNPCXfTfFyNLqdrNtTjobEuJrBJqBocjQAAAAA=') format('woff2'); /* iOS 4.1- */ |
|
||||
} |
|
||||
|
|
||||
.iconfont { |
|
||||
font-family: "iconfont" !important; |
|
||||
font-size: 26px; |
|
||||
font-style: normal; |
|
||||
-webkit-font-smoothing: antialiased; |
|
||||
-moz-osx-font-smoothing: grayscale; |
|
||||
} |
|
||||
|
|
||||
.icon-border:before { |
|
||||
content: "\e7a9"; |
|
||||
} |
|
||||
|
|
||||
.icon-timer:before { |
|
||||
content: "\e668"; |
|
||||
} |
|
||||
|
|
||||
.icon-history:before { |
|
||||
content: "\e60d"; |
|
||||
} |
|
||||
|
|
||||
.icon-room:before { |
|
||||
content: "\e600"; |
|
||||
} |
|
||||
|
|
||||
.icon-check-square:before { |
|
||||
content: "\e7a8"; |
|
||||
} |
|
||||
|
|
||||
.icon-user:before { |
|
||||
content: "\e7ae"; |
|
||||
} |
|
||||
|
|
||||
.icon-linechart:before { |
|
||||
content: "\e7af"; |
|
||||
} |
|
||||
|
|
||||
.icon-home:before { |
|
||||
content: "\e7c6"; |
|
||||
} |
|
||||
|
|
||||
.icon-carryout:before { |
|
||||
content: "\e7d3"; |
|
||||
} |
|
||||
|
|
||||
.icon-car:before { |
|
||||
content: "\e7d7"; |
|
||||
} |
|
||||
|
|
||||
.icon-right:before { |
|
||||
content: "\e7eb"; |
|
||||
} |
|
||||
|
|
||||
.icon-left:before { |
|
||||
content: "\e7ec"; |
|
||||
} |
|
||||
|
|
||||
.icon-flag-fill:before { |
|
||||
content: "\e863"; |
|
||||
} |
|
||||
|
|
||||
.icon-plus:before { |
|
||||
content: "\e8fe"; |
|
||||
} |
|
||||
|
|
||||
.icon-wenduji_thermometer:before { |
|
||||
content: "\e611"; |
|
||||
} |
|
||||
|
|
||||
.icon-calendar:before { |
|
||||
content: "\e7d3"; |
|
||||
} |
|
||||
|
|
||||
.icon-scan:before { |
|
||||
content: "\e7d4"; |
|
||||
} |
|
||||
|
|
||||
.icon-qrcode:before { |
|
||||
content: "\e7dd"; |
|
||||
} |
|
||||
|
|
||||
.icon-check-circle-fill:before { |
|
||||
content: "\e844"; |
|
||||
} |
|
||||
|
|
@ -1,105 +0,0 @@ |
|||||
<template> |
|
||||
<view class="mask" v-if="show"> |
|
||||
<view class="content shadow"> |
|
||||
<view class="text-black text-bold text-lg margin-bottom-lg">健康码小程序</view> |
|
||||
<view class="text-df text-gray">为了您的正常使用</view> |
|
||||
<view class="text-df text-gray margin-bottom-lg">小程序需要获得您的基本公开信息</view> |
|
||||
|
|
||||
<button |
|
||||
@tap="getuserinfo" |
|
||||
class="text-purple" |
|
||||
open-type="getUserInfo" |
|
||||
plain |
|
||||
style="border: none;" |
|
||||
>极速登录</button> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapActions, mapState } from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { show: false }; |
|
||||
}, |
|
||||
computed: { |
|
||||
...mapState('user', ['user']), |
|
||||
}, |
|
||||
|
|
||||
watch: { |
|
||||
// 登录以后 如果没有微信信息 |
|
||||
// 就显示本组件 |
|
||||
user(value) { |
|
||||
if (value) { |
|
||||
if (!value.wxInfo || !value.wxInfo.nickname) { |
|
||||
this.show = true; |
|
||||
} else { |
|
||||
this.show = false; |
|
||||
} |
|
||||
} else { |
|
||||
this.show = false; |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
...mapActions('user', ['updateUserInfo']), |
|
||||
|
|
||||
// 获取用户信息 |
|
||||
getuserinfo() { |
|
||||
this.show = false; |
|
||||
uni.getUserInfo({ |
|
||||
provider: 'weixin', |
|
||||
success: infoRes => { |
|
||||
const { |
|
||||
nickName, |
|
||||
avatarUrl, |
|
||||
city, |
|
||||
country, |
|
||||
gender, |
|
||||
language, |
|
||||
province, |
|
||||
} = infoRes.userInfo; |
|
||||
const params = { |
|
||||
nickname: nickName, |
|
||||
headImgUrl: avatarUrl, |
|
||||
city, |
|
||||
country, |
|
||||
sex: gender, |
|
||||
language, |
|
||||
province, |
|
||||
}; |
|
||||
this.updateUserInfo(params); |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style scoped> |
|
||||
.mask { |
|
||||
z-index: 9998; |
|
||||
position: fixed; |
|
||||
left: 0; |
|
||||
top: 0; |
|
||||
bottom: 0; |
|
||||
right: 0; |
|
||||
background: rgba(0, 0, 0, 0.2); |
|
||||
} |
|
||||
.content { |
|
||||
z-index: 9999; |
|
||||
position: absolute; |
|
||||
left: 50upx; |
|
||||
top: 50%; |
|
||||
box-sizing: border-box; |
|
||||
width: 650upx; |
|
||||
padding: 20px; |
|
||||
font-size: 14px; |
|
||||
transform: translate3d(0, -50%, 0); |
|
||||
background: #fff; |
|
||||
border-radius: 20upx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
</style> |
|
@ -1,45 +0,0 @@ |
|||||
<template> |
|
||||
<map |
|
||||
:latitude="latitude" |
|
||||
:longitude="longitude" |
|
||||
:markers="markers" |
|
||||
:polygons="polygons" |
|
||||
:polyline="polyline" |
|
||||
id="map" |
|
||||
ref="map" |
|
||||
scale="17" |
|
||||
show-location="true" |
|
||||
style="width: 100%; min-height: 1000rpx;height:100%" |
|
||||
/> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
props: { |
|
||||
markers: { type: Array, default: () => [] }, |
|
||||
polyline: { type: Array, default: () => [] }, |
|
||||
polygons: { type: Array, default: () => [] }, |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
latitude: 37.87059, |
|
||||
longitude: 112.55067, |
|
||||
}; |
|
||||
}, |
|
||||
watch: { |
|
||||
markers: { |
|
||||
deep: true, |
|
||||
handler(value) { |
|
||||
if (value && value.length) { |
|
||||
const { latitude, longitude } = value[0]; |
|
||||
this.latitude = latitude; |
|
||||
this.longitude = longitude; |
|
||||
} else { |
|
||||
this.latitude = 37.87059; |
|
||||
this.longitude = 112.55067; |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
@ -1,42 +0,0 @@ |
|||||
<template> |
|
||||
<view class="cu-bar tabbar bg-white" style="width: 750rpx"> |
|
||||
<view |
|
||||
:class="[index === 0 ? 'text-blue': 'text-gray']" |
|
||||
@tap="handleClickButton(0)" |
|
||||
class="action" |
|
||||
hover-class="cc-active" |
|
||||
> |
|
||||
<view class="cuIcon-home"></view>首页 |
|
||||
</view> |
|
||||
<view @tap="$emit('scan')" class="action text-gray add-action"> |
|
||||
<button class="cu-btn cuIcon-scan bg-blue shadow"></button> |
|
||||
扫一扫 |
|
||||
</view> |
|
||||
<view |
|
||||
:class="[index === 1 ? 'text-blue': 'text-gray']" |
|
||||
@tap="handleClickButton(1)" |
|
||||
class="action" |
|
||||
hover-class="cc-active" |
|
||||
> |
|
||||
<view class="cuIcon-my"> |
|
||||
<!-- <view class="cu-tag badge"></view> --> |
|
||||
</view>我的 |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
index: 0, |
|
||||
}; |
|
||||
}, |
|
||||
methods: { |
|
||||
handleClickButton(i) { |
|
||||
this.index = i; |
|
||||
this.$emit('change', i); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
@ -1,167 +0,0 @@ |
|||||
const GetDate = { |
|
||||
withData: (num) => { |
|
||||
let param = parseInt(num); |
|
||||
return param < 10 ? '0' + param : '' + param; |
|
||||
}, |
|
||||
getTimes(str){ |
|
||||
return new Date(str.replace(/-/g,'/')).getTime(); |
|
||||
}, |
|
||||
getCurrentTimes(){ |
|
||||
const date = new Date(); |
|
||||
const year = date.getFullYear(); |
|
||||
const month = date.getMonth() + 1; |
|
||||
const day = date.getDate(); |
|
||||
const hour = date.getHours(); |
|
||||
const minute = date.getMinutes(); |
|
||||
const second = date.getSeconds(); |
|
||||
return { |
|
||||
detail: { |
|
||||
year: year, |
|
||||
month: month, |
|
||||
day: day, |
|
||||
hour: hour, |
|
||||
minute: minute, |
|
||||
second: second |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
format(arr){ |
|
||||
let curarr = []; |
|
||||
let curarr0 = []; |
|
||||
let str = ''; |
|
||||
arr.forEach((cur,index) => { |
|
||||
let o = GetDate.withData(cur); |
|
||||
if(index > 2){ |
|
||||
curarr.push(o); |
|
||||
}else{ |
|
||||
curarr0.push(o); |
|
||||
} |
|
||||
}) |
|
||||
if(arr.length < 4){ |
|
||||
str = curarr0.join('-'); |
|
||||
}else{ |
|
||||
str = curarr0.join('-') + ' ' + curarr.join(':'); |
|
||||
} |
|
||||
return str; |
|
||||
}, |
|
||||
getCurrentStringValue(str){ |
|
||||
let newstr = str.split(' '); |
|
||||
if(newstr && newstr[1]){ |
|
||||
let arr = [...newstr[0].split('-'),...newstr[1].split(':')]; |
|
||||
return arr; |
|
||||
} |
|
||||
return newstr[0].split('-'); |
|
||||
}, |
|
||||
getCompare(curp,startp,endp,timesp){ |
|
||||
let cur = GetDate.getTimes(curp); |
|
||||
let start = GetDate.getTimes(startp); |
|
||||
let end = GetDate.getTimes(endp); |
|
||||
if(cur < start){ |
|
||||
return GetDate.getTimeIndex(timesp,GetDate.getCurrentStringValue(startp)); |
|
||||
}else if(cur > end){ |
|
||||
return GetDate.getTimeIndex(timesp,GetDate.getCurrentStringValue(endp)); |
|
||||
}else{ |
|
||||
return GetDate.getTimeIndex(timesp,GetDate.getCurrentStringValue(curp)); |
|
||||
} |
|
||||
}, |
|
||||
getChooseArr(times,indexs){ |
|
||||
let arr = []; |
|
||||
times.forEach((cur,index) => arr.push(cur[indexs[index]])); |
|
||||
return arr; |
|
||||
}, |
|
||||
getNewArray(arr){ |
|
||||
let newarr = []; |
|
||||
arr.forEach(cur => newarr.push(cur)); |
|
||||
return newarr; |
|
||||
}, |
|
||||
getLoopArray: (start, end) => { |
|
||||
var start = start || 0; |
|
||||
var end = end || 1; |
|
||||
var array = []; |
|
||||
for (var i = start; i <= end; i++) { |
|
||||
array.push(GetDate.withData(i)); |
|
||||
} |
|
||||
return array; |
|
||||
}, |
|
||||
getMonthDay: (year, month) => { |
|
||||
var flag = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0), array = null; |
|
||||
|
|
||||
switch (month) { |
|
||||
case '01': |
|
||||
case '03': |
|
||||
case '05': |
|
||||
case '07': |
|
||||
case '08': |
|
||||
case '10': |
|
||||
case '12': |
|
||||
array = GetDate.getLoopArray(1, 31) |
|
||||
break; |
|
||||
case '04': |
|
||||
case '06': |
|
||||
case '09': |
|
||||
case '11': |
|
||||
array = GetDate.getLoopArray(1, 30) |
|
||||
break; |
|
||||
case '02': |
|
||||
array = flag ? GetDate.getLoopArray(1, 29) : GetDate.getLoopArray(1, 28) |
|
||||
break; |
|
||||
default: |
|
||||
array = '月份格式不正确,请重新输入!' |
|
||||
} |
|
||||
return array; |
|
||||
}, |
|
||||
getDateTimes: (opts) => { |
|
||||
var years = GetDate.getLoopArray(opts.start, opts.end); |
|
||||
var months = GetDate.getLoopArray(1, 12); |
|
||||
var days = GetDate.getMonthDay(opts.curyear, opts.curmonth); |
|
||||
var hours = GetDate.getLoopArray(0, 23); |
|
||||
var minutes = GetDate.getLoopArray(0, 59); |
|
||||
var seconds = GetDate.getLoopArray(0, 59); |
|
||||
var times = null; |
|
||||
|
|
||||
switch (opts.fields) { |
|
||||
case 'year': |
|
||||
times = [years] |
|
||||
break; |
|
||||
case 'month': |
|
||||
times = [years, months] |
|
||||
break; |
|
||||
case 'day': |
|
||||
times = [years, months, days] |
|
||||
break; |
|
||||
case 'hour': |
|
||||
times = [years, months, days, hours] |
|
||||
break; |
|
||||
case 'minute': |
|
||||
times = [years, months, days, hours, minutes] |
|
||||
break; |
|
||||
case 'second': |
|
||||
times = [years, months, days, hours, minutes, seconds] |
|
||||
break; |
|
||||
default: |
|
||||
times = [years, months, days, hours, minutes, seconds] |
|
||||
} |
|
||||
return times; |
|
||||
}, |
|
||||
getIndex(arr,target){ |
|
||||
let len = arr.length; |
|
||||
for(let i = 0; i < len; i++){ |
|
||||
if(arr[i] == target){ |
|
||||
return i; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
getTimeIndex(arrs, targets){ |
|
||||
let len = arrs.length; |
|
||||
let arr = []; |
|
||||
for(let i = 0; i < len; i++){ |
|
||||
arr.push(GetDate.getIndex(arrs[i], targets[i])) |
|
||||
} |
|
||||
return arr; |
|
||||
}, |
|
||||
error(str){ |
|
||||
console.error(str); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
module.exports = GetDate; |
|
@ -1,221 +0,0 @@ |
|||||
<template> |
|
||||
<picker class='rui-picker rui-class' mode="multiSelector" :range="times" :value="timesIndex" :disabled="curDisabled" @change='changeDate' @cancel="cancelDate" @columnchange="columnchangeDate"> |
|
||||
{{curValue}} |
|
||||
</picker> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import GetDate from './GetDate.js'; |
|
||||
export default { |
|
||||
name: 'rattenking-dtpicker', |
|
||||
props: { |
|
||||
/** |
|
||||
* picker允许选中的最小值 |
|
||||
*/ |
|
||||
start: { |
|
||||
type: String, |
|
||||
default: '1900-00-00 00:00:00' |
|
||||
}, |
|
||||
/** |
|
||||
* picker允许选中的最大值 |
|
||||
*/ |
|
||||
end: { |
|
||||
type: String, |
|
||||
default: '2500-12-30 23:59:59' |
|
||||
}, |
|
||||
/** |
|
||||
* picker默认展示的值 |
|
||||
*/ |
|
||||
value: { |
|
||||
type: String, |
|
||||
default: '' |
|
||||
}, |
|
||||
/** |
|
||||
* picker的时间粒度 |
|
||||
*/ |
|
||||
fields: { |
|
||||
type: String, |
|
||||
default: 'second' |
|
||||
}, |
|
||||
/** |
|
||||
* picker是否禁止 |
|
||||
*/ |
|
||||
disabled: { |
|
||||
type: Boolean, |
|
||||
default: false |
|
||||
} |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
times:[['2019','2020'],['01','02']], |
|
||||
timesIndex: [1,1], |
|
||||
timesString: null, |
|
||||
curValue: this.value, |
|
||||
curDisabled: this.disabled, |
|
||||
cancel: null |
|
||||
} |
|
||||
}, |
|
||||
watch: { |
|
||||
value(val) { |
|
||||
this.curValue = val; |
|
||||
}, |
|
||||
disabled(val){ |
|
||||
this.curDisabled = val; |
|
||||
}, |
|
||||
curDisabled(val){ |
|
||||
this.curDisabled = val; |
|
||||
}, |
|
||||
curValue(val) { |
|
||||
this.curValue = val; |
|
||||
this.$emit('change', val); |
|
||||
}, |
|
||||
times(val){ |
|
||||
this.times = val; |
|
||||
}, |
|
||||
timesIndex(val){ |
|
||||
this.timesIndex = val; |
|
||||
}, |
|
||||
cancel(val) { |
|
||||
this.$emit('cancel', val); |
|
||||
} |
|
||||
}, |
|
||||
created() { |
|
||||
if(this.value === ''){ |
|
||||
let time = GetDate.getCurrentTimes(); |
|
||||
let arr = []; |
|
||||
for (let key in time.detail) { |
|
||||
arr.push(time.detail[key]); |
|
||||
if(key === this.fields){ |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
this.value = GetDate.format(arr); |
|
||||
this.curValue = GetDate.format(arr); |
|
||||
} |
|
||||
switch (this.fields){ |
|
||||
case 'year': |
|
||||
if (this.value.length !== 4) {GetDate.error('时间粒度和时间格式不一致');this.curDisabled = true;return false;} |
|
||||
if (this.start.length !== 4) { GetDate.error('时间粒度和开始时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.end.length !== 4) { GetDate.error('时间粒度和结束时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
break; |
|
||||
case 'month': |
|
||||
if (this.value.length !== 7) { GetDate.error('时间粒度和时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.start.length !== 7) { GetDate.error('时间粒度和开始时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.end.length !== 7) { GetDate.error('时间粒度和结束时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
break; |
|
||||
case 'day': |
|
||||
if (this.value.length !== 10) { GetDate.error('时间粒度和时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.start.length !== 10) { GetDate.error('时间粒度和开始时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.end.length !== 10) { GetDate.error('时间粒度和结束时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
break; |
|
||||
case 'hour': |
|
||||
if (this.value.length !== 13) { GetDate.error('时间粒度和时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.start.length !== 13) { GetDate.error('时间粒度和开始时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.end.length !== 13) { GetDate.error('时间粒度和结束时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
break; |
|
||||
case 'minute': |
|
||||
if (this.value.length !== 16) { GetDate.error('时间粒度和时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.start.length !== 16) { GetDate.error('时间粒度和开始时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.end.length !== 16) { GetDate.error('时间粒度和结束时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
break; |
|
||||
case 'second': |
|
||||
if (this.value.length !== 19) { GetDate.error('时间粒度和时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.start.length !== 19) { GetDate.error('时间粒度和开始时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
if (this.end.length !== 19) { GetDate.error('时间粒度和结束时间格式不一致'); this.curDisabled = true; return false;} |
|
||||
break; |
|
||||
default: |
|
||||
GetDate.error('时间粒度不存在') |
|
||||
break; |
|
||||
} |
|
||||
let values = this.value.split(' '); |
|
||||
let targets = GetDate.getCurrentStringValue(this.value); |
|
||||
|
|
||||
if (GetDate.getTimes(this.value) < GetDate.getTimes(this.start)){ |
|
||||
GetDate.error('默认时间不能小于开始时间') |
|
||||
this.curDisabled = true |
|
||||
return false; |
|
||||
} |
|
||||
if (GetDate.getTimes(this.value) > GetDate.getTimes(this.end)) { |
|
||||
GetDate.error('默认时间不能大于开始时间') |
|
||||
this.curDisabled = true |
|
||||
return false; |
|
||||
} |
|
||||
let times = GetDate.getDateTimes({ |
|
||||
start: this.start.substring(0, 4), |
|
||||
end: this.end.substring(0, 4), |
|
||||
curyear: this.value.substring(0, 4), |
|
||||
curmonth: this.value.substring(5, 7), |
|
||||
fields: this.fields |
|
||||
}) |
|
||||
let timesIndex = GetDate.getTimeIndex(times, targets); |
|
||||
let timesString = []; |
|
||||
timesIndex.forEach(o => timesString.push(o)); |
|
||||
|
|
||||
this.times = times; |
|
||||
this.timesIndex = timesIndex; |
|
||||
this.timesString = timesString; |
|
||||
}, |
|
||||
methods: { |
|
||||
changeDate(e){ |
|
||||
let values = e.detail.value; |
|
||||
let times = this.times; |
|
||||
let curarr = []; |
|
||||
for (let i = 0, len = values.length; i < len; i++) { |
|
||||
curarr.push(times[i][values[i]]) |
|
||||
} |
|
||||
let str = GetDate.format(curarr); |
|
||||
this.curValue = str; |
|
||||
}, |
|
||||
columnchangeDate(e){ |
|
||||
// 如果是年和月粒度,那么只需要改变时间格式的index,否则需要判断当月天数 |
|
||||
if ((this.fields === 'year' || this.fields === 'month')){ |
|
||||
let timesIndex = GetDate.getNewArray(this.timesIndex); |
|
||||
timesIndex[e.detail.column] = e.detail.value; |
|
||||
// let arr = GetDate.getCompare(GetDate.format(GetDate.getChooseArr(this.times,timesIndex)),this.start,this.end,this.times); |
|
||||
// console.log(arr) |
|
||||
this.timesIndex = timesIndex; |
|
||||
return false; |
|
||||
}else{ |
|
||||
// 如果改变的是年和月,重新获取天数,同时判断天数的index是否大于当前天数,大于就设置为当月最后一天,否则不变。 |
|
||||
if(e.detail.column === 0 || e.detail.column === 1){ |
|
||||
let times = GetDate.getNewArray(this.times); |
|
||||
let timesIndex = GetDate.getNewArray(this.timesIndex); |
|
||||
timesIndex[e.detail.column] = e.detail.value; |
|
||||
let days = GetDate.getMonthDay(times[0][timesIndex[0]], times[1][timesIndex[1]]); |
|
||||
times[2] = days; |
|
||||
if(timesIndex[2] > days.length - 1){ |
|
||||
timesIndex[2] = days.length - 1; |
|
||||
} |
|
||||
this.times = times; |
|
||||
// let arr = GetDate.getCompare(GetDate.format(GetDate.getChooseArr(this.times,timesIndex)),this.start,this.end,this.times); |
|
||||
this.timesIndex = timesIndex; |
|
||||
}else{ |
|
||||
let timesIndex = GetDate.getNewArray(this.timesIndex); |
|
||||
timesIndex[e.detail.column] = e.detail.value; |
|
||||
// let arr = GetDate.getCompare(GetDate.format(GetDate.getChooseArr(this.times,timesIndex)),this.start,this.end,this.times); |
|
||||
// console.log(arr) |
|
||||
this.timesIndex = timesIndex; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
cancelDate(e){ |
|
||||
this.cancel = e |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style> |
|
||||
.rui-picker{ |
|
||||
height: 10vw; |
|
||||
font-size: 4vw; |
|
||||
color: #000; |
|
||||
display: -webkit-flex; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
padding: 0 10px; |
|
||||
box-sizing: border-box; |
|
||||
border: 1px solid #aaa; |
|
||||
border-radius: 3px; |
|
||||
} |
|
||||
</style> |
|
@ -1,69 +0,0 @@ |
|||||
### DatePicker 多粒度时间选择器 |
|
||||
|
|
||||
可进行多粒度的时间选择器,组件名:``rattenking-dtpicker``,代码块: ruiDatePicker。 |
|
||||
|
|
||||
**使用方式:** |
|
||||
|
|
||||
在 ``script`` 中引用组件 |
|
||||
|
|
||||
```javascript |
|
||||
import ruiDatePicker from '@/components/rattenking-dtpicker/rattenking-dtpicker.vue'; |
|
||||
export default { |
|
||||
components: {ruiDatePicker} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
在 ``template`` 中使用组件 |
|
||||
|
|
||||
```html |
|
||||
<ruiDatePicker |
|
||||
fields="second" |
|
||||
start="2010-00-00 00:00:00" |
|
||||
end="2030-12-30 23:59:59" |
|
||||
:value="value" |
|
||||
@change="bindChange" |
|
||||
@cancel="bindCancel" |
|
||||
></ruiDatePicker> |
|
||||
``` |
|
||||
|
|
||||
实际效果参考:[https://github.com/Rattenking/rui-uni-components](https://github.com/Rattenking/rui-uni-components) |
|
||||
|
|
||||
**DatePicker 属性说明:** |
|
||||
|
|
||||
|属性名 |类型 |默认值 |说明 | |
|
||||
|--- |---- |--- |--- | |
|
||||
|start |String |'1900-00-00 00:00:00' |限制选择器选择的最小时间 | |
|
||||
|end |String |'2500-12-30 23:59:59' |限制选择器选择的最大时间 | |
|
||||
|value |String |'' |当前时间选择器显示的时间 | |
|
||||
|fields |String |'second' |时间选择器的粒度 | |
|
||||
|disabled |Boolean|false |是否为禁用状态 | |
|
||||
|
|
||||
|
|
||||
**fields 值说明:** |
|
||||
|
|
||||
|值 |类型 |说明 | |
|
||||
|--- |---- |--- | |
|
||||
|year |String |选择器粒度为年 | |
|
||||
|month |String |选择器粒度为月份 | |
|
||||
|day |String |选择器粒度为天 | |
|
||||
|hour |String |选择器粒度为小时 | |
|
||||
|minute |String |选择器粒度为分钟 | |
|
||||
|second |String |选择器粒度为秒 | |
|
||||
|
|
||||
**事件说明:** |
|
||||
|
|
||||
|事件名称 |说明 | |
|
||||
|---|---| |
|
||||
|change |时间选择器点击【确定】按钮时时触发的事件,参数为picker的当前的 value| |
|
||||
|cancel |时间选择器点击【取消】按钮时时触发的事件| |
|
||||
|
|
||||
**修复BUG说明:** |
|
||||
|
|
||||
1. 修复每个月都是 31 天的 bug ! |
|
||||
2. 修复 value 值做出改变,在外部赋值才改变的 bug ,当前版本只要 value 改变,显示值就会改变! |
|
||||
3. 优化了默认显示值问题,如果用户不填写,直接默认当前设备的当前时间! |
|
||||
4. 修复二月份能够选择 31 号的 bug! |
|
||||
|
|
||||
**感谢:** |
|
||||
|
|
||||
> 在这里特别感谢**AimerQAQ**、**icare**、**281245387@qq.com**、**椰子皮**等反馈的 bug 和给出的优化建议。有更多优化建议和需求,请联系作者。谢谢! |
|
@ -1,102 +0,0 @@ |
|||||
<template> |
|
||||
<map |
|
||||
:latitude="latitude" |
|
||||
:longitude="longitude" |
|
||||
:markers="covers" |
|
||||
:polygons="polygons" |
|
||||
:polyline="polyline" |
|
||||
id="map" |
|
||||
ref="map" |
|
||||
show-location="true" |
|
||||
include-points="true" |
|
||||
style="width: 100%; height: 1000rpx;" |
|
||||
/> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
latitude: 37.87059, |
|
||||
longitude: 112.55067, |
|
||||
covers: [ |
|
||||
{ |
|
||||
latitude: 37.87059, |
|
||||
longitude: 112.55067, |
|
||||
iconPath: '../../static/location.png', |
|
||||
callout: { |
|
||||
content: 'test', |
|
||||
color: '#fff', |
|
||||
padding: 4, |
|
||||
bgColor: '#0A97C6', |
|
||||
borderRadius: 2, |
|
||||
textAlign: 'center', |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
latitude: 37.87, |
|
||||
longitude: 112.5506, |
|
||||
iconPath: '../../static/location.png', |
|
||||
}, |
|
||||
{ |
|
||||
latitude: 37.8701, |
|
||||
longitude: 112.55, |
|
||||
iconPath: '../../static/location.png', |
|
||||
}, |
|
||||
{ |
|
||||
latitude: 37.86, |
|
||||
longitude: 112.5496, |
|
||||
iconPath: '../../static/location.png', |
|
||||
}, |
|
||||
], |
|
||||
polyline: [ |
|
||||
{ |
|
||||
points: [ |
|
||||
{ latitude: 37.87059, longitude: 112.55067 }, |
|
||||
{ latitude: 37.87, longitude: 112.5506 }, |
|
||||
{ latitude: 37.8701, longitude: 112.55 }, |
|
||||
{ latitude: 37.86, longitude: 112.5496 }, |
|
||||
], |
|
||||
arrowLine: true, |
|
||||
dottedLine: true, |
|
||||
borderColor: '#cccccc', |
|
||||
}, |
|
||||
], |
|
||||
polygons: [ |
|
||||
{ |
|
||||
points: [ |
|
||||
{ latitude: 37.87059, longitude: 112.55067 }, |
|
||||
{ latitude: 37.87, longitude: 112.5506 }, |
|
||||
{ latitude: 37.8701, longitude: 112.55 }, |
|
||||
{ latitude: 37.86, longitude: 112.5496 }, |
|
||||
], |
|
||||
strokeWidth: 0, |
|
||||
strokeColor: '#00000000', |
|
||||
fillColor: '#cce6ff88', |
|
||||
zIndex: 0, |
|
||||
}, |
|
||||
], |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
onLoad() { |
|
||||
this.getLocation(); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
// 获取当前的地址位置 |
|
||||
// 注意用国测局的数据 map只支持gcj02 |
|
||||
getLocation() { |
|
||||
uni.getLocation({ |
|
||||
type: 'gcj02', |
|
||||
success: res => { |
|
||||
this.longitude = res.longitude; |
|
||||
this.latitude = res.latitude; |
|
||||
console.log('当前位置的经度:' + res.longitude); |
|
||||
console.log('当前位置的纬度:' + res.latitude); |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
@ -0,0 +1,19 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
test组件 |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
|
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
|
||||
|
</style> |
@ -1,44 +0,0 @@ |
|||||
<template> |
|
||||
<view> |
|
||||
<view class="cu-timeline"> |
|
||||
<!-- <view class="cu-time">昨天</view> --> |
|
||||
<view :key="index" class="cu-item cur" v-for="(item, index) in userSigns"> |
|
||||
<view class="content bg-green shadow-blur"> |
|
||||
<text>{{ generateTime(item.time - 0) }}</text> |
|
||||
【 {{ item.siteName }} 】打卡 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState } from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return {}; |
|
||||
}, |
|
||||
|
|
||||
computed: mapState('statistics', ['userSigns']), |
|
||||
|
|
||||
methods: { |
|
||||
/** |
|
||||
* 格式化时间为文本 |
|
||||
* @param {number} time ms数 |
|
||||
*/ |
|
||||
generateTime(time) { |
|
||||
let type = 'YYYY-MM-DD HH:mm'; |
|
||||
if (this.$moment().isSame(time, 'day')) { |
|
||||
return `今天 ${this.$moment(time).format('HH:mm')}`; |
|
||||
} |
|
||||
|
|
||||
if (this.$moment().isSame(time, 'year')) { |
|
||||
type = 'MM-DD HH:mm'; |
|
||||
} |
|
||||
|
|
||||
return this.$moment(time).format(type); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
@ -1,546 +0,0 @@ |
|||||
/** |
|
||||
* @1900-2100区间内的公历、农历互转 |
|
||||
* @charset UTF-8 |
|
||||
* @github https://github.com/jjonline/calendar.js
|
|
||||
* @Author Jea杨(JJonline@JJonline.Cn) |
|
||||
* @Time 2014-7-21 |
|
||||
* @Time 2016-8-13 Fixed 2033hex、Attribution Annals |
|
||||
* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug |
|
||||
* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year |
|
||||
* @Version 1.0.3 |
|
||||
* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
|
|
||||
* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
|
|
||||
*/ |
|
||||
/* eslint-disable */ |
|
||||
var calendar = { |
|
||||
|
|
||||
/** |
|
||||
* 农历1900-2100的润大小信息表 |
|
||||
* @Array Of Property |
|
||||
* @return Hex |
|
||||
*/ |
|
||||
lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
|
|
||||
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
|
|
||||
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
|
|
||||
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
|
|
||||
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
|
|
||||
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
|
|
||||
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
|
|
||||
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
|
|
||||
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
|
|
||||
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
|
|
||||
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
|
|
||||
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
|
|
||||
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
|
|
||||
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
|
|
||||
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
|
|
||||
/** Add By JJonline@JJonline.Cn**/ |
|
||||
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
|
|
||||
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
|
|
||||
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
|
|
||||
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
|
|
||||
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
|
|
||||
0x0d520], // 2100
|
|
||||
|
|
||||
/** |
|
||||
* 公历每个月份的天数普通表 |
|
||||
* @Array Of Property |
|
||||
* @return Number |
|
||||
*/ |
|
||||
solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], |
|
||||
|
|
||||
/** |
|
||||
* 天干地支之天干速查表 |
|
||||
* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'], |
|
||||
|
|
||||
/** |
|
||||
* 天干地支之地支速查表 |
|
||||
* @Array Of Property |
|
||||
* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'], |
|
||||
|
|
||||
/** |
|
||||
* 天干地支之地支速查表<=>生肖 |
|
||||
* @Array Of Property |
|
||||
* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'], |
|
||||
|
|
||||
/** |
|
||||
* 24节气速查表 |
|
||||
* @Array Of Property |
|
||||
* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"] |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'], |
|
||||
|
|
||||
/** |
|
||||
* 1900-2100各年的24节气日期速查表 |
|
||||
* @Array Of Property |
|
||||
* @return 0x string For splice |
|
||||
*/ |
|
||||
sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', |
|
||||
'97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
|
||||
'97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', |
|
||||
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', |
|
||||
'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f', |
|
||||
'97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa', |
|
||||
'97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', |
|
||||
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f', |
|
||||
'97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
|
||||
'97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
|
||||
'97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', |
|
||||
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', |
|
||||
'97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
|
||||
'97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
|
||||
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722', |
|
||||
'9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f', |
|
||||
'97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', |
|
||||
'97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', |
|
||||
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722', |
|
||||
'7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
|
||||
'97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
|
||||
'97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', |
|
||||
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722', |
|
||||
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', |
|
||||
'97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
|
||||
'97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', |
|
||||
'9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', |
|
||||
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e', |
|
||||
'97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', |
|
||||
'9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', |
|
||||
'7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', |
|
||||
'7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
|
||||
'97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', |
|
||||
'9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', |
|
||||
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', |
|
||||
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa', |
|
||||
'97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', |
|
||||
'9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', |
|
||||
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721', |
|
||||
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2', |
|
||||
'977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722', |
|
||||
'7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
|
||||
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd', |
|
||||
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', |
|
||||
'977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', |
|
||||
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
|
||||
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', |
|
||||
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', |
|
||||
'977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', |
|
||||
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721', |
|
||||
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5', |
|
||||
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722', |
|
||||
'7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
|
||||
'7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', |
|
||||
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', |
|
||||
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', |
|
||||
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721', |
|
||||
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd', |
|
||||
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35', |
|
||||
'7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', |
|
||||
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721', |
|
||||
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5', |
|
||||
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35', |
|
||||
'665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', |
|
||||
'7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd', |
|
||||
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35', |
|
||||
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'], |
|
||||
|
|
||||
/** |
|
||||
* 数字转中文速查表 |
|
||||
* @Array Of Property |
|
||||
* @trans ['日','一','二','三','四','五','六','七','八','九','十'] |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'], |
|
||||
|
|
||||
/** |
|
||||
* 日期转农历称呼速查表 |
|
||||
* @Array Of Property |
|
||||
* @trans ['初','十','廿','卅'] |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'], |
|
||||
|
|
||||
/** |
|
||||
* 月份转农历称呼速查表 |
|
||||
* @Array Of Property |
|
||||
* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊'] |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'], |
|
||||
|
|
||||
/** |
|
||||
* 返回农历y年一整年的总天数 |
|
||||
* @param lunar Year |
|
||||
* @return Number |
|
||||
* @eg:var count = calendar.lYearDays(1987) ;//count=387
|
|
||||
*/ |
|
||||
lYearDays: function (y) { |
|
||||
var i; var sum = 348 |
|
||||
for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 } |
|
||||
return (sum + this.leapDays(y)) |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 |
|
||||
* @param lunar Year |
|
||||
* @return Number (0-12) |
|
||||
* @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
|
|
||||
*/ |
|
||||
leapMonth: function (y) { // 闰字编码 \u95f0
|
|
||||
return (this.lunarInfo[y - 1900] & 0xf) |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 返回农历y年闰月的天数 若该年没有闰月则返回0 |
|
||||
* @param lunar Year |
|
||||
* @return Number (0、29、30) |
|
||||
* @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
|
|
||||
*/ |
|
||||
leapDays: function (y) { |
|
||||
if (this.leapMonth(y)) { |
|
||||
return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29) |
|
||||
} |
|
||||
return (0) |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法 |
|
||||
* @param lunar Year |
|
||||
* @return Number (-1、29、30) |
|
||||
* @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
|
|
||||
*/ |
|
||||
monthDays: function (y, m) { |
|
||||
if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
|
|
||||
return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29) |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 返回公历(!)y年m月的天数 |
|
||||
* @param solar Year |
|
||||
* @return Number (-1、28、29、30、31) |
|
||||
* @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
|
|
||||
*/ |
|
||||
solarDays: function (y, m) { |
|
||||
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
|
|
||||
var ms = m - 1 |
|
||||
if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
|
|
||||
return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28) |
|
||||
} else { |
|
||||
return (this.solarMonth[ms]) |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 农历年份转换为干支纪年 |
|
||||
* @param lYear 农历年的年份数 |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
toGanZhiYear: function (lYear) { |
|
||||
var ganKey = (lYear - 3) % 10 |
|
||||
var zhiKey = (lYear - 3) % 12 |
|
||||
if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
|
|
||||
if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
|
|
||||
return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1] |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 公历月、日判断所属星座 |
|
||||
* @param cMonth [description] |
|
||||
* @param cDay [description] |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
toAstro: function (cMonth, cDay) { |
|
||||
var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf' |
|
||||
var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22] |
|
||||
return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
|
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 传入offset偏移量返回干支 |
|
||||
* @param offset 相对甲子的偏移量 |
|
||||
* @return Cn string |
|
||||
*/ |
|
||||
toGanZhi: function (offset) { |
|
||||
return this.Gan[offset % 10] + this.Zhi[offset % 12] |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 传入公历(!)y年获得该年第n个节气的公历日期 |
|
||||
* @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 |
|
||||
* @return day Number |
|
||||
* @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
|
|
||||
*/ |
|
||||
getTerm: function (y, n) { |
|
||||
if (y < 1900 || y > 2100) { return -1 } |
|
||||
if (n < 1 || n > 24) { return -1 } |
|
||||
var _table = this.sTermInfo[y - 1900] |
|
||||
var _info = [ |
|
||||
parseInt('0x' + _table.substr(0, 5)).toString(), |
|
||||
parseInt('0x' + _table.substr(5, 5)).toString(), |
|
||||
parseInt('0x' + _table.substr(10, 5)).toString(), |
|
||||
parseInt('0x' + _table.substr(15, 5)).toString(), |
|
||||
parseInt('0x' + _table.substr(20, 5)).toString(), |
|
||||
parseInt('0x' + _table.substr(25, 5)).toString() |
|
||||
] |
|
||||
var _calday = [ |
|
||||
_info[0].substr(0, 1), |
|
||||
_info[0].substr(1, 2), |
|
||||
_info[0].substr(3, 1), |
|
||||
_info[0].substr(4, 2), |
|
||||
|
|
||||
_info[1].substr(0, 1), |
|
||||
_info[1].substr(1, 2), |
|
||||
_info[1].substr(3, 1), |
|
||||
_info[1].substr(4, 2), |
|
||||
|
|
||||
_info[2].substr(0, 1), |
|
||||
_info[2].substr(1, 2), |
|
||||
_info[2].substr(3, 1), |
|
||||
_info[2].substr(4, 2), |
|
||||
|
|
||||
_info[3].substr(0, 1), |
|
||||
_info[3].substr(1, 2), |
|
||||
_info[3].substr(3, 1), |
|
||||
_info[3].substr(4, 2), |
|
||||
|
|
||||
_info[4].substr(0, 1), |
|
||||
_info[4].substr(1, 2), |
|
||||
_info[4].substr(3, 1), |
|
||||
_info[4].substr(4, 2), |
|
||||
|
|
||||
_info[5].substr(0, 1), |
|
||||
_info[5].substr(1, 2), |
|
||||
_info[5].substr(3, 1), |
|
||||
_info[5].substr(4, 2) |
|
||||
] |
|
||||
return parseInt(_calday[n - 1]) |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 传入农历数字月份返回汉语通俗表示法 |
|
||||
* @param lunar month |
|
||||
* @return Cn string |
|
||||
* @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
|
|
||||
*/ |
|
||||
toChinaMonth: function (m) { // 月 => \u6708
|
|
||||
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
|
|
||||
var s = this.nStr3[m - 1] |
|
||||
s += '\u6708'// 加上月字
|
|
||||
return s |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 传入农历日期数字返回汉字表示法 |
|
||||
* @param lunar day |
|
||||
* @return Cn string |
|
||||
* @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
|
|
||||
*/ |
|
||||
toChinaDay: function (d) { // 日 => \u65e5
|
|
||||
var s |
|
||||
switch (d) { |
|
||||
case 10: |
|
||||
s = '\u521d\u5341'; break |
|
||||
case 20: |
|
||||
s = '\u4e8c\u5341'; break |
|
||||
break |
|
||||
case 30: |
|
||||
s = '\u4e09\u5341'; break |
|
||||
break |
|
||||
default : |
|
||||
s = this.nStr2[Math.floor(d / 10)] |
|
||||
s += this.nStr1[d % 10] |
|
||||
} |
|
||||
return (s) |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春” |
|
||||
* @param y year |
|
||||
* @return Cn string |
|
||||
* @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
|
|
||||
*/ |
|
||||
getAnimal: function (y) { |
|
||||
return this.Animals[(y - 4) % 12] |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 传入阳历年月日获得详细的公历、农历object信息 <=>JSON |
|
||||
* @param y solar year |
|
||||
* @param m solar month |
|
||||
* @param d solar day |
|
||||
* @return JSON object |
|
||||
* @eg:console.log(calendar.solar2lunar(1987,11,01)); |
|
||||
*/ |
|
||||
solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
|
|
||||
// 年份限定、上限
|
|
||||
if (y < 1900 || y > 2100) { |
|
||||
return -1// undefined转换为数字变为NaN
|
|
||||
} |
|
||||
// 公历传参最下限
|
|
||||
if (y == 1900 && m == 1 && d < 31) { |
|
||||
return -1 |
|
||||
} |
|
||||
// 未传参 获得当天
|
|
||||
if (!y) { |
|
||||
var objDate = new Date() |
|
||||
} else { |
|
||||
var objDate = new Date(y, parseInt(m) - 1, d) |
|
||||
} |
|
||||
var i; var leap = 0; var temp = 0 |
|
||||
// 修正ymd参数
|
|
||||
var y = objDate.getFullYear() |
|
||||
var m = objDate.getMonth() + 1 |
|
||||
var d = objDate.getDate() |
|
||||
var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000 |
|
||||
for (i = 1900; i < 2101 && offset > 0; i++) { |
|
||||
temp = this.lYearDays(i) |
|
||||
offset -= temp |
|
||||
} |
|
||||
if (offset < 0) { |
|
||||
offset += temp; i-- |
|
||||
} |
|
||||
|
|
||||
// 是否今天
|
|
||||
var isTodayObj = new Date() |
|
||||
var isToday = false |
|
||||
if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { |
|
||||
isToday = true |
|
||||
} |
|
||||
// 星期几
|
|
||||
var nWeek = objDate.getDay() |
|
||||
var cWeek = this.nStr1[nWeek] |
|
||||
// 数字表示周几顺应天朝周一开始的惯例
|
|
||||
if (nWeek == 0) { |
|
||||
nWeek = 7 |
|
||||
} |
|
||||
// 农历年
|
|
||||
var year = i |
|
||||
var leap = this.leapMonth(i) // 闰哪个月
|
|
||||
var isLeap = false |
|
||||
|
|
||||
// 效验闰月
|
|
||||
for (i = 1; i < 13 && offset > 0; i++) { |
|
||||
// 闰月
|
|
||||
if (leap > 0 && i == (leap + 1) && isLeap == false) { |
|
||||
--i |
|
||||
isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
|
|
||||
} else { |
|
||||
temp = this.monthDays(year, i)// 计算农历普通月天数
|
|
||||
} |
|
||||
// 解除闰月
|
|
||||
if (isLeap == true && i == (leap + 1)) { isLeap = false } |
|
||||
offset -= temp |
|
||||
} |
|
||||
// 闰月导致数组下标重叠取反
|
|
||||
if (offset == 0 && leap > 0 && i == leap + 1) { |
|
||||
if (isLeap) { |
|
||||
isLeap = false |
|
||||
} else { |
|
||||
isLeap = true; --i |
|
||||
} |
|
||||
} |
|
||||
if (offset < 0) { |
|
||||
offset += temp; --i |
|
||||
} |
|
||||
// 农历月
|
|
||||
var month = i |
|
||||
// 农历日
|
|
||||
var day = offset + 1 |
|
||||
// 天干地支处理
|
|
||||
var sm = m - 1 |
|
||||
var gzY = this.toGanZhiYear(year) |
|
||||
|
|
||||
// 当月的两个节气
|
|
||||
// bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
|
|
||||
var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
|
|
||||
var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
|
|
||||
|
|
||||
// 依据12节气修正干支月
|
|
||||
var gzM = this.toGanZhi((y - 1900) * 12 + m + 11) |
|
||||
if (d >= firstNode) { |
|
||||
gzM = this.toGanZhi((y - 1900) * 12 + m + 12) |
|
||||
} |
|
||||
|
|
||||
// 传入的日期的节气与否
|
|
||||
var isTerm = false |
|
||||
var Term = null |
|
||||
if (firstNode == d) { |
|
||||
isTerm = true |
|
||||
Term = this.solarTerm[m * 2 - 2] |
|
||||
} |
|
||||
if (secondNode == d) { |
|
||||
isTerm = true |
|
||||
Term = this.solarTerm[m * 2 - 1] |
|
||||
} |
|
||||
// 日柱 当月一日与 1900/1/1 相差天数
|
|
||||
var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10 |
|
||||
var gzD = this.toGanZhi(dayCyclical + d - 1) |
|
||||
// 该日期所属的星座
|
|
||||
var astro = this.toAstro(m, d) |
|
||||
|
|
||||
return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro } |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON |
|
||||
* @param y lunar year |
|
||||
* @param m lunar month |
|
||||
* @param d lunar day |
|
||||
* @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可] |
|
||||
* @return JSON object |
|
||||
* @eg:console.log(calendar.lunar2solar(1987,9,10)); |
|
||||
*/ |
|
||||
lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
|
|
||||
var isLeapMonth = !!isLeapMonth |
|
||||
var leapOffset = 0 |
|
||||
var leapMonth = this.leapMonth(y) |
|
||||
var leapDay = this.leapDays(y) |
|
||||
if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
|
|
||||
if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
|
|
||||
var day = this.monthDays(y, m) |
|
||||
var _day = day |
|
||||
// bugFix 2016-9-25
|
|
||||
// if month is leap, _day use leapDays method
|
|
||||
if (isLeapMonth) { |
|
||||
_day = this.leapDays(y, m) |
|
||||
} |
|
||||
if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
|
|
||||
|
|
||||
// 计算农历的时间差
|
|
||||
var offset = 0 |
|
||||
for (var i = 1900; i < y; i++) { |
|
||||
offset += this.lYearDays(i) |
|
||||
} |
|
||||
var leap = 0; var isAdd = false |
|
||||
for (var i = 1; i < m; i++) { |
|
||||
leap = this.leapMonth(y) |
|
||||
if (!isAdd) { // 处理闰月
|
|
||||
if (leap <= i && leap > 0) { |
|
||||
offset += this.leapDays(y); isAdd = true |
|
||||
} |
|
||||
} |
|
||||
offset += this.monthDays(y, i) |
|
||||
} |
|
||||
// 转换闰月农历 需补充该年闰月的前一个月的时差
|
|
||||
if (isLeapMonth) { offset += day } |
|
||||
// 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
|
|
||||
var stmap = Date.UTC(1900, 1, 30, 0, 0, 0) |
|
||||
var calObj = new Date((offset + d - 31) * 86400000 + stmap) |
|
||||
var cY = calObj.getUTCFullYear() |
|
||||
var cM = calObj.getUTCMonth() + 1 |
|
||||
var cD = calObj.getUTCDate() |
|
||||
|
|
||||
return this.solar2lunar(cY, cM, cD) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export default calendar |
|
@ -1,152 +0,0 @@ |
|||||
<template> |
|
||||
<view class="uni-calendar-item__weeks-box" :class="{ |
|
||||
'uni-calendar-item--disable':weeks.disable, |
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay, |
|
||||
'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) , |
|
||||
'uni-calendar-item--multiple': weeks.multiple |
|
||||
}" |
|
||||
@click="choiceDate(weeks)"> |
|
||||
<view class="uni-calendar-item__weeks-box-item"> |
|
||||
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text> |
|
||||
<text class="uni-calendar-item__weeks-box-text" :class="{ |
|
||||
'uni-calendar-item--isDay-text': weeks.isDay, |
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay, |
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay, |
|
||||
'uni-calendar-item--multiple': weeks.multiple, |
|
||||
'uni-calendar-item--disable':weeks.disable, |
|
||||
}">{{weeks.date}}</text> |
|
||||
<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{ |
|
||||
'uni-calendar-item--isDay-text':weeks.isDay, |
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay, |
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay, |
|
||||
'uni-calendar-item--multiple': weeks.multiple, |
|
||||
}">今天</text> |
|
||||
<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{ |
|
||||
'uni-calendar-item--isDay-text':weeks.isDay, |
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay, |
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay, |
|
||||
'uni-calendar-item--multiple': weeks.multiple, |
|
||||
'uni-calendar-item--disable':weeks.disable, |
|
||||
}">{{weeks.isDay?'今天': (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text> |
|
||||
<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{ |
|
||||
'uni-calendar-item--extra':weeks.extraInfo.info, |
|
||||
'uni-calendar-item--isDay-text':weeks.isDay, |
|
||||
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay, |
|
||||
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay, |
|
||||
'uni-calendar-item--multiple': weeks.multiple, |
|
||||
'uni-calendar-item--disable':weeks.disable, |
|
||||
}">{{weeks.extraInfo.info}}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
props: { |
|
||||
weeks: { |
|
||||
type: Object, |
|
||||
default () { |
|
||||
return {} |
|
||||
} |
|
||||
}, |
|
||||
calendar: { |
|
||||
type: Object, |
|
||||
default: () => { |
|
||||
return {} |
|
||||
} |
|
||||
}, |
|
||||
selected: { |
|
||||
type: Array, |
|
||||
default: () => { |
|
||||
return [] |
|
||||
} |
|
||||
}, |
|
||||
lunar: { |
|
||||
type: Boolean, |
|
||||
default: false |
|
||||
} |
|
||||
}, |
|
||||
methods: { |
|
||||
choiceDate(weeks) { |
|
||||
this.$emit('change', weeks) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.uni-calendar-item__weeks-box { |
|
||||
flex: 1; |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
/* #endif */ |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item__weeks-box-text { |
|
||||
font-size: $uni-font-size-base; |
|
||||
color: $uni-text-color; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item__weeks-lunar-text { |
|
||||
font-size: $uni-font-size-sm; |
|
||||
color: $uni-text-color; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item__weeks-box-item { |
|
||||
position: relative; |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
/* #endif */ |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
width: 100rpx; |
|
||||
height: 100rpx; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item__weeks-box-circle { |
|
||||
position: absolute; |
|
||||
top: 5px; |
|
||||
right: 5px; |
|
||||
width: 8px; |
|
||||
height: 8px; |
|
||||
border-radius: 8px; |
|
||||
background-color: $uni-color-error; |
|
||||
|
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item--disable { |
|
||||
background-color: rgba(249, 249, 249, $uni-opacity-disabled); |
|
||||
color: $uni-text-color-disable; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item--isDay-text { |
|
||||
color: $uni-color-primary; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item--isDay { |
|
||||
background-color: $uni-color-primary; |
|
||||
opacity: 0.8; |
|
||||
color: #fff; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item--extra { |
|
||||
color: $uni-color-error; |
|
||||
opacity: 0.8; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item--checked { |
|
||||
background-color: $uni-color-primary; |
|
||||
color: #fff; |
|
||||
opacity: 0.8; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar-item--multiple { |
|
||||
background-color: $uni-color-primary; |
|
||||
color: #fff; |
|
||||
opacity: 0.8; |
|
||||
} |
|
||||
</style> |
|
@ -1,434 +0,0 @@ |
|||||
<template> |
|
||||
<view class="uni-calendar" @touchmove.stop.prevent="clean"> |
|
||||
<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view> |
|
||||
<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}"> |
|
||||
<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top"> |
|
||||
<view class="uni-calendar__header-btn-box" @click="close"> |
|
||||
<text class="uni-calendar__header-text uni-calendar--fixed-width">取消</text> |
|
||||
</view> |
|
||||
<view class="uni-calendar__header-btn-box" @click="confirm"> |
|
||||
<text class="uni-calendar__header-text uni-calendar--fixed-width">确定</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="uni-calendar__header"> |
|
||||
<view class="uni-calendar__header-btn-box" @click="pre"> |
|
||||
<view class="uni-calendar__header-btn uni-calendar--left"></view> |
|
||||
</view> |
|
||||
<text class="uni-calendar__header-text">{{ (nowDate.year||'') +'年'+( nowDate.month||'') +'月'}}</text> |
|
||||
<view class="uni-calendar__header-btn-box" @click="next"> |
|
||||
<view class="uni-calendar__header-btn uni-calendar--right"></view> |
|
||||
</view> |
|
||||
<text class="uni-calendar__backtoday" @click="backtoday">回到今天</text> |
|
||||
</view> |
|
||||
<view class="uni-calendar__box"> |
|
||||
<view v-if="showMonth" class="uni-calendar__box-bg"> |
|
||||
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text> |
|
||||
</view> |
|
||||
<view class="uni-calendar__weeks"> |
|
||||
<view class="uni-calendar__weeks-day"> |
|
||||
<text class="uni-calendar__weeks-day-text">日</text> |
|
||||
</view> |
|
||||
<view class="uni-calendar__weeks-day"> |
|
||||
<text class="uni-calendar__weeks-day-text">一</text> |
|
||||
</view> |
|
||||
<view class="uni-calendar__weeks-day"> |
|
||||
<text class="uni-calendar__weeks-day-text">二</text> |
|
||||
</view> |
|
||||
<view class="uni-calendar__weeks-day"> |
|
||||
<text class="uni-calendar__weeks-day-text">三</text> |
|
||||
</view> |
|
||||
<view class="uni-calendar__weeks-day"> |
|
||||
<text class="uni-calendar__weeks-day-text">四</text> |
|
||||
</view> |
|
||||
<view class="uni-calendar__weeks-day"> |
|
||||
<text class="uni-calendar__weeks-day-text">五</text> |
|
||||
</view> |
|
||||
<view class="uni-calendar__weeks-day"> |
|
||||
<text class="uni-calendar__weeks-day-text">六</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex"> |
|
||||
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex"> |
|
||||
<uni-calendar-item :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></uni-calendar-item> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import Calendar from './util.js'; |
|
||||
import uniCalendarItem from './uni-calendar-item.vue' |
|
||||
export default { |
|
||||
components: { |
|
||||
uniCalendarItem |
|
||||
}, |
|
||||
props: { |
|
||||
/** |
|
||||
* 当前日期 |
|
||||
*/ |
|
||||
date: { |
|
||||
type: String, |
|
||||
default: '' |
|
||||
}, |
|
||||
/** |
|
||||
* 打点日期 |
|
||||
*/ |
|
||||
selected: { |
|
||||
type: Array, |
|
||||
default () { |
|
||||
return [] |
|
||||
} |
|
||||
}, |
|
||||
/** |
|
||||
* 是否开启阴历日期 |
|
||||
*/ |
|
||||
lunar: { |
|
||||
type: Boolean, |
|
||||
default: false |
|
||||
}, |
|
||||
/** |
|
||||
* 开始时间 |
|
||||
*/ |
|
||||
startDate: { |
|
||||
type: String, |
|
||||
default: '' |
|
||||
}, |
|
||||
/** |
|
||||
* 结束时间 |
|
||||
*/ |
|
||||
endDate: { |
|
||||
type: String, |
|
||||
default: '' |
|
||||
}, |
|
||||
/** |
|
||||
* 范围 |
|
||||
*/ |
|
||||
range: { |
|
||||
type: Boolean, |
|
||||
default: false |
|
||||
}, |
|
||||
/** |
|
||||
* 插入 |
|
||||
*/ |
|
||||
insert: { |
|
||||
type: Boolean, |
|
||||
default: true |
|
||||
}, |
|
||||
/** |
|
||||
* 是否显示月份背景 |
|
||||
*/ |
|
||||
showMonth: { |
|
||||
type: Boolean, |
|
||||
default: true |
|
||||
} |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
show: false, |
|
||||
weeks: [], |
|
||||
calendar: {}, |
|
||||
nowDate: '', |
|
||||
aniMaskShow: false |
|
||||
} |
|
||||
}, |
|
||||
watch: { |
|
||||
selected(newVal) { |
|
||||
this.cale.setSelectInfo(this.nowDate.fullDate, newVal) |
|
||||
this.weeks = this.cale.weeks |
|
||||
} |
|
||||
}, |
|
||||
created() { |
|
||||
// 获取日历方法实例 |
|
||||
this.cale = new Calendar({ |
|
||||
date: this.date, |
|
||||
selected: this.selected, |
|
||||
startDate: this.startDate, |
|
||||
endDate: this.endDate, |
|
||||
range: this.range, |
|
||||
}) |
|
||||
this.init(this.cale.date.fullDate) |
|
||||
}, |
|
||||
methods: { |
|
||||
// 取消穿透 |
|
||||
clean() {}, |
|
||||
init(date) { |
|
||||
this.weeks = this.cale.weeks |
|
||||
this.nowDate = this.calendar = this.cale.getInfo(date) |
|
||||
}, |
|
||||
open() { |
|
||||
this.show = true |
|
||||
this.$nextTick(() => { |
|
||||
setTimeout(()=>{ |
|
||||
this.aniMaskShow = true |
|
||||
},50) |
|
||||
}) |
|
||||
}, |
|
||||
close() { |
|
||||
this.aniMaskShow = false |
|
||||
this.$nextTick(() => { |
|
||||
setTimeout(() => { |
|
||||
this.show = false |
|
||||
}, 300) |
|
||||
}) |
|
||||
}, |
|
||||
confirm() { |
|
||||
this.setEmit('confirm') |
|
||||
this.close() |
|
||||
}, |
|
||||
change() { |
|
||||
if (!this.insert) return |
|
||||
this.setEmit('change') |
|
||||
}, |
|
||||
monthSwitch() { |
|
||||
let { |
|
||||
year, |
|
||||
month |
|
||||
} = this.nowDate |
|
||||
this.$emit('monthSwitch', { |
|
||||
year, |
|
||||
month: Number(month) |
|
||||
}) |
|
||||
}, |
|
||||
setEmit(name) { |
|
||||
let { |
|
||||
year, |
|
||||
month, |
|
||||
date, |
|
||||
fullDate, |
|
||||
lunar, |
|
||||
extraInfo |
|
||||
} = this.calendar |
|
||||
this.$emit(name, { |
|
||||
range: this.cale.multipleStatus, |
|
||||
year, |
|
||||
month, |
|
||||
date, |
|
||||
fulldate: fullDate, |
|
||||
lunar, |
|
||||
extraInfo: extraInfo || {} |
|
||||
}) |
|
||||
}, |
|
||||
choiceDate(weeks) { |
|
||||
if (weeks.disable) return |
|
||||
this.calendar = weeks |
|
||||
// 设置多选 |
|
||||
this.cale.setMultiple(this.calendar.fullDate) |
|
||||
this.weeks = this.cale.weeks |
|
||||
this.change() |
|
||||
}, |
|
||||
backtoday() { |
|
||||
this.cale.setDate(this.date) |
|
||||
this.weeks = this.cale.weeks |
|
||||
this.nowDate = this.calendar = this.cale.getInfo(this.date) |
|
||||
this.change() |
|
||||
}, |
|
||||
pre() { |
|
||||
const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate |
|
||||
this.setDate(preDate) |
|
||||
this.monthSwitch() |
|
||||
|
|
||||
}, |
|
||||
next() { |
|
||||
const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate |
|
||||
this.setDate(nextDate) |
|
||||
this.monthSwitch() |
|
||||
}, |
|
||||
setDate(date) { |
|
||||
this.cale.setDate(date) |
|
||||
this.weeks = this.cale.weeks |
|
||||
this.nowDate = this.cale.getInfo(date) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.uni-calendar { |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
/* #endif */ |
|
||||
flex-direction: column; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__mask { |
|
||||
position: fixed; |
|
||||
bottom: 0; |
|
||||
top: 0; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
background-color: $uni-bg-color-mask; |
|
||||
transition-property: opacity; |
|
||||
transition-duration: 0.3s; |
|
||||
opacity: 0; |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
z-index: 99; |
|
||||
/* #endif */ |
|
||||
} |
|
||||
|
|
||||
.uni-calendar--mask-show { |
|
||||
opacity: 1 |
|
||||
} |
|
||||
|
|
||||
.uni-calendar--fixed { |
|
||||
position: fixed; |
|
||||
bottom: 0; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
transition-property: transform; |
|
||||
transition-duration: 0.3s; |
|
||||
transform: translateY(460px); |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
z-index: 99; |
|
||||
/* #endif */ |
|
||||
} |
|
||||
|
|
||||
.uni-calendar--ani-show { |
|
||||
transform: translateY(0); |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__content { |
|
||||
background-color: #fff; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__header { |
|
||||
position: relative; |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
/* #endif */ |
|
||||
flex-direction: row; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
height: 50px; |
|
||||
border-bottom-color: $uni-border-color; |
|
||||
border-bottom-style: solid; |
|
||||
border-bottom-width: 1px; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar--fixed-top { |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
/* #endif */ |
|
||||
flex-direction: row; |
|
||||
justify-content: space-between; |
|
||||
border-top-color: $uni-border-color; |
|
||||
border-top-style: solid; |
|
||||
border-top-width: 1px; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar--fixed-width { |
|
||||
width: 50px; |
|
||||
// padding: 0 15px; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__backtoday { |
|
||||
position: absolute; |
|
||||
right: 0; |
|
||||
top: 25rpx; |
|
||||
padding: 0 5px; |
|
||||
padding-left: 10px; |
|
||||
height: 25px; |
|
||||
line-height: 25px; |
|
||||
font-size: 12px; |
|
||||
border-top-left-radius: 25px; |
|
||||
border-bottom-left-radius: 25px; |
|
||||
color: $uni-text-color; |
|
||||
background-color: $uni-bg-color-hover; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__header-text { |
|
||||
text-align: center; |
|
||||
width: 100px; |
|
||||
font-size: $uni-font-size-base; |
|
||||
color: $uni-text-color; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__header-btn-box { |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
/* #endif */ |
|
||||
flex-direction: row; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
width: 50px; |
|
||||
height: 50px; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__header-btn { |
|
||||
width: 10px; |
|
||||
height: 10px; |
|
||||
border-left-color: $uni-text-color-placeholder; |
|
||||
border-left-style: solid; |
|
||||
border-left-width: 2px; |
|
||||
border-top-color: $uni-color-subtitle; |
|
||||
border-top-style: solid; |
|
||||
border-top-width: 2px; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar--left { |
|
||||
transform: rotate(-45deg); |
|
||||
} |
|
||||
|
|
||||
.uni-calendar--right { |
|
||||
transform: rotate(135deg); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
.uni-calendar__weeks { |
|
||||
position: relative; |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
/* #endif */ |
|
||||
flex-direction: row; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__weeks-item { |
|
||||
flex: 1; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__weeks-day { |
|
||||
flex: 1; |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
/* #endif */ |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
height: 45px; |
|
||||
border-bottom-color: #F5F5F5; |
|
||||
border-bottom-style: solid; |
|
||||
border-bottom-width: 1px; |
|
||||
} |
|
||||
.uni-calendar__weeks-day-text { |
|
||||
font-size: 14px; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__box { |
|
||||
position: relative; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__box-bg { |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
/* #endif */ |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
bottom: 0; |
|
||||
} |
|
||||
|
|
||||
.uni-calendar__box-bg-text { |
|
||||
font-size: 200px; |
|
||||
font-weight: bold; |
|
||||
color: $uni-text-color-grey; |
|
||||
opacity: 0.1; |
|
||||
text-align: center; |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
line-height: 1; |
|
||||
/* #endif */ |
|
||||
} |
|
||||
</style> |
|
@ -1,327 +0,0 @@ |
|||||
import CALENDAR from './calendar.js' |
|
||||
|
|
||||
class Calendar { |
|
||||
constructor({ |
|
||||
date, |
|
||||
selected, |
|
||||
startDate, |
|
||||
endDate, |
|
||||
range |
|
||||
} = {}) { |
|
||||
// 当前日期
|
|
||||
this.date = this.getDate(date) // 当前初入日期
|
|
||||
// 打点信息
|
|
||||
this.selected = selected || []; |
|
||||
// 范围开始
|
|
||||
this.startDate = startDate |
|
||||
// 范围结束
|
|
||||
this.endDate = endDate |
|
||||
this.range = range |
|
||||
// 多选状态
|
|
||||
this.multipleStatus = { |
|
||||
before: '', |
|
||||
after: '', |
|
||||
data: [] |
|
||||
} |
|
||||
// 每周日期
|
|
||||
this.weeks = {} |
|
||||
|
|
||||
this._getWeek(this.date.fullDate) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取任意时间 |
|
||||
*/ |
|
||||
getDate(date, AddDayCount = 0, str = 'day') { |
|
||||
if (!date) { |
|
||||
date = new Date() |
|
||||
} |
|
||||
if (typeof date !== 'object') { |
|
||||
date = date.replace(/-/g, '/') |
|
||||
} |
|
||||
const dd = new Date(date) |
|
||||
switch (str) { |
|
||||
case 'day': |
|
||||
dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
|
|
||||
break |
|
||||
case 'month': |
|
||||
if (dd.getDate() === 31) { |
|
||||
dd.setDate(dd.getDate() + AddDayCount) |
|
||||
} else { |
|
||||
dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
|
|
||||
} |
|
||||
break |
|
||||
case 'year': |
|
||||
dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
|
|
||||
break |
|
||||
} |
|
||||
const y = dd.getFullYear() |
|
||||
const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
|
|
||||
const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
|
|
||||
return { |
|
||||
fullDate: y + '-' + m + '-' + d, |
|
||||
year: y, |
|
||||
month: m, |
|
||||
date: d, |
|
||||
day: dd.getDay() |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 获取上月剩余天数 |
|
||||
*/ |
|
||||
_getLastMonthDays(firstDay, full) { |
|
||||
let dateArr = [] |
|
||||
for (let i = firstDay; i > 0; i--) { |
|
||||
const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate() |
|
||||
dateArr.push({ |
|
||||
date: beforeDate, |
|
||||
month: full.month - 1, |
|
||||
lunar: this.getlunar(full.year, full.month - 1, beforeDate), |
|
||||
disable: true |
|
||||
}) |
|
||||
} |
|
||||
return dateArr |
|
||||
} |
|
||||
/** |
|
||||
* 获取本月天数 |
|
||||
*/ |
|
||||
_currentMonthDys(dateData, full) { |
|
||||
let dateArr = [] |
|
||||
let fullDate = this.date.fullDate |
|
||||
for (let i = 1; i <= dateData; i++) { |
|
||||
let isinfo = false |
|
||||
let nowDate = full.year + '-' + (full.month < 10 ? |
|
||||
full.month : full.month) + '-' + (i < 10 ? |
|
||||
'0' + i : i) |
|
||||
// 是否今天
|
|
||||
let isDay = fullDate === nowDate |
|
||||
// 获取打点信息
|
|
||||
let info = this.selected && this.selected.find((item) => { |
|
||||
if (this.dateEqual(nowDate, item.date)) { |
|
||||
return item |
|
||||
} |
|
||||
}) |
|
||||
|
|
||||
// 日期禁用
|
|
||||
let disableBefore = true |
|
||||
let disableAfter = true |
|
||||
if (this.startDate) { |
|
||||
let dateCompBefore = this.dateCompare(this.startDate, fullDate) |
|
||||
disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate) |
|
||||
} |
|
||||
|
|
||||
if (this.endDate) { |
|
||||
let dateCompAfter = this.dateCompare(fullDate, this.endDate) |
|
||||
disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate) |
|
||||
} |
|
||||
|
|
||||
let multiples = this.multipleStatus.data |
|
||||
let checked = false |
|
||||
let multiplesStatus = -1 |
|
||||
if (this.range) { |
|
||||
if (multiples) { |
|
||||
multiplesStatus = multiples.findIndex((item) => { |
|
||||
return this.dateEqual(item, nowDate) |
|
||||
}) |
|
||||
} |
|
||||
if (multiplesStatus !== -1) { |
|
||||
checked = true |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
let data = { |
|
||||
fullDate: nowDate, |
|
||||
year: full.year, |
|
||||
date: i, |
|
||||
multiple: this.range ? checked : false, |
|
||||
month: full.month, |
|
||||
lunar: this.getlunar(full.year, full.month, i), |
|
||||
disable: !disableBefore || !disableAfter, |
|
||||
isDay |
|
||||
} |
|
||||
if (info) { |
|
||||
data.extraInfo = info |
|
||||
} |
|
||||
|
|
||||
dateArr.push(data) |
|
||||
} |
|
||||
return dateArr |
|
||||
} |
|
||||
/** |
|
||||
* 获取下月天数 |
|
||||
*/ |
|
||||
_getNextMonthDays(surplus, full) { |
|
||||
let dateArr = [] |
|
||||
for (let i = 1; i < surplus + 1; i++) { |
|
||||
dateArr.push({ |
|
||||
date: i, |
|
||||
month: Number(full.month) + 1, |
|
||||
lunar: this.getlunar(full.year, Number(full.month) + 1, i), |
|
||||
disable: true |
|
||||
}) |
|
||||
} |
|
||||
return dateArr |
|
||||
} |
|
||||
/** |
|
||||
* 设置日期 |
|
||||
* @param {Object} date |
|
||||
*/ |
|
||||
setDate(date) { |
|
||||
this._getWeek(date) |
|
||||
} |
|
||||
/** |
|
||||
* 获取当前日期详情 |
|
||||
* @param {Object} date |
|
||||
*/ |
|
||||
getInfo(date) { |
|
||||
if (!date) { |
|
||||
date = new Date() |
|
||||
} |
|
||||
const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate) |
|
||||
return dateInfo |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 比较时间大小 |
|
||||
*/ |
|
||||
dateCompare(startDate, endDate) { |
|
||||
// 计算截止时间
|
|
||||
startDate = new Date(startDate.replace('-', '/').replace('-', '/')) |
|
||||
// 计算详细项的截止时间
|
|
||||
endDate = new Date(endDate.replace('-', '/').replace('-', '/')) |
|
||||
if (startDate <= endDate) { |
|
||||
return true |
|
||||
} else { |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 比较时间是否相等 |
|
||||
*/ |
|
||||
dateEqual(before, after) { |
|
||||
// 计算截止时间
|
|
||||
before = new Date(before.replace('-', '/').replace('-', '/')) |
|
||||
// 计算详细项的截止时间
|
|
||||
after = new Date(after.replace('-', '/').replace('-', '/')) |
|
||||
if (before.getTime() - after.getTime() === 0) { |
|
||||
return true |
|
||||
} else { |
|
||||
return false |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 获取日期范围内所有日期 |
|
||||
* @param {Object} begin |
|
||||
* @param {Object} end |
|
||||
*/ |
|
||||
geDateAll(begin, end) { |
|
||||
var arr = [] |
|
||||
var ab = begin.split('-') |
|
||||
var ae = end.split('-') |
|
||||
var db = new Date() |
|
||||
db.setFullYear(ab[0], ab[1] - 1, ab[2]) |
|
||||
var de = new Date() |
|
||||
de.setFullYear(ae[0], ae[1] - 1, ae[2]) |
|
||||
var unixDb = db.getTime() - 24 * 60 * 60 * 1000 |
|
||||
var unixDe = de.getTime() - 24 * 60 * 60 * 1000 |
|
||||
for (var k = unixDb; k <= unixDe;) { |
|
||||
k = k + 24 * 60 * 60 * 1000 |
|
||||
arr.push(this.getDate(new Date(parseInt(k))).fullDate) |
|
||||
} |
|
||||
return arr |
|
||||
} |
|
||||
/** |
|
||||
* 计算阴历日期显示 |
|
||||
*/ |
|
||||
getlunar(year, month, date) { |
|
||||
return CALENDAR.solar2lunar(year, month, date) |
|
||||
} |
|
||||
/** |
|
||||
* 设置打点 |
|
||||
*/ |
|
||||
setSelectInfo(data, value) { |
|
||||
this.selected = value |
|
||||
this._getWeek(data) |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取多选状态 |
|
||||
*/ |
|
||||
setMultiple(fullDate) { |
|
||||
let { |
|
||||
before, |
|
||||
after |
|
||||
} = this.multipleStatus |
|
||||
if (!this.range) return |
|
||||
if (before && after) { |
|
||||
this.multipleStatus.before = '' |
|
||||
this.multipleStatus.after = '' |
|
||||
this.multipleStatus.data = [] |
|
||||
this._getWeek(fullDate) |
|
||||
} else { |
|
||||
if (!before) { |
|
||||
this.multipleStatus.before = fullDate |
|
||||
} else { |
|
||||
this.multipleStatus.after = fullDate |
|
||||
if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) { |
|
||||
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after); |
|
||||
} else { |
|
||||
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before); |
|
||||
} |
|
||||
this._getWeek(fullDate) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取每周数据 |
|
||||
* @param {Object} dateData |
|
||||
*/ |
|
||||
_getWeek(dateData) { |
|
||||
const { |
|
||||
fullDate, |
|
||||
year, |
|
||||
month, |
|
||||
date, |
|
||||
day |
|
||||
} = this.getDate(dateData) |
|
||||
let firstDay = new Date(year, month - 1, 1).getDay() |
|
||||
let currentDay = new Date(year, month, 0).getDate() |
|
||||
let dates = { |
|
||||
lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
|
|
||||
currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
|
|
||||
nextMonthDays: [], // 下个月开始几天
|
|
||||
weeks: [] |
|
||||
} |
|
||||
let canlender = [] |
|
||||
const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length) |
|
||||
dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData)) |
|
||||
canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays) |
|
||||
let weeks = {} |
|
||||
// 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
|
|
||||
for (let i = 0; i < canlender.length; i++) { |
|
||||
if (i % 7 === 0) { |
|
||||
weeks[parseInt(i / 7)] = new Array(7) |
|
||||
} |
|
||||
weeks[parseInt(i / 7)][i % 7] = canlender[i] |
|
||||
} |
|
||||
this.canlender = canlender |
|
||||
this.weeks = weeks |
|
||||
} |
|
||||
|
|
||||
//静态方法
|
|
||||
// static init(date) {
|
|
||||
// if (!this.instance) {
|
|
||||
// this.instance = new Calendar(date);
|
|
||||
// }
|
|
||||
// return this.instance;
|
|
||||
// }
|
|
||||
} |
|
||||
|
|
||||
|
|
||||
export default Calendar |
|
@ -1,124 +0,0 @@ |
|||||
<template> |
|
||||
<view :class="[styleType === 'text'?'segmented-control--text' : 'segmented-control--button' ]" :style="{ borderColor: styleType === 'text' ? '' : activeColor }" |
|
||||
class="segmented-control"> |
|
||||
<view v-for="(item, index) in values" :class="[ styleType === 'text'?'segmented-control__item--text': 'segmented-control__item--button' , index === currentIndex&&styleType === 'button'?'segmented-control__item--button--active': '' , index === 0&&styleType === 'button'?'segmented-control__item--button--first': '',index === values.length - 1&&styleType === 'button'?'segmented-control__item--button--last': '' ]" |
|
||||
:key="index" :style="{ |
|
||||
backgroundColor: index === currentIndex && styleType === 'button' ? activeColor : '',borderColor: index === currentIndex&&styleType === 'text'||styleType === 'button'?activeColor:'transparent' |
|
||||
}" |
|
||||
class="segmented-control__item" @click="_onClick(index)"> |
|
||||
<text :style="{color: |
|
||||
index === currentIndex |
|
||||
? styleType === 'text' |
|
||||
? activeColor |
|
||||
: '#fff' |
|
||||
: styleType === 'text' |
|
||||
? '#000' |
|
||||
: activeColor}" |
|
||||
class="segmented-control__text">{{ item }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
name: 'UniSegmentedControl', |
|
||||
props: { |
|
||||
current: { |
|
||||
type: Number, |
|
||||
default: 0 |
|
||||
}, |
|
||||
values: { |
|
||||
type: Array, |
|
||||
default () { |
|
||||
return [] |
|
||||
} |
|
||||
}, |
|
||||
activeColor: { |
|
||||
type: String, |
|
||||
default: '#007aff' |
|
||||
}, |
|
||||
styleType: { |
|
||||
type: String, |
|
||||
default: 'button' |
|
||||
} |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
currentIndex: 0 |
|
||||
} |
|
||||
}, |
|
||||
watch: { |
|
||||
current(val) { |
|
||||
if (val !== this.currentIndex) { |
|
||||
this.currentIndex = val |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
created() { |
|
||||
this.currentIndex = this.current |
|
||||
}, |
|
||||
methods: { |
|
||||
_onClick(index) { |
|
||||
if (this.currentIndex !== index) { |
|
||||
this.currentIndex = index |
|
||||
this.$emit('clickItem', {currentIndex:index}) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
@import '@/uni.scss'; |
|
||||
|
|
||||
.segmented-control { |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: flex; |
|
||||
box-sizing: border-box; |
|
||||
/* #endif */ |
|
||||
flex-direction: row; |
|
||||
height: 36px; |
|
||||
overflow: hidden; |
|
||||
} |
|
||||
|
|
||||
.segmented-control__item { |
|
||||
/* #ifndef APP-NVUE */ |
|
||||
display: inline-flex; |
|
||||
box-sizing: border-box; |
|
||||
/* #endif */ |
|
||||
position: relative; |
|
||||
flex: 1; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
} |
|
||||
|
|
||||
.segmented-control__item--button { |
|
||||
border-style: solid; |
|
||||
border-top-width: 1px; |
|
||||
border-bottom-width: 1px; |
|
||||
border-right-width: 1px; |
|
||||
border-left-width: 0; |
|
||||
} |
|
||||
|
|
||||
.segmented-control__item--button--first { |
|
||||
border-left-width: 1px; |
|
||||
border-top-left-radius: 5px; |
|
||||
border-bottom-left-radius: 5px; |
|
||||
} |
|
||||
|
|
||||
.segmented-control__item--button--last { |
|
||||
border-top-right-radius: 5px; |
|
||||
border-bottom-right-radius: 5px; |
|
||||
} |
|
||||
|
|
||||
.segmented-control__item--text { |
|
||||
border-bottom-style: solid; |
|
||||
border-bottom-width: 3px; |
|
||||
} |
|
||||
|
|
||||
.segmented-control__text { |
|
||||
font-size: 16px; |
|
||||
line-height: 20px; |
|
||||
text-align: center; |
|
||||
} |
|
||||
</style> |
|
@ -1,103 +0,0 @@ |
|||||
<template> |
|
||||
<view class="margin flex flex-wrap"> |
|
||||
<view class="flex flex-wrap"> |
|
||||
<view @click="changeIntentions" class="iconfont agree-box" :class="[agree ? 'text-blue icon-check-square': 'text-gray icon-border']"></view> |
|
||||
<view class="text-df text-black flex-sub agree-text"> |
|
||||
请认真阅读 |
|
||||
<text class="text-blue" @tap="openPage('/pages/service-agreement/service-agreement')">《用户服务协议》</text>和 |
|
||||
<text class="text-blue" @tap="openPage('/pages/privacy-aolicy/privacy-aolicy')">《隐私政策》</text>, |
|
||||
勾选代表您已同意此协议 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="flex flex-wrap margin-tb-sm text-black"> |
|
||||
<view class="text-df text-bold flex agree-text"> |
|
||||
本人郑重承诺: |
|
||||
</view> |
|
||||
<view class="flex"> |
|
||||
<view @click="changeIntentions1" class="iconfont agree-box" :class="[agree1 ? 'text-blue icon-check-square': 'text-gray icon-border']"></view> |
|
||||
<view class="text-df flex-sub agree-text"> |
|
||||
为疫情防控,本人同意以上信息依法提交山西大学统筹管理。 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="flex"> |
|
||||
<view @click="changeIntentions2" class="iconfont agree-box" :class="[agree2 ? 'text-blue icon-check-square': 'text-gray icon-border']"></view> |
|
||||
<view class="text-df flex-sub agree-text"> |
|
||||
上述信息是我本人填写,本人对信息内容的真实性和完整性负责。如果信息有误或者缺失,本人愿承担相应的法律责任。同时,本人保证遵守防疫管控的各项规定,配合并听从各项措施和要求。 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
agree: false, |
|
||||
agree1: false, |
|
||||
agree2: false, |
|
||||
}; |
|
||||
}, |
|
||||
onLoad(op) {}, |
|
||||
methods: { |
|
||||
changeIntentions(){ |
|
||||
if(!this.agree){ |
|
||||
this.agree = true; |
|
||||
}else{ |
|
||||
this.agree = false; |
|
||||
} |
|
||||
this.$emit('changeIntentions',this.agree) |
|
||||
}, |
|
||||
|
|
||||
changeIntentions1(){ |
|
||||
if(!this.agree1){ |
|
||||
this.agree1 = true; |
|
||||
}else{ |
|
||||
this.agree1 = false; |
|
||||
} |
|
||||
this.$emit('changeIntentions1',this.agree1) |
|
||||
}, |
|
||||
|
|
||||
changeIntentions2(){ |
|
||||
if(!this.agree2){ |
|
||||
this.agree2 = true; |
|
||||
}else{ |
|
||||
this.agree2 = false; |
|
||||
} |
|
||||
this.$emit('changeIntentions2',this.agree2) |
|
||||
}, |
|
||||
|
|
||||
// 服务协议 |
|
||||
serviceAgreement(){ |
|
||||
uni.navigateToMiniProgram({ |
|
||||
appId: 'wx5b97b0686831c076', |
|
||||
path: 'pages/preview/preview?sid=&fid=60774991254', |
|
||||
success(res) { |
|
||||
console.log(res); |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 隐私政策 |
|
||||
privacyAolicy(){ |
|
||||
uni.navigateToMiniProgram({ |
|
||||
appId: 'wx5b97b0686831c076', |
|
||||
path: 'pages/preview/preview?sid=&fid=60774976650', |
|
||||
success(res) { |
|
||||
console.log(res); |
|
||||
}, |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.agree-box { |
|
||||
width: 70rpx; |
|
||||
} |
|
||||
|
|
||||
.agree-text { |
|
||||
line-height: 60rpx; |
|
||||
} |
|
||||
</style> |
|
@ -1,49 +0,0 @@ |
|||||
const HEALTH = '/health'; |
|
||||
const users = `${HEALTH}/users`; |
|
||||
const health = `${HEALTH}/health`; |
|
||||
const sites = `${HEALTH}/sites`; |
|
||||
const journeys = `${HEALTH}/journeys`; |
|
||||
|
|
||||
// 保存个人信息
|
|
||||
export const SUBMIT_USER_INFO = `${users}/addInfo`; |
|
||||
|
|
||||
// 获取个人信息
|
|
||||
export const GET_USER_INFO = `${users}/info`; |
|
||||
|
|
||||
// 获取健康打卡记录
|
|
||||
export const HEALTH_SIGN_HISTORY = `${health}/info`; |
|
||||
|
|
||||
// 健康上报数目统计
|
|
||||
export const HEALTH_TYPE_STATISTICS = `${health}/statistics`; |
|
||||
|
|
||||
// 查询健康状态类型
|
|
||||
export const HEALTH_TYPE_STATUS = `${health}/type`; |
|
||||
|
|
||||
// 健康打卡
|
|
||||
export const HEALTH_SIGN = `${health}/upload`; |
|
||||
|
|
||||
// 上传备注图片
|
|
||||
export const HEALTH_FILE = `${health}/file`; |
|
||||
|
|
||||
// 查看自己的打卡记录
|
|
||||
export const USER_SIGNS = `${sites}/info`; |
|
||||
|
|
||||
// 获取所有场景信息
|
|
||||
export const SITES_INFO = `${sites}/siteInfo`; |
|
||||
|
|
||||
// 根据二维码的id获取场所的信息
|
|
||||
export const SITE = `${sites}/site`; |
|
||||
|
|
||||
// 扫码统计
|
|
||||
export const SCHOOL_SIGNS = `${sites}/statistics`; |
|
||||
|
|
||||
// 扫码打卡
|
|
||||
export const SCAN_SIGN = `${sites}/upload`; |
|
||||
|
|
||||
// 查询行程
|
|
||||
export const GET_JOURNEYS = `${journeys}/info`; |
|
||||
|
|
||||
// 上报行程
|
|
||||
export const SUBMIT_JOURNEYS = `${journeys}/upload`; |
|
||||
|
|
||||
|
|
@ -1,10 +0,0 @@ |
|||||
const proxyUrl = '/tall/v1.0'; |
|
||||
|
|
||||
// 登录api
|
|
||||
export const SIGN_IN = `${proxyUrl}/users/signin`; |
|
||||
|
|
||||
// 上传用户微信信息
|
|
||||
export const UPDATE_USER = `${proxyUrl}/users/userInfo`; |
|
||||
|
|
||||
// 通过userId 获取token
|
|
||||
export const USER_ID_EXCHANGE_TOKEN = `${proxyUrl}/users/userId`; |
|
@ -1,291 +0,0 @@ |
|||||
<template> |
|
||||
<view> |
|
||||
<form class="padding-lr cu-form-group flex-direction"> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>出发时间</view> |
|
||||
<start-date-selector @change="getStartData" /> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>抵达时间</view> |
|
||||
<end-date-selector @change="getEndData" /> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>行程类型</view> |
|
||||
<radio-group class="block" @change="TypeChange"> |
|
||||
<view class="flex"> |
|
||||
<view class="flex-sub margin-tb-sm" v-for="(journey,index) in journeys" :key="index"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === journeyType" :value="journey.value"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ journey.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="text-xl padding-tb-sm"><span class="text-red padding-right-xs">*</span>出行交通方式</view> |
|
||||
<radio-group class="block" @change="RadioChange"> |
|
||||
<view class="cu-list menu text-left"> |
|
||||
<view class="cu-item" v-for="(transport,index) in transports" :key="index"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === tripMode" :value="transport.value"></radio> |
|
||||
<view class="flex-sub" style="font-size: 34rpx;">{{ transport.name }}</view> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>乘坐航班车次或车牌号码及座位号(没有填无)</view> |
|
||||
<input placeholder="请输入" name="input" type="text" v-model="carNo" maxlength="12"/> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm">同行人</view> |
|
||||
<input placeholder="请输入同行人" name="input" type="text" v-model="together" maxlength="255" /> |
|
||||
</view> |
|
||||
</form> |
|
||||
<user-agreement @changeIntentions="changeIntentions" @changeIntentions1="changeIntentions1" @changeIntentions2="changeIntentions2"></user-agreement> |
|
||||
<button class="bg-cyan margin primary-btn" hover-class="cc-active" @tap="handleAddStroke">确认提交</button> |
|
||||
<!-- 历史 --> |
|
||||
<button class="shadow round bg-cyan history-btn iconfont icon-history" hover-class="cc-active" @tap="openPage('/pages/my-trips/my-trips')"></button> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { showToast } from 'common/script/util'; |
|
||||
import UniCalendar from 'components/uni-calendar/uni-calendar.vue'; |
|
||||
import StartDateSelector from './components/start-date-selector.vue'; |
|
||||
import EndDateSelector from './components/end-date-selector.vue'; |
|
||||
import { SUBMIT_JOURNEYS } from 'api/api'; |
|
||||
|
|
||||
export default { |
|
||||
components: {UniCalendar,StartDateSelector,EndDateSelector}, |
|
||||
data() { |
|
||||
return { |
|
||||
startTime: this.$moment().format('YYYY-MM-DD HH:mm'), |
|
||||
endTime: this.$moment().format('YYYY-MM-DD HH:mm'), |
|
||||
transports: [ |
|
||||
{ |
|
||||
value: '0', |
|
||||
name: '火车', |
|
||||
}, |
|
||||
{ |
|
||||
value: '1', |
|
||||
name: '飞机', |
|
||||
}, |
|
||||
{ |
|
||||
value: '2', |
|
||||
name: '客运车辆', |
|
||||
}, |
|
||||
{ |
|
||||
value: '3', |
|
||||
name: '自驾', |
|
||||
}, |
|
||||
{ |
|
||||
value: '4', |
|
||||
name: '船', |
|
||||
}, |
|
||||
{ |
|
||||
value: '5', |
|
||||
name: '其他', |
|
||||
} |
|
||||
], |
|
||||
carNo: '', |
|
||||
journeys: [ |
|
||||
{ |
|
||||
value: '0', |
|
||||
name: '返校行程', |
|
||||
}, |
|
||||
{ |
|
||||
value: '1', |
|
||||
name: '日常外出', |
|
||||
} |
|
||||
], |
|
||||
together: '', |
|
||||
tripMode: 0, |
|
||||
journeyType: 0, |
|
||||
agree: false, |
|
||||
agree1: false, |
|
||||
agree2: false |
|
||||
}; |
|
||||
}, |
|
||||
methods: { |
|
||||
RadioChange: function(evt) { |
|
||||
for (let i = 0; i < this.transports.length; i++) { |
|
||||
if (this.transports[i].value === evt.target.value) { |
|
||||
this.tripMode = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
TypeChange: function(evt) { |
|
||||
for (let i = 0; i < this.journeys.length; i++) { |
|
||||
if (this.journeys[i].value === evt.target.value) { |
|
||||
this.journeyType = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 同意协议 |
|
||||
changeIntentions(data) { |
|
||||
this.agree = data; |
|
||||
}, |
|
||||
changeIntentions1(data) { |
|
||||
this.agree1 = data; |
|
||||
}, |
|
||||
changeIntentions2(data) { |
|
||||
this.agree2 = data; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 获取出发时间 |
|
||||
* @param {string} start 开始时间 |
|
||||
* @param {string} end 截止时间 |
|
||||
*/ |
|
||||
getStartData(start) { |
|
||||
console.log('出发时间 start: ', start); |
|
||||
this.startTime = start; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 获取抵达时间 |
|
||||
* @param {string} start 开始时间 |
|
||||
* @param {string} end 截止时间 |
|
||||
*/ |
|
||||
getEndData(end) { |
|
||||
console.log('抵达时间 end: ', end); |
|
||||
this.endTime = end; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 添加行程 |
|
||||
*/ |
|
||||
async handleAddStroke() { |
|
||||
try { |
|
||||
if (!this.checkRules()) return; |
|
||||
const { |
|
||||
carNo, |
|
||||
endTime, |
|
||||
journeyType, |
|
||||
startTime, |
|
||||
together, |
|
||||
tripMode, |
|
||||
agree1, |
|
||||
agree2, |
|
||||
} = this; |
|
||||
const params = { |
|
||||
param: { |
|
||||
carNo, |
|
||||
endTime: +this.$moment(endTime).format('x'), |
|
||||
journeyType: journeyType+1, |
|
||||
startTime: +this.$moment(startTime).format('x'), |
|
||||
together, |
|
||||
tripMode, |
|
||||
healthAgreement: agree1 ? 1 : 0, |
|
||||
selfFill: agree2 ? 1 : 0, |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
const res = await this.$http.post(SUBMIT_JOURNEYS, params); |
|
||||
const { |
|
||||
success, |
|
||||
code, |
|
||||
msg, |
|
||||
data |
|
||||
} = res.data; |
|
||||
if (success && code === 200) { |
|
||||
uni.showToast({ |
|
||||
title: '行程添加成功', |
|
||||
duration: 2000 |
|
||||
}); |
|
||||
this.success = true; |
|
||||
uni.reLaunch({ |
|
||||
url: `/pages/index/index`, |
|
||||
}); |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: msg || '行程添加失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
if (error.msg) { |
|
||||
uni.showToast({ |
|
||||
title: error.msg || '行程添加失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 验证信息 |
|
||||
checkRules() { |
|
||||
const { startTime,endTime,journeyType,tripMode,carNo,agree,agree1,agree2 } = this; |
|
||||
if (!this.startTime) { |
|
||||
showToast('请选择出发时间'); |
|
||||
return; |
|
||||
} |
|
||||
if (!this.endTime) { |
|
||||
showToast('请选择抵达时间'); |
|
||||
return; |
|
||||
} |
|
||||
if (this.startTime >= this.endTime){ |
|
||||
showToast('开始时间不能和抵达时间相同或者晚于抵达时间'); |
|
||||
return; |
|
||||
} |
|
||||
if (this.journeyType<0) { |
|
||||
showToast('请选择行程类型'); |
|
||||
return; |
|
||||
} |
|
||||
if (this.tripMode<0) { |
|
||||
showToast('请选择出行交通方式'); |
|
||||
return; |
|
||||
} |
|
||||
if (!this.carNo) { |
|
||||
showToast('乘坐航班车次或车牌号码及座位号'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree) { |
|
||||
showToast('请选择是否同意《用户服务协议》和《隐私政策》'); |
|
||||
return; |
|
||||
} |
|
||||
if (!this.agree1) { |
|
||||
showToast('请选择是否同意信息提交山西大学管理'); |
|
||||
return; |
|
||||
} |
|
||||
if (!this.agree2) { |
|
||||
showToast('请确定是否为本人填写'); |
|
||||
return; |
|
||||
} |
|
||||
return true; |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.agree-box{ |
|
||||
width: 70rpx; |
|
||||
} |
|
||||
.agree-text{ |
|
||||
line-height: 60rpx; |
|
||||
} |
|
||||
.primary-btn{ |
|
||||
border-radius: 15rpx; |
|
||||
} |
|
||||
.history-btn{ |
|
||||
position: fixed; |
|
||||
bottom: 40rpx; |
|
||||
right: 40rpx; |
|
||||
width: 96rpx; |
|
||||
height: 96rpx; |
|
||||
line-height: 96rpx; |
|
||||
padding: 0; |
|
||||
} |
|
||||
.history-btn::after{ |
|
||||
border: none; |
|
||||
} |
|
||||
</style> |
|
@ -1,73 +0,0 @@ |
|||||
<template> |
|
||||
<view class="date-bg"> |
|
||||
<view hover-class="cc-active"> |
|
||||
<view class="iconfont icon-calendar timer"><text class="padding-left-xs">{{ endDate }}</text></view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="startTime"> |
|
||||
<ruiDatePicker |
|
||||
fields="minute" |
|
||||
start="2010-01-01 00:00" |
|
||||
end="2030-12-30 23:59" |
|
||||
:value="valueEnd" |
|
||||
@change="bindChangeEnd" |
|
||||
class="rui-date-picker" |
|
||||
></ruiDatePicker> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import ruiDatePicker from 'components/rattenking-dtpicker/rattenking-dtpicker.vue'; |
|
||||
|
|
||||
export default { |
|
||||
name: 'EndDateSelector', |
|
||||
components: {ruiDatePicker}, |
|
||||
|
|
||||
data() { |
|
||||
return { |
|
||||
valueEnd: this.$moment(new Date()).format('YYYY-MM-DD HH:mm') |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: { |
|
||||
endDate() { |
|
||||
const { |
|
||||
valueEnd |
|
||||
} = this; |
|
||||
return valueEnd; |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
bindChangeEnd(value){ |
|
||||
// console.log('抵达时间',value) |
|
||||
this.valueEnd = value; |
|
||||
this.$emit('change', this.valueEnd); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.timer { |
|
||||
font-size: 34rpx !important; |
|
||||
color: $gray; |
|
||||
} |
|
||||
|
|
||||
.date-bg{ |
|
||||
position: relative; |
|
||||
} |
|
||||
|
|
||||
.startTime{ |
|
||||
opacity: 0; |
|
||||
position: absolute; |
|
||||
top: -14rpx; |
|
||||
left: 50rpx; |
|
||||
} |
|
||||
|
|
||||
.rui-date-picker{ |
|
||||
text-indent: 12em; |
|
||||
} |
|
||||
</style> |
|
@ -1,73 +0,0 @@ |
|||||
<template> |
|
||||
<view class="date-bg"> |
|
||||
<view hover-class="cc-active"> |
|
||||
<view class="iconfont icon-calendar timer"><text class="padding-left-xs">{{ startDate }}</text></view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="startTime"> |
|
||||
<ruiDatePicker |
|
||||
fields="minute" |
|
||||
start="2010-01-01 00:00" |
|
||||
end="2030-12-30 23:59" |
|
||||
:value="valueStart" |
|
||||
@change="bindChangeStart" |
|
||||
class="rui-date-picker" |
|
||||
></ruiDatePicker> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import ruiDatePicker from 'components/rattenking-dtpicker/rattenking-dtpicker.vue'; |
|
||||
|
|
||||
export default { |
|
||||
name: 'StartDateSelector', |
|
||||
components: {ruiDatePicker}, |
|
||||
|
|
||||
data() { |
|
||||
return { |
|
||||
valueStart: this.$moment(new Date()).format('YYYY-MM-DD HH:mm') |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: { |
|
||||
startDate() { |
|
||||
const { |
|
||||
valueStart |
|
||||
} = this; |
|
||||
return valueStart; |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
bindChangeStart(value){ |
|
||||
// console.log('抵达时间',value) |
|
||||
this.valueStart = value; |
|
||||
this.$emit('change', this.valueStart); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.timer { |
|
||||
font-size: 34rpx !important; |
|
||||
color: $gray; |
|
||||
} |
|
||||
|
|
||||
.date-bg{ |
|
||||
position: relative; |
|
||||
} |
|
||||
|
|
||||
.startTime{ |
|
||||
opacity: 0; |
|
||||
position: absolute; |
|
||||
top: -14rpx; |
|
||||
left: 50rpx; |
|
||||
} |
|
||||
|
|
||||
.rui-date-picker{ |
|
||||
text-indent: 12em; |
|
||||
} |
|
||||
</style> |
|
@ -1,489 +0,0 @@ |
|||||
<template> |
|
||||
<view> |
|
||||
<form class="padding-lr cu-form-group flex-direction"> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs">*</span>当前所在地区 |
|
||||
</view> |
|
||||
<view class="flex align-center"> |
|
||||
<input @tap="handleSelectLocation" class="flex-sub padding-left-xs" name="input" placeholder="请选择当前所在地区" type="btn" |
|
||||
v-model="district" maxlength="128" /> |
|
||||
<text class="cuIcon-location timer"></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs">*</span>当前所在详细地址 |
|
||||
</view> |
|
||||
<input name="input" placeholder="请输入详细地址(含门牌号)" type="text" v-model="address" maxlength="128" /> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs">*</span>当前状态 |
|
||||
</view> |
|
||||
<radio-group @change="StateChange" class="block"> |
|
||||
<view class="cu-list menu text-left"> |
|
||||
<view :key="index" class="cu-item" v-for="(state,index) in status"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio :checked="index === healthTypeId" :value="state.id" class="round margin-right-xs"></radio> |
|
||||
<view class="flex-sub" style="font-size: 34rpx;">{{ state.name }}</view> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm">就诊医院(若无填无)</view> |
|
||||
<input name="input" placeholder="请输入就诊医院" type="text" v-model="hospital" maxlength="32" /> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>最近14天是否有武汉居住史、旅游史或武汉亲戚来访</view> |
|
||||
<radio-group @change="TourChange" class="block"> |
|
||||
<view class="flex"> |
|
||||
<view :key="index" class="flex-sub margin-tb-sm" v-for="(tour,index) in tours"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio :checked="index === touchHubei" :value="tour.value" class="round margin-right-xs"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ tour.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>最近14天是否有新冠肺炎患者或疑似患者接触史</view> |
|
||||
<radio-group @change="TouchChange" class="block"> |
|
||||
<view class="flex"> |
|
||||
<view :key="index" class="flex-sub margin-tb-sm" v-for="(touch,index) in touches"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio :checked="index === touchSick" :value="touch.value" class="round margin-right-xs"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ touch.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>最近14天有无接触过近期境外返回人员</view> |
|
||||
<radio-group class="block" @change="TouchOverseasChange"> |
|
||||
<view class="flex"> |
|
||||
<view class="flex-sub margin-tb-sm" v-for="(touch,index) in overseas" :key="index"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === touchOverseas" :value="touch.value"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ touch.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>是否在学校所在地</view> |
|
||||
<radio-group class="block" @change="SchoolLocationChange"> |
|
||||
<view class="flex"> |
|
||||
<view class="flex-sub margin-tb-sm" v-for="(location,index) in locations" :key="location.value"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === schoolLocation" :value="location.value"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ location.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>当前体温(℃)</view> |
|
||||
<input placeholder="0" name="input" type="digit" v-model="animalHeat" /> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm">紧急联系人</view> |
|
||||
<view class="flex"> |
|
||||
<input placeholder="姓名" maxlength="6" class="flex flex-sub" name="input" type="text" v-model="emergencyName" /> |
|
||||
<input placeholder="联系方式" maxlength="11" class="flex flex-sub" name="input" type="number" v-model="emergencyPhone" /> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm">备注(选填)</view> |
|
||||
<textarea placeholder="请填写具体情况..." name="input" v-model="remark" /> |
|
||||
|
|
||||
<!-- 上传图片 --> |
|
||||
<view class="grid col-4 grid-square flex-sub"> |
|
||||
<view class="bg-img" v-for="(item,index) in imgList" :key="index" @tap="ViewImage" :data-url="imgList[index]"> |
|
||||
<image :src="imgList[index]" mode="aspectFill"></image> |
|
||||
<view class="cu-tag bg-red" @tap.stop="DelImg" :data-index="index"> |
|
||||
<text class='cuIcon-close'></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="solids" @tap="ChooseImage" v-if="imgList.length<9"> |
|
||||
<text class='cuIcon-cameraadd'></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
</form> |
|
||||
<user-agreement @changeIntentions="changeIntentions" @changeIntentions1="changeIntentions1" @changeIntentions2="changeIntentions2"></user-agreement> |
|
||||
<button @tap="handleHealthSign" class="bg-cyan margin primary-btn" hover-class="cc-active">确认提交</button> |
|
||||
<!-- 历史 --> |
|
||||
<button |
|
||||
@tap="openPage('/pages/my-code/my-code')" |
|
||||
class="shadow round bg-cyan history-btn iconfont icon-history" |
|
||||
hover-class="cc-active" |
|
||||
></button> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { showToast } from 'common/script/util'; |
|
||||
import { HEALTH_SIGN, HEALTH_FILE } from 'api/api'; |
|
||||
import { mapState, mapMutations } from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
district: '请选择当前所在地区', |
|
||||
address: '', |
|
||||
// status: [], |
|
||||
hospital: '', |
|
||||
tours: [ |
|
||||
{ |
|
||||
value: '0', |
|
||||
name: '否', |
|
||||
}, |
|
||||
{ |
|
||||
value: '1', |
|
||||
name: '是', |
|
||||
}, |
|
||||
], |
|
||||
touches: [ |
|
||||
{ |
|
||||
value: '0', |
|
||||
name: '否', |
|
||||
}, |
|
||||
{ |
|
||||
value: '1', |
|
||||
name: '是', |
|
||||
}, |
|
||||
], |
|
||||
overseas: [{ |
|
||||
value: '0', |
|
||||
name: '无' |
|
||||
}, { |
|
||||
value: '1', |
|
||||
name: '有' |
|
||||
}], |
|
||||
locations: [{ |
|
||||
value: '0', |
|
||||
name: '否' |
|
||||
}, { |
|
||||
value: '1', |
|
||||
name: '是' |
|
||||
}], |
|
||||
animalHeat: '', |
|
||||
healthTypeId: 0, |
|
||||
touchHubei: 0, |
|
||||
touchSick: 0, |
|
||||
touchOverseas: 0, |
|
||||
schoolLocation: 1, |
|
||||
emergencyName: '', |
|
||||
emergencyPhone: '', |
|
||||
remark: '', |
|
||||
fileIdList: [], |
|
||||
imgList: [], |
|
||||
agree: false, |
|
||||
agree1: false, |
|
||||
agree2: false, |
|
||||
}; |
|
||||
}, |
|
||||
computed: mapState('user', ['token', 'status']), |
|
||||
|
|
||||
methods: { |
|
||||
...mapMutations('user', ['setHealthCode']), |
|
||||
handleSelectLocation() { |
|
||||
const that = this; |
|
||||
uni.chooseLocation({ |
|
||||
success: function(res) { |
|
||||
console.log('位置名称:' + res.name); |
|
||||
console.log('详细地址:' + res.address); |
|
||||
that.district = res.address; |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
changeIntentions(data) { |
|
||||
this.agree = data; |
|
||||
}, |
|
||||
changeIntentions1(data) { |
|
||||
this.agree1 = data; |
|
||||
}, |
|
||||
changeIntentions2(data) { |
|
||||
this.agree2 = data; |
|
||||
}, |
|
||||
|
|
||||
// 状态 |
|
||||
StateChange: function(evt) { |
|
||||
for (let i = 0; i < this.status.length; i++) { |
|
||||
if (this.status[i].id === evt.target.value) { |
|
||||
this.healthTypeId = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 旅游 |
|
||||
TourChange: function(evt) { |
|
||||
for (let i = 0; i < this.tours.length; i++) { |
|
||||
if (this.tours[i].value === evt.target.value) { |
|
||||
this.touchHubei = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 接触 |
|
||||
TouchChange(evt) { |
|
||||
for (let b = 0; b < this.touches.length; b++) { |
|
||||
if (this.touches[b].value === evt.target.value) { |
|
||||
this.touchSick = b; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 境外 |
|
||||
TouchOverseasChange(evt) { |
|
||||
for (let i = 0; i < this.overseas.length; i++) { |
|
||||
if (this.overseas[i].value === evt.target.value) { |
|
||||
this.touchOverseas = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 学校所在地 |
|
||||
SchoolLocationChange(evt) { |
|
||||
for (let i = 0; i < this.locations.length; i++) { |
|
||||
if (this.locations[i].value === evt.target.value) { |
|
||||
this.schoolLocation = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
ChooseImage() { |
|
||||
uni.chooseImage({ |
|
||||
count: 1, //默认9 |
|
||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 |
|
||||
sourceType: ['album', 'camera'], //从相册选择 |
|
||||
success: (res) => { |
|
||||
if (this.imgList.length != 0) { |
|
||||
this.imgList = this.imgList.concat(res.tempFilePaths) |
|
||||
} else { |
|
||||
this.imgList = res.tempFilePaths |
|
||||
} |
|
||||
uni.uploadFile({ |
|
||||
url: `https://www.tall.wiki/gateway${HEALTH_FILE}`, |
|
||||
// url: `https://test.tall.wiki/gateway${HEALTH_FILE}`, |
|
||||
filePath: res.tempFilePaths[0], |
|
||||
fileType: 'image', |
|
||||
name: 'file', |
|
||||
success: (res) => { |
|
||||
const resData = JSON.parse(res.data) |
|
||||
const { |
|
||||
success, |
|
||||
code, |
|
||||
msg, |
|
||||
data |
|
||||
} = resData; |
|
||||
this.fileIdList.splice(-1,0,resData.data.fileId); |
|
||||
uni.showToast({ |
|
||||
title: '图片提交成功', |
|
||||
duration: 1000, |
|
||||
}); |
|
||||
},fail: (err) => { |
|
||||
console.log('uploadImage fail', err); |
|
||||
uni.showModal({ |
|
||||
content: err.errMsg, |
|
||||
showCancel: false |
|
||||
}); |
|
||||
} |
|
||||
}); |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
ViewImage(e) { |
|
||||
uni.previewImage({ |
|
||||
urls: this.imgList, |
|
||||
current: e.currentTarget.dataset.url |
|
||||
}); |
|
||||
}, |
|
||||
DelImg(e) { |
|
||||
uni.showModal({ |
|
||||
title: '删除', |
|
||||
content: '确定要删除这张图片吗?', |
|
||||
cancelText: '再想想', |
|
||||
confirmText: '再见', |
|
||||
success: res => { |
|
||||
if (res.confirm) { |
|
||||
this.imgList.splice(e.currentTarget.dataset.index, 1) |
|
||||
this.fileIdList.splice(e.currentTarget.dataset.index, 1) |
|
||||
} |
|
||||
} |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 申请健康码 |
|
||||
*/ |
|
||||
async handleHealthSign() { |
|
||||
try { |
|
||||
if (!this.checkRules()) return; |
|
||||
|
|
||||
const { |
|
||||
address, |
|
||||
animalHeat, |
|
||||
district, |
|
||||
healthTypeId, |
|
||||
hospital, |
|
||||
token, |
|
||||
touchHubei, |
|
||||
touchSick, |
|
||||
touchOverseas, |
|
||||
schoolLocation, |
|
||||
emergencyName, |
|
||||
emergencyPhone, |
|
||||
remark, |
|
||||
fileIdList, |
|
||||
agree1, |
|
||||
agree2, |
|
||||
} = this; |
|
||||
const params = { |
|
||||
param: { |
|
||||
address, |
|
||||
animalHeat, |
|
||||
district, |
|
||||
healthTypeId: healthTypeId + 1, |
|
||||
hospital, |
|
||||
token, |
|
||||
touchHubei, |
|
||||
touchSick, |
|
||||
touchOverseas, |
|
||||
schoolLocation, |
|
||||
emergencyName, |
|
||||
emergencyPhone, |
|
||||
remark, |
|
||||
fileIdList, |
|
||||
healthAgreement: agree1 ? 1 : 0, |
|
||||
selfFill: agree2 ? 1 : 0, |
|
||||
}, |
|
||||
}; |
|
||||
const res = await this.$http.post(HEALTH_SIGN, params); |
|
||||
const { success, code, msg, data } = res.data; |
|
||||
if (success && code === 200) { |
|
||||
uni.showToast({ |
|
||||
title: '申请健康码成功', |
|
||||
duration: 2000, |
|
||||
}); |
|
||||
this.success = true; |
|
||||
this.setHealthCode(data.healthCode); |
|
||||
uni.reLaunch({ |
|
||||
url: `/pages/index/index`, |
|
||||
}); |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: msg || '申请健康码失败', |
|
||||
icon: 'none', |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
if (error.msg) { |
|
||||
uni.showToast({ |
|
||||
title: error.msg || '申请健康码失败', |
|
||||
icon: 'none', |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 验证信息 |
|
||||
checkRules() { |
|
||||
const { district, address, healthTypeId, animalHeat, agree,agree1,agree2 } = this; |
|
||||
if (!district || district === '请选择当前所在地区') { |
|
||||
showToast('请选择当前所在地区'); |
|
||||
return; |
|
||||
} |
|
||||
if (!address) { |
|
||||
showToast('请输入当前所在地址'); |
|
||||
return; |
|
||||
} |
|
||||
if (healthTypeId < 0) { |
|
||||
showToast('请选择状态'); |
|
||||
return; |
|
||||
} |
|
||||
if (!animalHeat || animalHeat<30 || animalHeat>45) { |
|
||||
showToast('请输入正确的体温值(范围:30℃~45℃)'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree) { |
|
||||
showToast('请选择是否同意《用户服务协议》和《隐私政策》'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree1) { |
|
||||
showToast('请选择是否同意信息提交山西大学管理'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree2) { |
|
||||
showToast('请确定是否为本人填写'); |
|
||||
return; |
|
||||
} |
|
||||
return true; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 验证手机号格式 |
|
||||
* @param {string} phone 手机号 |
|
||||
*/ |
|
||||
verifyPhone(phone) { |
|
||||
const phoneExg = /^1\d{10}$/; |
|
||||
return phoneExg.test(phone); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.agree-box { |
|
||||
width: 70rpx; |
|
||||
} |
|
||||
|
|
||||
.agree-text { |
|
||||
line-height: 60rpx; |
|
||||
} |
|
||||
|
|
||||
.timer { |
|
||||
font-size: 34rpx !important; |
|
||||
color: $gray; |
|
||||
} |
|
||||
|
|
||||
.primary-btn { |
|
||||
border-radius: 15rpx; |
|
||||
} |
|
||||
|
|
||||
.history-btn { |
|
||||
position: fixed; |
|
||||
bottom: 40rpx; |
|
||||
right: 40rpx; |
|
||||
width: 96rpx; |
|
||||
height: 96rpx; |
|
||||
line-height: 96rpx; |
|
||||
padding: 0; |
|
||||
} |
|
||||
|
|
||||
.history-btn::after { |
|
||||
border: none; |
|
||||
} |
|
||||
</style> |
|
@ -1,281 +0,0 @@ |
|||||
<template> |
|
||||
<view> |
|
||||
<form class="padding-lr cu-form-group flex-direction"> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs" v-show="!(userInfo && userInfo.id)">*</span>姓名 |
|
||||
</view> |
|
||||
<input |
|
||||
:disabled="userInfo && userInfo.id ? true : false" |
|
||||
name="input" |
|
||||
placeholder="请输入真实姓名" |
|
||||
type="text" |
|
||||
v-model="name" |
|
||||
maxlength="6" |
|
||||
/> |
|
||||
</view> |
|
||||
<!-- <view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs" v-show="!(userInfo && userInfo.id)">*</span>身份证 |
|
||||
</view> |
|
||||
<input |
|
||||
:disabled="userInfo && userInfo.id ? true : false" |
|
||||
name="input" |
|
||||
placeholder="请输入身份证号" |
|
||||
type="idcard" |
|
||||
v-model="idCard" |
|
||||
maxlength="18" |
|
||||
/> |
|
||||
</view> --> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs" v-show="!(userInfo && userInfo.id)">*</span>联系方式 |
|
||||
</view> |
|
||||
<input |
|
||||
:disabled="userInfo && userInfo.id ? true : false" |
|
||||
name="input" |
|
||||
placeholder="请输入手机号码" |
|
||||
type="number" |
|
||||
v-model="phone" |
|
||||
maxlength="11" |
|
||||
/> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs" v-show="!(userInfo && userInfo.id)">*</span>身份 |
|
||||
</view> |
|
||||
<radio-group @change="RadioChange" class="block" v-if="!(userInfo && userInfo.id)"> |
|
||||
<view class="flex"> |
|
||||
<view :key="index" class="flex-sub margin-tb-sm" v-for="(identity, index) in identitys"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio |
|
||||
:checked="index === current" |
|
||||
:value="identity.value" |
|
||||
class="round margin-right-xs" |
|
||||
></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ identity.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
<input |
|
||||
:value="current === 0 ? '学生' : current === 1 ? '教师' : '工作人员'" |
|
||||
disabled |
|
||||
name="input" |
|
||||
type="text" |
|
||||
v-else |
|
||||
/> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs" v-show="!(userInfo && userInfo.id)">*</span>学号/工号 |
|
||||
</view> |
|
||||
<input |
|
||||
:disabled="userInfo && userInfo.id ? true : false" |
|
||||
name="input" |
|
||||
placeholder="请输入学号/工号" |
|
||||
type="text" |
|
||||
v-model="studentID" |
|
||||
maxlength="16" |
|
||||
/> |
|
||||
</view> |
|
||||
</form> |
|
||||
<user-agreement @changeIntentions="changeIntentions" @changeIntentions1="changeIntentions1" @changeIntentions2="changeIntentions2" v-if="!(userInfo && userInfo.id)"></user-agreement> |
|
||||
<view v-if="!(userInfo && userInfo.id)" class="flex text-df margin-bottom margin-lr agree-text"> |
|
||||
微信小程序和企业微信应用同时实名后,可以绑定微信小程序帐号和企业微信应用帐号,方便操作 |
|
||||
</view> |
|
||||
|
|
||||
<button |
|
||||
@tap="handleSubmitUserInfo" |
|
||||
class="bg-cyan margin primary-btn" |
|
||||
hover-class="cc-active" |
|
||||
v-show="!(userInfo && userInfo.id)" |
|
||||
>确认提交</button> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { showToast } from 'common/script/util'; |
|
||||
import { SUBMIT_USER_INFO } from 'api/api'; |
|
||||
import { mapState, mapMutations } from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
name: '', |
|
||||
// idCard: '', |
|
||||
phone: '', |
|
||||
identitys: [ |
|
||||
{ |
|
||||
value: '0', |
|
||||
name: '学生', |
|
||||
}, |
|
||||
{ |
|
||||
value: '1', |
|
||||
name: '教师', |
|
||||
}, |
|
||||
{ |
|
||||
value: '2', |
|
||||
name: '工作人员', |
|
||||
}, |
|
||||
], |
|
||||
studentID: '', |
|
||||
current: 0, |
|
||||
agree: false, |
|
||||
agree1: false, |
|
||||
agree2: false |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
created() { |
|
||||
if (this.userInfo) { |
|
||||
this.name = this.userInfo.name; |
|
||||
// this.idCard = this.userInfo.idCard; |
|
||||
this.phone = this.userInfo.phone; |
|
||||
this.studentID = this.userInfo.no; |
|
||||
this.current = this.userInfo.post; |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
computed: mapState('user', ['userInfo', 'pagePath']), |
|
||||
|
|
||||
methods: { |
|
||||
...mapMutations('user', ['setUserInfo']), |
|
||||
RadioChange: function(evt) { |
|
||||
for (let i = 0; i < this.identitys.length; i++) { |
|
||||
if (this.identitys[i].value === evt.target.value) { |
|
||||
this.current = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
changeIntentions(data) { |
|
||||
this.agree = data; |
|
||||
}, |
|
||||
changeIntentions1(data) { |
|
||||
this.agree1 = data; |
|
||||
}, |
|
||||
changeIntentions2(data) { |
|
||||
this.agree2 = data; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 提交基本信息 |
|
||||
*/ |
|
||||
async handleSubmitUserInfo() { |
|
||||
try { |
|
||||
if (!this.checkRules()) return; |
|
||||
|
|
||||
const { name, phone, studentID, current, pagePath } = this; |
|
||||
const params = { |
|
||||
param: { |
|
||||
// idCard, |
|
||||
name, |
|
||||
no: studentID, |
|
||||
phone, |
|
||||
post: current, |
|
||||
}, |
|
||||
}; |
|
||||
|
|
||||
const res = await this.$http.post(SUBMIT_USER_INFO, params); |
|
||||
const { success, code, msg, data } = res.data; |
|
||||
if (success && code === 200) { |
|
||||
uni.showToast({ |
|
||||
title: '基本信息提交成功', |
|
||||
duration: 2000, |
|
||||
}); |
|
||||
this.success = true; |
|
||||
this.setUserInfo(data); |
|
||||
if (pagePath === '/pages/basic-info/basic-info') { |
|
||||
uni.reLaunch({ |
|
||||
url: `/pages/index/index`, |
|
||||
}); |
|
||||
} else { |
|
||||
uni.redirectTo({ url: pagePath }); |
|
||||
} |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: msg || '基本信息提交失败', |
|
||||
icon: 'none', |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
if (error.msg) { |
|
||||
uni.showToast({ |
|
||||
title: error.msg || '基本信息提交失败', |
|
||||
icon: 'none', |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 验证信息 |
|
||||
checkRules() { |
|
||||
const { name, phone, identitys, studentID, agree,agree1,agree2 } = this; |
|
||||
if (!name) { |
|
||||
showToast('请输入姓名'); |
|
||||
return; |
|
||||
} |
|
||||
// if (!this.verifyIdCard(idCard)) { |
|
||||
// showToast('请输入正确的身份证号'); |
|
||||
// return; |
|
||||
// } |
|
||||
if (!this.verifyPhone(phone)) { |
|
||||
showToast('请输入正确的手机号'); |
|
||||
return false; |
|
||||
} |
|
||||
if (!identitys) { |
|
||||
showToast('请选择身份'); |
|
||||
return; |
|
||||
} |
|
||||
if (!studentID) { |
|
||||
showToast('请输入学号/工号'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree) { |
|
||||
showToast('请选择是否同意《用户服务协议》和《隐私政策》'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree1) { |
|
||||
showToast('请选择是否同意信息提交山西大学管理'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree2) { |
|
||||
showToast('请确定是否为本人填写'); |
|
||||
return; |
|
||||
} |
|
||||
return true; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 验证手机号格式 |
|
||||
* @param {string} phone 手机号 |
|
||||
*/ |
|
||||
verifyPhone(phone) { |
|
||||
const phoneExg = /^1\d{10}$/; |
|
||||
return phoneExg.test(phone); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 验证身份证号格式 |
|
||||
* @param {string} idCard 身份证号 |
|
||||
*/ |
|
||||
// verifyIdCard(idCard) { |
|
||||
// const idCardExg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; |
|
||||
// return idCardExg.test(idCard); |
|
||||
// }, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.primary-btn { |
|
||||
border-radius: 15rpx; |
|
||||
} |
|
||||
|
|
||||
.agree-text { |
|
||||
line-height: 60rpx; |
|
||||
} |
|
||||
</style> |
|
@ -1,238 +0,0 @@ |
|||||
<template> |
|
||||
<view> |
|
||||
<form class="padding-lr cu-form-group flex-direction"> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>当前所在地区</view> |
|
||||
<input placeholder="请输入当前所在地区" name="input" type="text" v-model="area" /> |
|
||||
<button @tap="handleSelectLocation">选择位置</button> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>当前所在详细地址</view> |
|
||||
<input placeholder="请输入详细地址(含门牌号)" name="input" type="text" v-model="address" /> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>当前状态</view> |
|
||||
<radio-group class="block" @change="StateChange"> |
|
||||
<view class="cu-list menu text-left"> |
|
||||
<view class="cu-item" v-for="(state,index) in status" :key="index"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === current" :value="state.value"></radio> |
|
||||
<view class="flex-sub" style="font-size: 34rpx;">{{ state.name }}</view> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm">就诊医院(若无填无)</view> |
|
||||
<input placeholder="请输入就诊医院" name="input" type="text" v-model="hospital" /> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm">最近14天是否有武汉居住史、旅游史或武汉亲戚来访</view> |
|
||||
<radio-group class="block" @change="TourChange"> |
|
||||
<view class="flex"> |
|
||||
<view class="flex-sub margin-tb-sm" v-for="(tour,index) in tours" :key="index"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === tourCurrent" :value="tour.value"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ tour.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm">最近14天是否有新冠肺炎患者或疑似患者接触史</view> |
|
||||
<radio-group class="block" @change="TouchChange"> |
|
||||
<view class="flex"> |
|
||||
<view class="flex-sub margin-tb-sm" v-for="(touch,index) in touches" :key="index"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === touchCurrent" :value="touch.value"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ touch.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>当前体温(℃)</view> |
|
||||
<input placeholder="请输入当前真实体温" name="input" type="number" v-model="temperature" /> |
|
||||
</view> |
|
||||
</form> |
|
||||
|
|
||||
<view class="margin flex flex-wrap"> |
|
||||
<view @click="agree = !agree" class="iconfont agree-box" :class="[agree ? 'text-blue icon-check-square': 'text-gray icon-border']"></view> |
|
||||
<view class="text-df text-black flex-sub agree-text"> |
|
||||
以上信息是我本人填写,本人对信息的真实性和完整性负责。 |
|
||||
</view> |
|
||||
</view> |
|
||||
<button class="bg-cyan margin primary-btn" hover-class="cc-active" @tap="addStroke">确认提交</button> |
|
||||
<!-- 历史 --> |
|
||||
<button class="shadow round bg-cyan history-btn iconfont icon-history" hover-class="cc-active" @tap="openPage('/pages/my-code/my-code')"></button> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { showToast } from 'common/script/util'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
area: '', |
|
||||
address: '', |
|
||||
status: [ |
|
||||
{ |
|
||||
value: '0', |
|
||||
name: '正常', |
|
||||
}, |
|
||||
{ |
|
||||
value: '1', |
|
||||
name: '发烧(377.3度以上)', |
|
||||
}, |
|
||||
{ |
|
||||
value: '2', |
|
||||
name: '咳嗽', |
|
||||
}, |
|
||||
{ |
|
||||
value: '3', |
|
||||
name: '咽喉疼痛', |
|
||||
}, |
|
||||
{ |
|
||||
value: '4', |
|
||||
name: '流鼻涕', |
|
||||
}, |
|
||||
{ |
|
||||
value: '5', |
|
||||
name: '头痛', |
|
||||
}, |
|
||||
{ |
|
||||
value: '6', |
|
||||
name: '其他', |
|
||||
} |
|
||||
], |
|
||||
hospital: '', |
|
||||
tours: [ |
|
||||
{ |
|
||||
value: 1, |
|
||||
name: '是' |
|
||||
}, |
|
||||
{ |
|
||||
value: 0, |
|
||||
name: '否' |
|
||||
} |
|
||||
], |
|
||||
touches: [ |
|
||||
{ |
|
||||
value: 1, |
|
||||
name: '是' |
|
||||
}, |
|
||||
{ |
|
||||
value: 0, |
|
||||
name: '否' |
|
||||
} |
|
||||
], |
|
||||
temperature: '', |
|
||||
current: 0, |
|
||||
tourCurrent: 0, |
|
||||
touchCurrent: 0, |
|
||||
agree: false, |
|
||||
}; |
|
||||
}, |
|
||||
methods: { |
|
||||
handleSelectLocation() { |
|
||||
uni.chooseLocation({ |
|
||||
success: function(res) { |
|
||||
console.log('位置名称:' + res.name); |
|
||||
console.log('详细地址:' + res.address); |
|
||||
console.log('纬度:' + res.latitude); |
|
||||
console.log('经度:' + res.longitude); |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 状态 |
|
||||
StateChange: function(evt) { |
|
||||
for (let i = 0; i < this.status.length; i++) { |
|
||||
if (this.status[i].value === evt.target.value) { |
|
||||
this.current = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 旅游 |
|
||||
TourChange: function(evt) { |
|
||||
for (let i = 0; i < this.tours.length; i++) { |
|
||||
if (this.tours[i].value === evt.target.value) { |
|
||||
this.tourCurrent = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 接触 |
|
||||
TouchChange: function(evt) { |
|
||||
for (let i = 0; i < this.touches.length; i++) { |
|
||||
if (this.touches[i].value === evt.target.value) { |
|
||||
this.touchCurrent = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 提交基本信息 |
|
||||
*/ |
|
||||
addStroke() { |
|
||||
if (!this.area) { |
|
||||
showToast('请输入当前所在地区'); |
|
||||
return; |
|
||||
} |
|
||||
if (!this.address) { |
|
||||
showToast('请输入当前所在地址'); |
|
||||
return; |
|
||||
} |
|
||||
if (!this.status) { |
|
||||
showToast('请选择状态'); |
|
||||
return; |
|
||||
} |
|
||||
if (!this.temperature) { |
|
||||
showToast('请输入当前体温'); |
|
||||
return; |
|
||||
} |
|
||||
if (!this.agree) { |
|
||||
showToast('请确定是否为本人填写'); |
|
||||
return; |
|
||||
} |
|
||||
uni.reLaunch({ |
|
||||
url: `/pages/index/index`, |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.agree-box{ |
|
||||
width: 70rpx; |
|
||||
} |
|
||||
.agree-text{ |
|
||||
line-height: 60rpx; |
|
||||
} |
|
||||
.primary-btn{ |
|
||||
border-radius: 15rpx; |
|
||||
} |
|
||||
.history-btn{ |
|
||||
position: fixed; |
|
||||
bottom: 40rpx; |
|
||||
right: 40rpx; |
|
||||
width: 96rpx; |
|
||||
height: 96rpx; |
|
||||
line-height: 96rpx; |
|
||||
padding: 0; |
|
||||
} |
|
||||
.history-btn::after{ |
|
||||
border: none; |
|
||||
} |
|
||||
</style> |
|
@ -1,175 +0,0 @@ |
|||||
<template> |
|
||||
<view class="content flex flex-direction"> |
|
||||
<view v-if="healthCode" style="position: relative;"> |
|
||||
<image |
|
||||
src="/static/img/shanda2.png" |
|
||||
class="bg1" |
|
||||
></image> |
|
||||
<view class="bg-code" @click="getPreviewImg(healthCode)"> |
|
||||
<view class="healthy-code-bg shadow-lg"> |
|
||||
<image class="healthy-code" :src="healthCode"></image> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<image |
|
||||
v-else |
|
||||
src="/static/img/shanda1.png" |
|
||||
class="bg" |
|
||||
></image> |
|
||||
|
|
||||
<view :class="healthCode ? 'box1' : 'box'"> |
|
||||
<view |
|
||||
@tap="openPage('/pages/apply-code/apply-code')" |
|
||||
class="cu-card flex margin bg-white shadow card-radius" |
|
||||
hover-class="cc-active" |
|
||||
v-show="!healthCode" |
|
||||
> |
|
||||
<view class="flex align-center padding"> |
|
||||
<view class="round lg cu-avatar icon1"> |
|
||||
<view class="iconfont icon-qrcode"></view> |
|
||||
</view> |
|
||||
<view class="padding-left-sm flex-sub"> |
|
||||
<view class="text-xl">领取健康码</view> |
|
||||
<view class="text-df padding-top-xs description">领取健康码,查看健康状态</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view |
|
||||
@tap="openPage('/pages/punch-the-clock/punch-the-clock')" |
|
||||
class="cu-card flex margin bg-white shadow card-radius" |
|
||||
hover-class="cc-active" |
|
||||
> |
|
||||
<view class="flex align-center padding"> |
|
||||
<view class="round lg cu-avatar icon2"> |
|
||||
<view class="iconfont icon-carryout"></view> |
|
||||
</view> |
|
||||
<view class="padding-left-sm flex-sub"> |
|
||||
<view class="text-xl">每日健康打卡</view> |
|
||||
<view class="text-df padding-top-xs description">山大人员健康情况打卡</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view |
|
||||
@tap="openPage('/pages/add-stroke/add-stroke')" |
|
||||
class="cu-card flex margin bg-white shadow card-radius" |
|
||||
hover-class="cc-active" |
|
||||
> |
|
||||
<view class="flex align-center padding"> |
|
||||
<view class="round lg cu-avatar icon3"> |
|
||||
<view class="iconfont icon-car"></view> |
|
||||
</view> |
|
||||
<view class="padding-left-sm flex-sub"> |
|
||||
<view class="text-xl">行程上报</view> |
|
||||
<view class="text-df padding-top-xs description">外出行程及时上报</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view |
|
||||
@tap="openPage('/pages/statistics/statistics')" |
|
||||
class="cu-card flex margin bg-white shadow card-radius" |
|
||||
hover-class="cc-active" |
|
||||
> |
|
||||
<view class="flex align-center padding"> |
|
||||
<view class="round lg cu-avatar icon4"> |
|
||||
<view class="iconfont icon-linechart"></view> |
|
||||
</view> |
|
||||
<view class="padding-left-sm flex-sub"> |
|
||||
<view class="text-xl">统计</view> |
|
||||
<view class="text-df padding-top-xs description">山大校园疫情统计</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState } from 'vuex'; |
|
||||
export default { |
|
||||
name: 'Home', |
|
||||
data() { |
|
||||
return {}; |
|
||||
}, |
|
||||
computed: mapState('user', ['userInfo', 'healthCode']), |
|
||||
methods: { |
|
||||
//预览图片 |
|
||||
getPreviewImg(image) { |
|
||||
var imgArr = []; |
|
||||
imgArr.push(image); |
|
||||
uni.previewImage({ |
|
||||
urls: imgArr, |
|
||||
current: imgArr[0], |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style scoped lang="scss"> |
|
||||
.bg { |
|
||||
width: 100%; |
|
||||
height: 495rpx; |
|
||||
} |
|
||||
|
|
||||
.bg1 { |
|
||||
width: 100%; |
|
||||
height: 635rpx; |
|
||||
} |
|
||||
|
|
||||
.bg-code { |
|
||||
display: flex; |
|
||||
width: 100%; |
|
||||
position: absolute; |
|
||||
top: 370rpx; |
|
||||
|
|
||||
.healthy-code-bg { |
|
||||
margin: 0 auto; |
|
||||
width: 230rpx; |
|
||||
height: 230rpx; |
|
||||
border-radius: 6px; |
|
||||
overflow: hidden; |
|
||||
background: $whiteShadow; |
|
||||
|
|
||||
.healthy-code { |
|
||||
margin: 5rpx; |
|
||||
width: 220rpx; |
|
||||
height: 220rpx; |
|
||||
border-radius: 6px; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.box { |
|
||||
position: relative; |
|
||||
top: -100rpx; |
|
||||
} |
|
||||
|
|
||||
.box1 { |
|
||||
position: relative; |
|
||||
top: 0; |
|
||||
} |
|
||||
|
|
||||
.card-radius { |
|
||||
border-radius: 15rpx; |
|
||||
} |
|
||||
|
|
||||
.description { |
|
||||
color: $grey; |
|
||||
} |
|
||||
|
|
||||
.icon1 { |
|
||||
background: $iconGreen; |
|
||||
} |
|
||||
|
|
||||
.icon2 { |
|
||||
background: $iconCyan; |
|
||||
} |
|
||||
|
|
||||
.icon3 { |
|
||||
background: $iconBlue; |
|
||||
} |
|
||||
|
|
||||
.icon4 { |
|
||||
background: $iconPurple; |
|
||||
} |
|
||||
</style> |
|
@ -1,100 +0,0 @@ |
|||||
<template> |
|
||||
<view> |
|
||||
<!-- 头部 --> |
|
||||
<view class="cu-card flex bg-white" v-if="user && user.wxInfo"> |
|
||||
<view class="flex flex-sub align-center padding-xl"> |
|
||||
<view class="round xl cu-avatar portrait bg-white"> |
|
||||
<image class="xl cu-avatar" :src="user.wxInfo.headImgUrl"></image> |
|
||||
</view> |
|
||||
<view class="flex-sub padding-left"> |
|
||||
<view class="text-xxl">{{ user.wxInfo.nickname }}</view> |
|
||||
<!-- <view class="text-df padding-top-xs">{{ user.wxInfo.classes }}</view> --> |
|
||||
</view> |
|
||||
|
|
||||
<image class="healthy-code" :src="healthCode" @tap="getPreviewImg(healthCode)"></image> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="cu-card flex bg-white" v-else> |
|
||||
<view class="flex flex-sub align-center padding-xl"> |
|
||||
<view class="round xl cu-avatar portrait"> |
|
||||
<image class="xl cu-avatar" :src="userInfo.avatarUrl"></image> |
|
||||
</view> |
|
||||
<view class="flex-sub padding-left"> |
|
||||
<view class="text-xxl">{{ userInfo.nickName }}</view> |
|
||||
<!-- <view class="text-df padding-top-sm">{{ userInfo.classes }}</view> --> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<!-- 列表 --> |
|
||||
<view class="bg-white margin-top"> |
|
||||
<view class="cu-list menu margin-lr"> |
|
||||
<view |
|
||||
class="cu-item" |
|
||||
hover-class="cc-active" |
|
||||
@tap="openPage('/pages/basic-info/basic-info')" |
|
||||
> |
|
||||
<text class="text-xl">个人信息</text> |
|
||||
<view class="iconfont icon-right more"></view> |
|
||||
</view> |
|
||||
<view class="cu-item" hover-class="cc-active" @tap="openPage('/pages/my-code/my-code')"> |
|
||||
<text class="text-xl">我的健康打卡</text> |
|
||||
<view class="iconfont icon-right more"></view> |
|
||||
</view> |
|
||||
<view class="cu-item" hover-class="cc-active" @tap="openPage('/pages/my-trips/my-trips')"> |
|
||||
<text class="text-xl">我的行程</text> |
|
||||
<view class="iconfont icon-right more"></view> |
|
||||
</view> |
|
||||
<view class="cu-item" hover-class="cc-active" @tap="openPage('/pages/my-signs/my-signs')"> |
|
||||
<text class="text-xl">我的校园打卡</text> |
|
||||
<view class="iconfont icon-right more"></view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState } from 'vuex'; |
|
||||
export default { |
|
||||
name: 'Mine', |
|
||||
data() { |
|
||||
return { |
|
||||
userInfo: { |
|
||||
avatarUrl: '/static/head-portrait.png', |
|
||||
nickName: '健康码', |
|
||||
// classes: '计算机19级软工二班', |
|
||||
}, |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: mapState('user', ['healthCode', 'user']), |
|
||||
|
|
||||
methods: { |
|
||||
//预览图片 |
|
||||
getPreviewImg(image) { |
|
||||
var imgArr = []; |
|
||||
imgArr.push(image); |
|
||||
uni.previewImage({ |
|
||||
urls: imgArr, |
|
||||
current: imgArr[0], |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.portrait { |
|
||||
overflow: hidden; |
|
||||
} |
|
||||
|
|
||||
.healthy-code { |
|
||||
width: 70rpx; |
|
||||
height: 70rpx; |
|
||||
} |
|
||||
|
|
||||
.more { |
|
||||
font-size: 18px; |
|
||||
color: $grey; |
|
||||
} |
|
||||
</style> |
|
@ -1,87 +1,17 @@ |
|||||
<template> |
<template> |
||||
<view class="container"> |
<view class="container"> |
||||
<view class="content" style="width: 100%;"> |
模板首页 |
||||
<home v-if="navIndex === 0" /> |
<!-- 测试组件 不需要引入 注册 --> |
||||
<mine v-else /> |
<test /> |
||||
</view> |
|
||||
|
|
||||
<!-- 底部菜单 --> |
|
||||
<nav-bottom @change="onNavChange" @scan="onScan" class="nav-bottom"></nav-bottom> |
|
||||
|
|
||||
<!-- 获取用户信息的授权组件 --> |
|
||||
<auth /> |
|
||||
</view> |
</view> |
||||
</template> |
</template> |
||||
|
|
||||
<script> |
<script> |
||||
import Home from './components/home.vue'; |
|
||||
import Mine from './components/mine.vue'; |
|
||||
|
|
||||
export default { |
export default { |
||||
components: { Home, Mine }, |
|
||||
data() { |
|
||||
return { |
|
||||
navIndex: 0, |
|
||||
}; |
|
||||
}, |
|
||||
// 分享 |
|
||||
onShareAppMessage() { |
|
||||
return { |
|
||||
title: '健康码小程序', |
|
||||
path: '/pages/index/index?scene=1008', |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
/** |
|
||||
* 监听nav-bottom的点击事件 |
|
||||
* @param {number} index nav-bottom按钮的索引值 |
|
||||
*/ |
|
||||
onNavChange(index) { |
|
||||
this.navIndex = index; |
|
||||
}, |
|
||||
|
|
||||
// 扫一扫 |
|
||||
// 只允许通过相机扫码 |
|
||||
onScan() { |
|
||||
wx.scanCode({ |
|
||||
onlyFromCamera: true, |
|
||||
scanType: ['qrCode', 'wxCode'], |
|
||||
success: res => { |
|
||||
// 如果有路径 |
|
||||
if (res && res.path) { |
|
||||
const pathArr = res.path.split('?scene='); |
|
||||
const query = encodeURIComponent(pathArr[1]); |
|
||||
const path = `/${pathArr[0]}?scene=${query}&scan=true`; |
|
||||
this.openPage(path); |
|
||||
} else { |
|
||||
uni.showModal({ |
|
||||
title: '提示', |
|
||||
content: '您的微信版本不支持此功能, 请使用微信APP的扫码功能', |
|
||||
success: function(res) {}, |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
}; |
||||
</script> |
</script> |
||||
|
|
||||
<style scoped lang="scss"> |
<style scoped lang="scss"> |
||||
.container { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
width: 100%; |
|
||||
height: 100vh; |
|
||||
|
|
||||
.content { |
|
||||
flex: 1; |
|
||||
overflow-y: auto; |
|
||||
} |
|
||||
.nav-bottom { |
|
||||
width: 100%; |
|
||||
} |
|
||||
} |
|
||||
</style> |
</style> |
||||
|
@ -1,175 +0,0 @@ |
|||||
<template> |
|
||||
<view> |
|
||||
<!-- 添加 --> |
|
||||
<button v-if="tableList && tableList.length === 0" class="shadow round bg-cyan add-btn iconfont icon-plus" hover-class="cc-active" @tap="openPage('/pages/apply-code/apply-code')"></button> |
|
||||
<button v-if="tableList && tableList.length > 0" class="shadow round bg-cyan add-btn iconfont icon-plus" hover-class="cc-active" @tap="openPage('/pages/punch-the-clock/punch-the-clock')"></button> |
|
||||
<view v-if="tableList && tableList.length > 0" class="cu-timeline" :key="index" v-for="(item, index) in tableList"> |
|
||||
<view class="cu-time">{{ +item.time | formatDate }}</view> |
|
||||
<view class="cu-item text-blue cuIcon-locationfill"> |
|
||||
<view class="content shadow-blur bg-blue light">{{ item.district }},{{ item.address }}</view> |
|
||||
</view> |
|
||||
<view class="cu-item text-green cuIcon-wefill"> |
|
||||
<view class="content shadow-blur light" :class="item.healthLevel === 0 ? 'bg-green' : item.healthLevel === 1 ? 'bg-yellow' : 'bg-red'"> |
|
||||
<view class="margin-bottom flex"> |
|
||||
体温:{{ item.animalHeat }}℃, |
|
||||
<text v-for="state in status" :key="state.id"> |
|
||||
<text v-if="state.id === item.healthTypeId">状态:{{ state.name }}</text> |
|
||||
</text> |
|
||||
</view> |
|
||||
<view> |
|
||||
<text class="radius bg-red margin-tb margin-right padding-xs" v-show="item.touchHubei === 1">武汉接触史</text> |
|
||||
<text class="radius bg-red margin-tb margin-right padding-xs" v-show="item.touchSick === 1">患者接触史</text> |
|
||||
</view> |
|
||||
<view class="margin-tb-sm"> |
|
||||
<text class="radius bg-red margin-tb margin-right padding-xs" v-show="item.touchOverseas === 1">境外人员接触史</text> |
|
||||
<text class="radius bg-green margin-tb margin-right padding-xs" v-if="item.schoolLocation === 1">在校</text> |
|
||||
<text class="radius bg-green margin-tb margin-right padding-xs" v-else>不在校</text> |
|
||||
</view> |
|
||||
<view class="margin-top" v-if="item.emergencyName || item.emergencyPhone">紧急联系人:{{ item.emergencyName }} {{ item.emergencyPhone }}</view> |
|
||||
<view class="margin-top" v-show="item.remark || item.filePath.length > 0"> |
|
||||
备注:{{ item.remark }} |
|
||||
<view class="padding-top"> |
|
||||
<image @tap="viewImage(item.filePath, i)" :key="i" v-for="(file, i) in item.filePath" :src="file" style="width: 69px;height: 75px;" |
|
||||
class="margin-lr-xs"></image> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view v-if="tableList && tableList.length === 0" class="padding-lg">您还没有申请健康码,请点击右下角加号申请健康码。</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { |
|
||||
formatDate |
|
||||
} from 'common/script/filters'; |
|
||||
import { |
|
||||
showToast |
|
||||
} from 'common/script/util'; |
|
||||
import { |
|
||||
HEALTH_SIGN_HISTORY |
|
||||
} from 'api/api'; |
|
||||
import { |
|
||||
mapState, |
|
||||
mapMutations |
|
||||
} from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
tableList: [] |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: mapState('user', ['token', 'userInfo', 'status']), |
|
||||
|
|
||||
// 时间戳转化日期 |
|
||||
filters: { |
|
||||
formatDate(time) { |
|
||||
var data = new Date(time); |
|
||||
return formatDate(data, 'MM-dd'); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
onLoad() { |
|
||||
const startTime = +this.$moment() |
|
||||
.startOf('year') |
|
||||
.format('x'); |
|
||||
const endTime = +this.$moment() |
|
||||
.endOf('day') |
|
||||
.format('x'); |
|
||||
const params = { |
|
||||
param: { |
|
||||
startTime, |
|
||||
endTime, |
|
||||
token: this.token |
|
||||
} |
|
||||
}; |
|
||||
this.getHealthSignHistory(params); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
...mapMutations('user', ['setStatus', 'setUserInfo']), |
|
||||
|
|
||||
// 获取健康打卡记录 |
|
||||
async getHealthSignHistory(params) { |
|
||||
try { |
|
||||
const res = await this.$http.post(HEALTH_SIGN_HISTORY, params); |
|
||||
const { |
|
||||
success, |
|
||||
code, |
|
||||
msg, |
|
||||
data |
|
||||
} = res.data; |
|
||||
if (success && code === 200) { |
|
||||
this.success = true; |
|
||||
this.tableList = data; |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: msg || '获取健康打卡记录失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
if (error.msg) { |
|
||||
uni.showToast({ |
|
||||
title: error.msg || '获取健康打卡记录失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 预览图片 |
|
||||
viewImage(filePath, index) { |
|
||||
if (filePath && filePath.length > 0) { |
|
||||
uni.previewImage({ |
|
||||
urls: filePath, |
|
||||
current: filePath[index], |
|
||||
indicator: 'number', |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.data-wrap { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: left; |
|
||||
justify-content: flex-start; |
|
||||
padding: 40rpx 0; |
|
||||
|
|
||||
.data-item { |
|
||||
display: flex; |
|
||||
flex-wrap: wrap; |
|
||||
align-items: left; |
|
||||
font-size: 36rpx; |
|
||||
margin-bottom: 20rpx; |
|
||||
|
|
||||
.data-title { |
|
||||
line-height: 60rpx; |
|
||||
color: $black; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.add-btn { |
|
||||
position: fixed; |
|
||||
bottom: 40rpx; |
|
||||
right: 40rpx; |
|
||||
width: 96rpx; |
|
||||
height: 96rpx; |
|
||||
line-height: 96rpx; |
|
||||
padding: 0; |
|
||||
z-index: 1; |
|
||||
} |
|
||||
|
|
||||
.add-btn::after { |
|
||||
border: none; |
|
||||
} |
|
||||
</style> |
|
@ -1,157 +0,0 @@ |
|||||
<template> |
|
||||
<view class="wrap"> |
|
||||
<!-- 头部菜单 --> |
|
||||
<view class="nav-wrap slide-bottom"> |
|
||||
<uni-segmented-control |
|
||||
:active-color="activeColor" |
|
||||
:current="current" |
|
||||
:values="values" |
|
||||
@clickItem="handleClickNav" |
|
||||
class="nav" |
|
||||
/> |
|
||||
</view> |
|
||||
<!-- 内容区 --> |
|
||||
<view class="content"> |
|
||||
<!-- 今日打卡地图显示 --> |
|
||||
<history-map |
|
||||
:markers="markers" |
|
||||
:polygons="polygons" |
|
||||
:polyline="polyline" |
|
||||
v-if="current === 0" |
|
||||
/> |
|
||||
<!-- 打卡记录 时间轴显示 --> |
|
||||
<timeline v-else /> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState, mapActions } from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
current: 0, |
|
||||
values: ['今日打卡', '打卡记录'], |
|
||||
activeColor: '#0897C7', |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: { |
|
||||
...mapState('statistics', ['userSigns']), |
|
||||
...mapState('user', ['token']), |
|
||||
// 坐标标注点 |
|
||||
markers() { |
|
||||
if (!this.userSigns) return null; |
|
||||
const result = []; |
|
||||
this.userSigns.forEach(item => { |
|
||||
const content = `${this.$moment(+item.time).format('YY-MM-DD HH:mm')} \n ${item.siteName}`; |
|
||||
const obj = { |
|
||||
latitude: item.latitude, |
|
||||
longitude: item.longitude, |
|
||||
iconPath: '/static/location.png', |
|
||||
callout: { |
|
||||
content, |
|
||||
color: '#fff', |
|
||||
padding: 4, |
|
||||
bgColor: '#0A97C6', |
|
||||
borderRadius: 2, |
|
||||
textAlign: 'center', |
|
||||
}, |
|
||||
}; |
|
||||
result.push(obj); |
|
||||
}); |
|
||||
|
|
||||
return result; |
|
||||
}, |
|
||||
|
|
||||
// 轨迹连线 |
|
||||
polyline() { |
|
||||
if (!this.userSigns) return null; |
|
||||
const points = []; |
|
||||
this.userSigns.forEach(item => { |
|
||||
const obj = { |
|
||||
latitude: item.latitude, |
|
||||
longitude: item.longitude, |
|
||||
}; |
|
||||
points.push(obj); |
|
||||
}); |
|
||||
return [{ points, arrowLine: true, dottedLine: true, borderColor: '#cccccc' }]; |
|
||||
}, |
|
||||
|
|
||||
// 多边形区域 |
|
||||
polygons() { |
|
||||
if (!this.userSigns) return null; |
|
||||
const points = []; |
|
||||
this.userSigns.forEach(item => { |
|
||||
const obj = { |
|
||||
latitude: item.latitude, |
|
||||
longitude: item.longitude, |
|
||||
}; |
|
||||
points.push(obj); |
|
||||
}); |
|
||||
return [ |
|
||||
{ points, strokeWidth: 0, strokeColor: '#00000000', fillColor: '#cce6ff88', zIndex: 0 }, |
|
||||
]; |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
onLoad() { |
|
||||
const startTime = +this.$moment() |
|
||||
.startOf('day') |
|
||||
.format('x'); |
|
||||
const endTime = +this.$moment() |
|
||||
.endOf('day') |
|
||||
.format('x'); |
|
||||
const params = { param: { startTime, endTime, token: this.token } }; |
|
||||
this.getUserSigns(params); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
...mapActions('statistics', ['getUserSigns']), |
|
||||
|
|
||||
handleClickNav({ currentIndex }) { |
|
||||
this.current = currentIndex; |
|
||||
const endTime = +this.$moment() |
|
||||
.endOf('day') |
|
||||
.format('x'); |
|
||||
const startTime = +this.$moment('2020-01-01') |
|
||||
.startOf('day') |
|
||||
.format('x'); |
|
||||
let param = { startTime, endTime, token: this.token }; |
|
||||
if (currentIndex === 0) { |
|
||||
param.startTime = +this.$moment() |
|
||||
.startOf('day') |
|
||||
.format('x'); |
|
||||
} |
|
||||
const params = { param }; |
|
||||
this.getUserSigns(params); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.wrap { |
|
||||
padding-top: 88rpx; |
|
||||
min-height: 100vh; |
|
||||
background-color: $white; |
|
||||
|
|
||||
.nav-wrap { |
|
||||
z-index: 999; |
|
||||
position: fixed; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
top: 0; |
|
||||
|
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
height: 88rpx; |
|
||||
background-color: $white; |
|
||||
.nav { |
|
||||
width: 540rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,195 +0,0 @@ |
|||||
<template> |
|
||||
<view> |
|
||||
<!-- 添加 --> |
|
||||
<button class="shadow round bg-cyan add-btn iconfont icon-plus" hover-class="cc-active" @tap="openPage('/pages/add-stroke/add-stroke')"></button> |
|
||||
<view v-if="tableList && tableList.length>0" class="cu-timeline" :key="index" v-for="(item,index) in tableList"> |
|
||||
<view class="cu-time">{{ +item.startTime | formatDate }}</view> |
|
||||
<view class="cu-item cuIcon-timefill text-blue"> |
|
||||
<view class="content shadow-blur bg-blue light"> |
|
||||
{{ +item.startTime | formatDate1 }} 至 {{ +item.endTime | formatDate1 }} |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="cu-item cuIcon-tagfill text-green"> |
|
||||
<view class="content shadow-blur bg-green light"> |
|
||||
<view> |
|
||||
<text class="radius bg-green margin-tb padding-xs" v-if="item.journeyType === '0'">返校行程</text> |
|
||||
<text class="radius bg-green margin-tb padding-xs" v-if="item.journeyType === '1'">日常外出</text> |
|
||||
</view> |
|
||||
<view class="margin-bottom" v-if="item.together"> |
|
||||
同行人:{{ item.together }} |
|
||||
</view> |
|
||||
<view v-for="trip in transports" :key="trip.id" class="margin-bottom" v-if="trip.value === item.tripMode"> |
|
||||
出行方式: |
|
||||
{{ trip.name }} |
|
||||
</view> |
|
||||
<view> |
|
||||
乘坐航班车次或车牌号码及座位号: |
|
||||
{{ item.carNo }} |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view v-if="tableList && tableList.length === 0" class="padding-lg"> |
|
||||
您还没有添加行程,请点击右下角加号添加行程。 |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
|
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { |
|
||||
formatDate |
|
||||
} from 'common/script/filters'; |
|
||||
import { |
|
||||
showToast |
|
||||
} from 'common/script/util'; |
|
||||
import { |
|
||||
mapState, |
|
||||
mapMutations |
|
||||
} from 'vuex'; |
|
||||
import { |
|
||||
GET_JOURNEYS |
|
||||
} from 'api/api'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
tableList: [], |
|
||||
transports: [{ |
|
||||
value: 0, |
|
||||
name: '火车', |
|
||||
}, |
|
||||
{ |
|
||||
value: 1, |
|
||||
name: '飞机', |
|
||||
}, |
|
||||
{ |
|
||||
value: 2, |
|
||||
name: '客运车辆', |
|
||||
}, |
|
||||
{ |
|
||||
value: 3, |
|
||||
name: '自驾', |
|
||||
}, |
|
||||
{ |
|
||||
value: 4, |
|
||||
name: '船', |
|
||||
}, |
|
||||
{ |
|
||||
value: 5, |
|
||||
name: '其他', |
|
||||
} |
|
||||
] |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: mapState('user', ['token']), |
|
||||
|
|
||||
// 时间戳转化日期 |
|
||||
filters: { |
|
||||
formatDate(time) { |
|
||||
var data = new Date(time); |
|
||||
return formatDate(data, 'MM-dd'); |
|
||||
}, |
|
||||
|
|
||||
formatDate1(time) { |
|
||||
var data = new Date(time); |
|
||||
return formatDate(data, 'MM月dd日 hh:mm'); |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
onLoad() { |
|
||||
const startTime = +this.$moment() |
|
||||
.startOf('year') |
|
||||
.format('x'); |
|
||||
const endTime = +this.$moment() |
|
||||
.endOf('day') |
|
||||
.format('x'); |
|
||||
const params = { |
|
||||
param: { |
|
||||
startTime, |
|
||||
endTime, |
|
||||
token: this.token |
|
||||
} |
|
||||
}; |
|
||||
this.getJourneys(params); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
// 查询行程 |
|
||||
async getJourneys(params) { |
|
||||
try { |
|
||||
const res = await this.$http.post(GET_JOURNEYS, params); |
|
||||
const { |
|
||||
success, |
|
||||
code, |
|
||||
msg, |
|
||||
data |
|
||||
} = res.data; |
|
||||
|
|
||||
if (success && code === 200) { |
|
||||
this.success = true; |
|
||||
this.tableList = data; |
|
||||
|
|
||||
const fff = this.$moment(1583683200000).format('YY-MM-DD') |
|
||||
|
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: msg || '查询行程失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
if (error.msg) { |
|
||||
uni.showToast({ |
|
||||
title: error.msg || '查询行程失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.data-wrap { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: left; |
|
||||
justify-content: flex-start; |
|
||||
padding: 40rpx 0; |
|
||||
|
|
||||
.data-item { |
|
||||
display: flex; |
|
||||
flex-wrap: wrap; |
|
||||
align-items: left; |
|
||||
font-size: 36rpx; |
|
||||
margin-bottom: 20rpx; |
|
||||
|
|
||||
.data-title { |
|
||||
line-height: 60rpx; |
|
||||
color: $black; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.add-btn { |
|
||||
position: fixed; |
|
||||
bottom: 40rpx; |
|
||||
right: 40rpx; |
|
||||
width: 96rpx; |
|
||||
height: 96rpx; |
|
||||
line-height: 96rpx; |
|
||||
padding: 0; |
|
||||
z-index: 1; |
|
||||
} |
|
||||
|
|
||||
.add-btn::after { |
|
||||
border: none; |
|
||||
} |
|
||||
</style> |
|
@ -1,398 +0,0 @@ |
|||||
<template> |
|
||||
<view class="margin-lr-lg"> |
|
||||
<view class="text-xxl margin-tb-lg text-center text-bold">隐私政策</view> |
|
||||
<view class="margin-bottom-lg"> |
|
||||
感谢您信任并使用传控科技的产品和服务,我们根据最新的法律法规、监管政策要求,更新了《传控科技隐私政策》。请您仔细阅读并充分理解以下条款。 |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
引言 |
|
||||
</view> |
|
||||
<view> |
|
||||
传控科技严格遵守法律法规,遵循以下隐私保护原则,为您提供更加安全、可靠的服务: |
|
||||
</view> |
|
||||
<view class="margin-left"> |
|
||||
<view> |
|
||||
1、安全可靠: |
|
||||
</view> |
|
||||
<view> |
|
||||
我们竭尽全力通过合理有效的信息安全技术及管理流程,防止您的信息泄露、损毁、丢失。 |
|
||||
</view> |
|
||||
<view> |
|
||||
2、自主选择: |
|
||||
</view> |
|
||||
<view> |
|
||||
我们为您提供便利的信息管理选项,以便您做出合适的选择,管理您的个人信息。 |
|
||||
</view> |
|
||||
<view> |
|
||||
3、保护通信秘密: |
|
||||
</view> |
|
||||
<view> |
|
||||
我们严格遵照法律法规,保护您的通信秘密,为您提供安全的通信服务。 |
|
||||
</view> |
|
||||
<view> |
|
||||
4、合理必要: |
|
||||
</view> |
|
||||
<view> |
|
||||
为了向您和其他用户提供更好的服务,我们仅收集必要的信息。 |
|
||||
</view> |
|
||||
<view> |
|
||||
5、清晰透明: |
|
||||
</view> |
|
||||
<view> |
|
||||
我们努力使用简明易懂的表述,向您介绍隐私政策,以便您清晰地了解我们的信息处理方式。 |
|
||||
</view> |
|
||||
<view> |
|
||||
6、将隐私保护融入产品设计: |
|
||||
</view> |
|
||||
<view> |
|
||||
我们在产品或服务开发的各个环节,综合法律、产品、设计等多方因素,融入隐私保护的理念。 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="margin-top"> |
|
||||
本《隐私政策》主要向您说明: |
|
||||
</view> |
|
||||
<view> |
|
||||
我们收集哪些信息 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们收集信息的用途 |
|
||||
</view> |
|
||||
<view> |
|
||||
您所享有的权利 |
|
||||
</view> |
|
||||
<view class="margin-top"> |
|
||||
希望您仔细阅读《隐私政策》(以下简称“本政策”),详细了解我们对信息的收集、使用方式,以便您更好地了解我们的服务并作出适当的选择。 |
|
||||
</view> |
|
||||
<view class="margin-top"> |
|
||||
若您使用传控科技服务,即表示您认同我们在本政策中所述内容。除另有约定外,本政策所用术语与《用户服务协议》中的术语具有相同的涵义。如您有问题,请联系我们。 |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
我们收集的信息 |
|
||||
</view> |
|
||||
<view>我们根据合法、正当、必要的原则,仅收集实现产品功能所必要的信息。</view> |
|
||||
<view class="margin-left"> |
|
||||
<view>您在使用我们服务时主动提供的信息</view> |
|
||||
<view>您在登录系统时,经授权产生的信息,比如昵称、头像等</view> |
|
||||
<view>您在使用服务时上传的信息</view> |
|
||||
<view>例如,您在使用我们的微信小程序时,上传的头像、分享的照片。</view> |
|
||||
<view>我们的部分服务可能需要您提供特定的个人敏感信息来实现特定功能。若您选择不提供该类信息,则可能无法正常使用服务中的特定功能,但不影响您使用服务中的其他功能。若您主动提供您的个人敏感信息,即表示您同意我们按本政策所述目的和方式来处理您的个人敏感信息。</view> |
|
||||
</view> |
|
||||
<view class="margin-top"> |
|
||||
我们在您使用服务时获取的信息 |
|
||||
</view> |
|
||||
<view> |
|
||||
<text class="text-bold margin-tb">日志信息</text> |
|
||||
<view>当您使用我们的服务时,我们可能会自动收集相关信息并存储为服务日志信息。</view> |
|
||||
</view> |
|
||||
<view class="margin-left"> |
|
||||
<view>1)设备信息</view> |
|
||||
<view>例如,设备型号、操作系统版本、唯一设备标识符、电池、信号强度等信息。</view> |
|
||||
<view>2)软件信息</view> |
|
||||
<view>例如,软件的版本号、浏览器类型。为确保操作环境的安全或提供服务所需,我们会收集有关您使用的移动应用和其他软件的信息。</view> |
|
||||
<view>3)IP地址</view> |
|
||||
<view>4)服务日志信息</view> |
|
||||
<view>例如,您在使用我们服务时搜索、查看的信息、服务故障信息、引荐网址等信息。</view> |
|
||||
<view>5)通讯日志信息</view> |
|
||||
<view>例如,您在使用我们服务时曾经通讯的账户、通讯时间和时长。</view> |
|
||||
</view> |
|
||||
|
|
||||
<view> |
|
||||
<text class="text-bold margin-tb">位置信息</text> |
|
||||
<view>当您使用与位置有关的服务时,我们可能会记录您设备所在的位置信息,以便为您提供相关服务。</view> |
|
||||
<view>在您使用服务时,我们可能会通过IP地址 、GPS、WLAN(如 WiFi)或基站等途径获取您的地理位置信息;</view> |
|
||||
<view>您或其他用户在使用服务时提供的信息中可能包含您所在地理位置信息,例如您提供的帐号信息中可能包含的您所在地区信息,您或其他人共享的照片包含的地理标记信息。</view> |
|
||||
</view> |
|
||||
|
|
||||
<view> |
|
||||
<text class="text-bold margin-tb">其他相关信息</text> |
|
||||
<view>为了帮助您更好地使用我们的产品或服务,我们会收集相关信息。例如,我们收集的好友列表、群列表信息、声纹特征值信息。为确保您使用我们服务时能与您认识的人进行联系,如您选择开启导入通讯录功能,我们可能对您联系人的姓名和电话号码进行加密,并仅收集加密后的信息。</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="margin-top"> |
|
||||
其他用户分享的信息中含有您的信息 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
例如,其他用户发布的照片或分享的视频中可能包含您的信息。 |
|
||||
</view> |
|
||||
|
|
||||
<view class="margin-top"> |
|
||||
从第三方合作伙伴获取的信息 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
我们可能会获得您在使用第三方合作伙伴服务时所产生或分享的信息。例如,您使用微信或QQ帐户登录第三方合作伙伴服务时,我们会获得您登录第三方合作伙伴服务的名称、登录时间,方便您进行授权管理。请您仔细阅读第三方合作伙伴服务的用户协议或隐私政策。 |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
我们如何使用收集的信息 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们严格遵守法律法规的规定及与用户的约定,将收集的信息用于以下用途。若我们超出以下用途使用您的信息,我们将再次向您进行说明,并征得您的同意。 |
|
||||
</view> |
|
||||
<view class="margin-left"> |
|
||||
<view> |
|
||||
向您提供服务 |
|
||||
</view> |
|
||||
<view> |
|
||||
满足您的个性化需求 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
例如,语言设定、位置设定、个性化的帮助服务。 |
|
||||
</view> |
|
||||
<view> |
|
||||
产品开发和服务优化 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
例如,当我们的系统发生故障时,我们会记录和分析系统故障时产生的信息,优化我们的服务。 |
|
||||
</view> |
|
||||
<view> |
|
||||
安全保障 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
例如,我们会将您的信息用于身份验证、安全防范、反诈骗监测、存档备份、客户的安全服务等用途。例如,您下载或安装的安全软件会对恶意程序或病毒进行检测,或为您识别诈骗信息。 |
|
||||
</view> |
|
||||
<view> |
|
||||
向您推荐您可能感兴趣的广告、资讯等 |
|
||||
</view> |
|
||||
<view> |
|
||||
评估、改善我们的广告投放和其他促销及推广活动的效果 |
|
||||
</view> |
|
||||
<view> |
|
||||
管理软件 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
例如,进行软件认证、软件升级等。 |
|
||||
</view> |
|
||||
<view> |
|
||||
邀请您参与有关我们服务的调查 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view> |
|
||||
为了让您有更好的体验、改善我们的服务或经您同意的其他用途,在符合相关法律法规的前提下,我们可能将通过某些服务所收集的信息用于我们的其他服务。例如,将您在使用我们某项服务时的信息,用于另一项服务中向您展示个性化的内容或广告、用于用户研究分析与统计等服务。 |
|
||||
</view> |
|
||||
<view> |
|
||||
为了确保服务的安全,帮助我们更好地了解我们应用程序的运行情况,我们可能记录相关信息,例如,您使用应用程序的频率、故障信息、总体使用情况、性能数据以及应用程序的来源。我们不会将我们存储在分析软件中的信息与您在应用程序中提供的个人身份信息相结合。 |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
您分享的信息 |
|
||||
</view> |
|
||||
<view> |
|
||||
您可以通过我们的服务与您的好友、家人及其他用户分享您的相关信息。例如,您在微信朋友圈中公开分享的文字和照片。 |
|
||||
</view> |
|
||||
<view> |
|
||||
请注意,这其中可能包含您的个人身份信息、个人财产信息等敏感信息。请您谨慎考虑披露您的相关个人敏感信息。 |
|
||||
</view> |
|
||||
<view> |
|
||||
您可通过我们服务中的隐私设置来控制您分享信息的范围,也可通过服务中的设置或我们提供的指引删除您公开分享的信息。但请您注意,这些信息仍可能由其他用户或不受我们控制的非关联第三方独立地保存。 |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
您如何管理自己的信息 |
|
||||
</view> |
|
||||
<view> |
|
||||
您可以在使用我们服务的过程中,访问、修改和删除您提供的注册信息和其他个人信息,也可按照通知指引与我们联系。您访问、修改和删除个人信息的范围和方式将取决于您使用的具体服务。 |
|
||||
</view> |
|
||||
<view> |
|
||||
例如,若您在使用地理位置相关服务时,希望停止分享您的地理位置信息,您可通过手机定位关闭功能、软硬件服务商及通讯服务提供商的关闭方式停止分享,建议您仔细阅读相关指引。 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们将按照本政策所述,仅为实现我们产品或服务的功能,收集、使用您的信息。 |
|
||||
</view> |
|
||||
<view> |
|
||||
如您发现我们违反法律、行政法规的规定或者双方的约定收集、使用您的个人信息,您可以要求我们删除。 |
|
||||
</view> |
|
||||
<view> |
|
||||
如您发现我们收集、存储的您的个人信息有错误的,您也可以要求我们更正。 |
|
||||
</view> |
|
||||
<view> |
|
||||
请通过本政策列明的联系方式与我们联系。 |
|
||||
</view> |
|
||||
<view> |
|
||||
在您访问、修改和删除相关信息时,我们可能会要求您进行身份验证,以保障帐号的安全。 |
|
||||
</view> |
|
||||
<view> |
|
||||
请您理解,由于技术所限、法律或监管要求,我们可能无法满足您的所有要求,我们会在合理的期限内答复您的请求。 |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
我们分享的信息 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们遵照法律法规的规定,对信息的分享进行严格的限制,例如: |
|
||||
</view> |
|
||||
<view> |
|
||||
<view> |
|
||||
经您事先同意,我们可能与第三方分享您的个人信息 |
|
||||
</view> |
|
||||
<view> |
|
||||
仅为实现外部处理的目的,我们可能会与第三方合作伙伴(第三方服务供应商、承包商、代理、广告合作伙伴、应用开发者等,例如,代表我们发出电子邮件或推送通知的通讯服务提供商、为我们提供位置服务的地图服务供应商)(他们可能并非位于您所在的法域)分享您的个人信息,让他们按照我们的说明、隐私政策以及其他相关的保密和安全措施来为我们处理上述信息,并用于以下用途: |
|
||||
<view class="text-sm margin-left"> |
|
||||
向您提供我们的服务; |
|
||||
</view> |
|
||||
<view class="text-sm margin-left"> |
|
||||
实现“我们如何使用收集的信息”部分所述目的; |
|
||||
</view> |
|
||||
<view class="text-sm margin-left"> |
|
||||
履行我们在《用户服务协议》或本政策中的义务和行使我们的权利; |
|
||||
</view> |
|
||||
<view class="text-sm margin-left"> |
|
||||
理解、维护和改善我们的服务。 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view> |
|
||||
如我们与上述第三方分享您的信息,我们将会采用加密、匿名化处理等手段保障您的信息安全。 |
|
||||
</view> |
|
||||
<view> |
|
||||
随着我们业务的持续发展,当发生合并、收购、资产转让等交易导致向第三方分享您的个人信息时,我们将通过推送通知、公告等形式告知您相关情形,按照法律法规及不低于本政策所要求的标准继续保护或要求新的管理者继续保护您的个人信息。 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们会将所收集到的信息用于大数据分析。 |
|
||||
<view class="text-sm"> |
|
||||
例如,我们将收集到的信息用于分析形成不包含任何个人信息的城市热力图或行业洞察报告。 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
我们可能对外公开并与我们的合作伙伴分享经统计加工后不含身份识别内容的信息,用于了解用户如何使用我们服务或让公众了解我们服务的总体使用趋势。 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view> |
|
||||
我们可能基于以下目的披露您的个人信息 |
|
||||
<view class="text-sm margin-left"> |
|
||||
遵守适用的法律法规等有关规定; |
|
||||
</view> |
|
||||
<view class="text-sm margin-left"> |
|
||||
遵守法院判决、裁定或其他法律程序的规定; |
|
||||
</view> |
|
||||
<view class="text-sm margin-left"> |
|
||||
遵守相关政府机关或其他法定授权组织的要求; |
|
||||
</view> |
|
||||
<view class="text-sm margin-left"> |
|
||||
我们有理由确信需要遵守法律法规等有关规定; |
|
||||
</view> |
|
||||
<view class="text-sm margin-left"> |
|
||||
为执行相关服务协议或本政策、维护社会公共利益,为保护我们的客户、我们或我们的关联公司、其他用户或雇员的人身财产安全或其他合法权益合理且必要的用途。 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
我们可能向您发送的信息 |
|
||||
</view> |
|
||||
<view> |
|
||||
信息推送 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
您在使用我们的服务时,我们可能向您发送电子邮件、短信、资讯或推送通知。 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
您可以按照我们的相关提示,在设备上选择取消订阅。 |
|
||||
</view> |
|
||||
<view> |
|
||||
与服务有关的公告 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
我们可能在必要时(例如,因系统维护而暂停某一项服务时)向您发出与服务有关的公告。 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
您可能无法取消这些与服务有关、性质不属于广告的公告。 |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
信息安全 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们为您的信息提供相应的安全保障,以防止信息的丢失、不当使用、未经授权访问或披露。 |
|
||||
</view> |
|
||||
<view class="margin-left"> |
|
||||
<view> |
|
||||
我们严格遵守法律法规保护用户的通信秘密。 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们将在合理的安全水平内使用各种安全保护措施以保障信息的安全。 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
例如,我们使用加密技术(例如,TLS、SSL)、匿名化处理等手段来保护您的个人信息。 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们建立专门的管理制度、流程和组织确保信息安全。 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
例如,我们严格限制访问信息的人员范围,要求他们遵守保密义务,并进行审查。 |
|
||||
</view> |
|
||||
<view> |
|
||||
若发生个人信息泄露等安全事件,我们会启动应急预案,阻止安全事件扩大,并以推送通知、公告等形式告知您。 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
广告 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们可能使用您的相关信息,在相关网站、应用及其他渠道向您提供与您更加相关的广告。 |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
适用范围 |
|
||||
</view> |
|
||||
<view> |
|
||||
我们的所有服务均适用本政策。 |
|
||||
</view> |
|
||||
<view class="margin-left"> |
|
||||
<view> |
|
||||
某些服务有其特定的隐私指引/声明,该特定隐私指引/声明更具体地说明我们在该服务中如何处理您的信息。 |
|
||||
</view> |
|
||||
<view> |
|
||||
如本政策与特定服务的隐私指引/声明有不一致之处,请以该特定隐私指引声明为准。 |
|
||||
</view> |
|
||||
<view> |
|
||||
请您注意,本政策不适用由其他公司或个人提供的服务。 |
|
||||
</view> |
|
||||
<view class="text-sm"> |
|
||||
例如,您通过使用微信帐号登录其他公司或个人提供的服务。 |
|
||||
</view> |
|
||||
<view> |
|
||||
您使用该等第三方服务须受其隐私政策(而非本政策)约束,您需要仔细阅读其政策内容。 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="text-content margin-bottom-xl"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
联系我们 |
|
||||
</view> |
|
||||
<view> |
|
||||
如您对本政策或其他相关事宜有疑问,请通过 https://www.ccsens.com 与我们联系。 |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
} |
|
||||
}, |
|
||||
} |
|
||||
</script> |
|
@ -1,559 +0,0 @@ |
|||||
<template> |
|
||||
<view> |
|
||||
<form class="padding-lr cu-form-group flex-direction"> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs">*</span>当前所在地区 |
|
||||
</view> |
|
||||
<view class="flex align-center"> |
|
||||
<input @tap="handleSelectLocation" class="flex-sub padding-left-xs" name="input" placeholder="请选择当前所在地区" type="btn" |
|
||||
v-model="district" maxlength="128" /> |
|
||||
<text class="cuIcon-location timer"></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs">*</span>当前所在详细地址 |
|
||||
</view> |
|
||||
<input name="input" placeholder="请输入详细地址(含门牌号)" type="text" v-model="address" maxlength="128" /> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"> |
|
||||
<span class="text-red padding-right-xs">*</span>当前状态 |
|
||||
</view> |
|
||||
<radio-group @change="StateChange" class="block"> |
|
||||
<view class="cu-list menu text-left"> |
|
||||
<view :key="index" class="cu-item" v-for="(state,index) in status"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio :checked="index === healthTypeId" :value="state.id" class="round margin-right-xs"></radio> |
|
||||
<view class="flex-sub" style="font-size: 34rpx;">{{ state.name }}</view> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm">就诊医院(若无填无)</view> |
|
||||
<input name="input" placeholder="请输入就诊医院" type="text" v-model="hospital" maxlength="32" /> |
|
||||
</view> |
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>最近14天是否有武汉居住史、旅游史或武汉亲戚来访</view> |
|
||||
<radio-group class="block" @change="TourChange"> |
|
||||
<view class="flex"> |
|
||||
<view class="flex-sub margin-tb-sm" v-for="(tour,index) in tours" :key="index"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === touchHubei" :value="tour.value"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ tour.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>最近14天是否有新冠肺炎患者或疑似患者接触史</view> |
|
||||
<radio-group class="block" @change="TouchChange"> |
|
||||
<view class="flex"> |
|
||||
<view class="flex-sub margin-tb-sm" v-for="(touch,index) in touches" :key="index"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === touchSick" :value="touch.value"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ touch.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>最近14天有无接触过近期境外返回人员</view> |
|
||||
<radio-group class="block" @change="TouchOverseasChange"> |
|
||||
<view class="flex"> |
|
||||
<view class="flex-sub margin-tb-sm" v-for="(touch,index) in overseas" :key="index"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === touchOverseas" :value="touch.value"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ touch.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-top"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>是否在学校所在地</view> |
|
||||
<radio-group class="block" @change="SchoolLocationChange"> |
|
||||
<view class="flex"> |
|
||||
<view class="flex-sub margin-tb-sm" v-for="(location,index) in locations" :key="location.value"> |
|
||||
<label class="flex justify-between align-center"> |
|
||||
<radio class="round margin-right-xs" :checked="index === schoolLocation" :value="location.value"></radio> |
|
||||
<text class="flex-sub" style="font-size: 34rpx;">{{ location.name }}</text> |
|
||||
</label> |
|
||||
</view> |
|
||||
</view> |
|
||||
</radio-group> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm"><span class="text-red padding-right-xs">*</span>当前体温(℃)</view> |
|
||||
<input placeholder="0" name="input" type="digit" v-model="animalHeat" /> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm">紧急联系人</view> |
|
||||
<view class="flex"> |
|
||||
<input placeholder="姓名" maxlength="6" class="flex flex-sub" name="input" type="text" v-model="emergencyName" /> |
|
||||
<input placeholder="联系方式" maxlength="11" class="flex flex-sub" name="input" type="number" v-model="emergencyPhone" /> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="cu-form-group flex flex-direction padding-tb"> |
|
||||
<view class="title padding-bottom-sm">备注(选填)</view> |
|
||||
<textarea placeholder="请填写具体情况..." name="input" v-model="remark" /> |
|
||||
|
|
||||
<!-- 上传图片 --> |
|
||||
<view class="grid col-4 grid-square flex-sub"> |
|
||||
<view class="bg-img" v-for="(item,index) in imgList" :key="index" @tap="ViewImage" :data-url="imgList[index]"> |
|
||||
<image :src="imgList[index]" mode="aspectFill"></image> |
|
||||
<view class="cu-tag bg-red" @tap.stop="DelImg" :data-index="index"> |
|
||||
<text class='cuIcon-close'></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="solids" @tap="ChooseImage" v-if="imgList.length<9"> |
|
||||
<text class='cuIcon-cameraadd'></text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</form> |
|
||||
<user-agreement @changeIntentions="changeIntentions" @changeIntentions1="changeIntentions1" @changeIntentions2="changeIntentions2"></user-agreement> |
|
||||
|
|
||||
<button class="bg-cyan margin primary-btn" hover-class="cc-active" @tap="handleHealthSign">确认提交</button> |
|
||||
<!-- 历史 --> |
|
||||
<button class="shadow round bg-cyan history-btn iconfont icon-history" hover-class="cc-active" @tap="openPage('/pages/my-code/my-code')"></button> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { |
|
||||
showToast |
|
||||
} from 'common/script/util'; |
|
||||
import { |
|
||||
HEALTH_SIGN,HEALTH_FILE,HEALTH_SIGN_HISTORY |
|
||||
} from 'api/api'; |
|
||||
import { |
|
||||
mapState, |
|
||||
mapMutations |
|
||||
} from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
district: '请选择当前所在地区', |
|
||||
address: '', |
|
||||
// status: [], |
|
||||
hospital: '', |
|
||||
tours: [{ |
|
||||
value: '0', |
|
||||
name: '否' |
|
||||
}, { |
|
||||
value: '1', |
|
||||
name: '是' |
|
||||
}], |
|
||||
touches: [{ |
|
||||
value: '0', |
|
||||
name: '否' |
|
||||
}, { |
|
||||
value: '1', |
|
||||
name: '是' |
|
||||
}], |
|
||||
overseas: [{ |
|
||||
value: '0', |
|
||||
name: '无' |
|
||||
}, { |
|
||||
value: '1', |
|
||||
name: '有' |
|
||||
}], |
|
||||
locations: [{ |
|
||||
value: '0', |
|
||||
name: '否' |
|
||||
}, { |
|
||||
value: '1', |
|
||||
name: '是' |
|
||||
}], |
|
||||
animalHeat: '', |
|
||||
healthTypeId: 0, |
|
||||
touchHubei: 0, |
|
||||
touchSick: 0, |
|
||||
touchOverseas: 0, |
|
||||
schoolLocation: 1, |
|
||||
emergencyName: '', |
|
||||
emergencyPhone: '', |
|
||||
remark: '', |
|
||||
fileIdList: [], |
|
||||
imgList: [], |
|
||||
agree: false, |
|
||||
agree1: false, |
|
||||
agree2: false, |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
onLoad() { |
|
||||
const startTime = +this.$moment() |
|
||||
.startOf('year') |
|
||||
.format('x'); |
|
||||
const endTime = +this.$moment() |
|
||||
.endOf('day') |
|
||||
.format('x'); |
|
||||
const params = { |
|
||||
param: { |
|
||||
startTime, |
|
||||
endTime, |
|
||||
token: this.token |
|
||||
} |
|
||||
}; |
|
||||
this.getHealthSignHistory(params); |
|
||||
}, |
|
||||
|
|
||||
computed: mapState('user', ['token', 'status','healthyInfo']), |
|
||||
|
|
||||
methods: { |
|
||||
...mapMutations('user', ['setHealthCode','setHealthyInfo']), |
|
||||
handleSelectLocation() { |
|
||||
const that = this; |
|
||||
uni.chooseLocation({ |
|
||||
success: function(res) { |
|
||||
console.log('位置名称:' + res.name); |
|
||||
console.log('详细地址:' + res.address); |
|
||||
that.district = res.address; |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
changeIntentions(data) { |
|
||||
this.agree = data; |
|
||||
}, |
|
||||
changeIntentions1(data) { |
|
||||
this.agree1 = data; |
|
||||
}, |
|
||||
changeIntentions2(data) { |
|
||||
this.agree2 = data; |
|
||||
}, |
|
||||
|
|
||||
// 状态 |
|
||||
StateChange: function(evt) { |
|
||||
for (let i = 0; i < this.status.length; i++) { |
|
||||
if (this.status[i].id === evt.target.value) { |
|
||||
this.healthTypeId = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 旅游 |
|
||||
TourChange: function(evt) { |
|
||||
for (let i = 0; i < this.tours.length; i++) { |
|
||||
if (this.tours[i].value === evt.target.value) { |
|
||||
this.touchHubei = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 接触 |
|
||||
TouchChange(evt) { |
|
||||
for (let b = 0; b < this.touches.length; b++) { |
|
||||
if (this.touches[b].value === evt.target.value) { |
|
||||
this.touchSick = b; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 境外 |
|
||||
TouchOverseasChange(evt) { |
|
||||
for (let i = 0; i < this.overseas.length; i++) { |
|
||||
if (this.overseas[i].value === evt.target.value) { |
|
||||
this.touchOverseas = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 学校所在地 |
|
||||
SchoolLocationChange(evt) { |
|
||||
for (let i = 0; i < this.locations.length; i++) { |
|
||||
if (this.locations[i].value === evt.target.value) { |
|
||||
this.schoolLocation = i; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
ChooseImage() { |
|
||||
uni.chooseImage({ |
|
||||
count: 1, //默认9 |
|
||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 |
|
||||
sourceType: ['album', 'camera'], //从相册选择 |
|
||||
success: (res) => { |
|
||||
if (this.imgList.length != 0) { |
|
||||
this.imgList = this.imgList.concat(res.tempFilePaths) |
|
||||
} else { |
|
||||
this.imgList = res.tempFilePaths |
|
||||
} |
|
||||
uni.uploadFile({ |
|
||||
usrl: `https://www.tall.wiki/gateway${HEALTH_FILE}`, |
|
||||
// url: `https://test.tall.wiki/gateway${HEALTH_FILE}`, |
|
||||
filePath: res.tempFilePaths[0], |
|
||||
fileType: 'image', |
|
||||
name: 'file', |
|
||||
success: (res) => { |
|
||||
const resData = JSON.parse(res.data) |
|
||||
const { |
|
||||
success, |
|
||||
code, |
|
||||
msg, |
|
||||
data |
|
||||
} = resData; |
|
||||
this.fileIdList.splice(-1,0,resData.data.fileId); |
|
||||
uni.showToast({ |
|
||||
title: '图片提交成功', |
|
||||
duration: 1000, |
|
||||
}); |
|
||||
},fail: (err) => { |
|
||||
console.log('uploadImage fail', err); |
|
||||
uni.showModal({ |
|
||||
content: err.errMsg, |
|
||||
showCancel: false |
|
||||
}); |
|
||||
} |
|
||||
}); |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
ViewImage(e) { |
|
||||
uni.previewImage({ |
|
||||
urls: this.imgList, |
|
||||
current: e.currentTarget.dataset.url |
|
||||
}); |
|
||||
}, |
|
||||
DelImg(e) { |
|
||||
uni.showModal({ |
|
||||
title: '删除', |
|
||||
content: '确定要删除这张图片吗?', |
|
||||
cancelText: '再想想', |
|
||||
confirmText: '再见', |
|
||||
success: res => { |
|
||||
if (res.confirm) { |
|
||||
this.imgList.splice(e.currentTarget.dataset.index, 1) |
|
||||
this.fileIdList.splice(e.currentTarget.dataset.index, 1) |
|
||||
} |
|
||||
} |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 申请健康码 |
|
||||
*/ |
|
||||
async handleHealthSign() { |
|
||||
try { |
|
||||
if (!this.checkRules()) return; |
|
||||
|
|
||||
const { |
|
||||
address, |
|
||||
animalHeat, |
|
||||
district, |
|
||||
healthTypeId, |
|
||||
hospital, |
|
||||
token, |
|
||||
touchHubei, |
|
||||
touchSick, |
|
||||
touchOverseas, |
|
||||
schoolLocation, |
|
||||
emergencyName, |
|
||||
emergencyPhone, |
|
||||
remark, |
|
||||
fileIdList, |
|
||||
agree1, |
|
||||
agree2, |
|
||||
} = this; |
|
||||
const params = { |
|
||||
param: { |
|
||||
address, |
|
||||
animalHeat, |
|
||||
district, |
|
||||
healthTypeId: healthTypeId + 1, |
|
||||
hospital, |
|
||||
token, |
|
||||
touchHubei, |
|
||||
touchSick, |
|
||||
touchOverseas, |
|
||||
schoolLocation, |
|
||||
emergencyName, |
|
||||
emergencyPhone, |
|
||||
remark, |
|
||||
fileIdList, |
|
||||
healthAgreement: agree1 ? 1 : 0, |
|
||||
selfFill: agree2 ? 1 : 0, |
|
||||
} |
|
||||
}; |
|
||||
const res = await this.$http.post(HEALTH_SIGN, params); |
|
||||
const { |
|
||||
success, |
|
||||
code, |
|
||||
msg, |
|
||||
data |
|
||||
} = res.data; |
|
||||
if (success && code === 200) { |
|
||||
uni.showToast({ |
|
||||
title: '申请健康码成功', |
|
||||
duration: 2000 |
|
||||
}); |
|
||||
this.success = true; |
|
||||
this.setHealthCode(data.healthCode) |
|
||||
uni.reLaunch({ |
|
||||
url: `/pages/index/index`, |
|
||||
}); |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: msg || '申请健康码失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
if (error.msg) { |
|
||||
uni.showToast({ |
|
||||
title: error.msg || '申请健康码失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 验证信息 |
|
||||
checkRules() { |
|
||||
const { |
|
||||
district, |
|
||||
address, |
|
||||
healthTypeId, |
|
||||
animalHeat, |
|
||||
agree, |
|
||||
agree1, |
|
||||
agree2 |
|
||||
} = this; |
|
||||
if (!district || district === '请选择当前所在地区') { |
|
||||
showToast('请选择当前所在地区'); |
|
||||
return; |
|
||||
} |
|
||||
if (!address) { |
|
||||
showToast('请输入当前所在地址'); |
|
||||
return; |
|
||||
} |
|
||||
if (healthTypeId < 0) { |
|
||||
showToast('请选择状态'); |
|
||||
return; |
|
||||
} |
|
||||
if (!animalHeat || animalHeat<30 || animalHeat>45) { |
|
||||
showToast('请输入正确的体温值(范围:30℃~45℃)'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree) { |
|
||||
showToast('请选择是否同意《用户服务协议》和《隐私政策》'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree1) { |
|
||||
showToast('请选择是否同意信息提交山西大学管理'); |
|
||||
return; |
|
||||
} |
|
||||
if (!agree2) { |
|
||||
showToast('请确定是否为本人填写'); |
|
||||
return; |
|
||||
} |
|
||||
return true; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 验证手机号格式 |
|
||||
* @param {string} phone 手机号 |
|
||||
*/ |
|
||||
verifyPhone(phone) { |
|
||||
const phoneExg = /^1\d{10}$/; |
|
||||
return phoneExg.test(phone); |
|
||||
}, |
|
||||
|
|
||||
// 获取健康打卡记录 |
|
||||
async getHealthSignHistory(params) { |
|
||||
try { |
|
||||
const res = await this.$http.post(HEALTH_SIGN_HISTORY, params); |
|
||||
const { |
|
||||
success, |
|
||||
code, |
|
||||
msg, |
|
||||
data |
|
||||
} = res.data; |
|
||||
if (success && code === 200) { |
|
||||
this.success = true; |
|
||||
this.setHealthyInfo(data[0]); |
|
||||
if(this.healthyInfo){ |
|
||||
this.address = this.healthyInfo.address; |
|
||||
this.district = this.healthyInfo.district; |
|
||||
this.healthTypeId = this.healthyInfo.healthTypeId - 1; |
|
||||
this.hospital = this.healthyInfo.hospital; |
|
||||
this.touchHubei = this.healthyInfo.touchHubei; |
|
||||
this.touchSick = this.healthyInfo.touchSick; |
|
||||
this.touchOverseas = this.healthyInfo.touchOverseas; |
|
||||
this.schoolLocation = this.healthyInfo.schoolLocation; |
|
||||
this.emergencyName = this.healthyInfo.emergencyName; |
|
||||
this.emergencyPhone = this.healthyInfo.emergencyPhone; |
|
||||
} |
|
||||
} else { |
|
||||
uni.showToast({ |
|
||||
title: msg || '获取健康打卡记录失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
if (error.msg) { |
|
||||
uni.showToast({ |
|
||||
title: error.msg || '获取健康打卡记录失败', |
|
||||
icon: 'none' |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.agree-box { |
|
||||
width: 70rpx; |
|
||||
} |
|
||||
|
|
||||
.agree-text { |
|
||||
line-height: 60rpx; |
|
||||
} |
|
||||
|
|
||||
.timer { |
|
||||
font-size: 34rpx !important; |
|
||||
color: $gray; |
|
||||
} |
|
||||
|
|
||||
.primary-btn { |
|
||||
border-radius: 15rpx; |
|
||||
} |
|
||||
|
|
||||
.history-btn { |
|
||||
position: fixed; |
|
||||
bottom: 40rpx; |
|
||||
right: 40rpx; |
|
||||
width: 96rpx; |
|
||||
height: 96rpx; |
|
||||
line-height: 96rpx; |
|
||||
padding: 0; |
|
||||
} |
|
||||
|
|
||||
.history-btn::after { |
|
||||
border: none; |
|
||||
} |
|
||||
</style> |
|
@ -1,79 +0,0 @@ |
|||||
<template> |
|
||||
<view class="margin-lr-lg"> |
|
||||
<view class="text-xxl margin-tb-lg text-center text-bold">用户服务协议</view> |
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
一、特别提示 |
|
||||
</view> |
|
||||
<view> |
|
||||
在此特别提醒您(用户)在使用tall健康码之前,请认真阅读本《tall健康码用户服务协议》 (以下简称“协议”),确保您充分理解本协议中各条款。请您审慎阅读并选择接受或不接 受本协议。除非您接受本协议所有条款,否则您无权注册、登录或使用本协议所涉服务。您的注册、登录、使用等行为将视为对本协议的接受,并同意接受本协议各项条款的约束。 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
二、账号注册 |
|
||||
</view> |
|
||||
<view>1、tall健康码以微信小程序方式提供服务,不需要用户刻意注册,我们会通过调用微信接口自动使用您在微信平台的身份信息。</view> |
|
||||
<view>2、本系统面向特定用户群体,在登录系统后,需要您填写在该群体下的特定用户信息,tall健康码需要搜集能识别用户身份的个人信息以便传控科技可以在必要时联系用户,或为用户提供更好的使用体验。</view> |
|
||||
</view> |
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
三、账户安全 |
|
||||
</view> |
|
||||
<view> |
|
||||
1、用户一旦注册/登录成功,成为tall健康码的用户,传控科技会尽最大限度保证用户的账户信息安全。 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
四、服务内容 |
|
||||
</view> |
|
||||
<view> |
|
||||
1、上报健康信息 |
|
||||
</view> |
|
||||
<view> |
|
||||
2、查询疫情情况 |
|
||||
</view> |
|
||||
<view> |
|
||||
3、查询个人打卡轨迹 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="text-content margin-bottom"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
五、服务的终止 |
|
||||
</view> |
|
||||
<view> |
|
||||
1、在下列情况下,传控科技有权终止向用户提供服务: |
|
||||
</view> |
|
||||
<view> |
|
||||
1)在用户违反本服务协议相关规定时,传控科技有权终止向该用户提供服务。 |
|
||||
</view> |
|
||||
<view> |
|
||||
2)用户不得通过程序或人工方式进行恶意注册,若发现用户有该类行为,传控科技将立即终止服务,并有权扣留账户内金额。 |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="text-content margin-bottom-xl"> |
|
||||
<view class="text-xl text-bold"> |
|
||||
六、免责与赔偿声明 |
|
||||
</view> |
|
||||
<view> |
|
||||
1、请用户在使用过程中,对自己的账号密码妥善保管,不要告知他人,避免给您带来不必要的损失。 |
|
||||
</view> |
|
||||
<view> |
|
||||
2、本协议最终解释权归安庆公共交通有限公司(简称“传控科技”)所有。 |
|
||||
</view> |
|
||||
<view> |
|
||||
3、本协议从 2020年3月1日起适用 |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
} |
|
||||
}, |
|
||||
} |
|
||||
</script> |
|
@ -1,143 +0,0 @@ |
|||||
<template> |
|
||||
<view class="padding-top-lg"> |
|
||||
<template v-if="!success"> |
|
||||
<view class="text-xxl padding text-center margin-top-xl"> |
|
||||
<text class="text-black text-bold">{{ site.siteName }}</text> |
|
||||
</view> |
|
||||
<button @tap="handleSign(siteId)" class="cu-btn lg bg-purple margin sign-btn">{{ typeText }}</button> |
|
||||
</template> |
|
||||
<view class="success" v-else> |
|
||||
<view class="cuIcon-roundcheckfill text-green"></view> |
|
||||
<text class="text-black margin-top">打卡成功</text> |
|
||||
<button @tap="goHome" class="cu-btn lg bg-purple margin-lg sign-btn">返回首页</button> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState, mapActions } from 'vuex'; |
|
||||
import { formatQuery } from 'utils/util'; |
|
||||
import { showToast, showLoading, hideLoading, showModal } from 'utils/ui'; |
|
||||
import { SCAN_SIGN } from 'api/api'; |
|
||||
|
|
||||
export default { |
|
||||
name: 'SignScan', |
|
||||
data() { |
|
||||
return { |
|
||||
siteId: '', |
|
||||
siteName: '', |
|
||||
success: false, |
|
||||
type: 0, // 0进 / 1出 |
|
||||
timer: null, |
|
||||
latitude: '', |
|
||||
longitude: '', |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: { |
|
||||
...mapState('site', ['site']), |
|
||||
...mapState('user', ['token']), |
|
||||
typeText() { |
|
||||
return this.type === 0 ? '进场打卡' : '出场打卡'; |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
onLoad(options) { |
|
||||
this.getLocation(); |
|
||||
this.init(options); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
...mapActions('site', ['sign', 'getSiteByQrId']), |
|
||||
|
|
||||
init(options) { |
|
||||
try { |
|
||||
const query = formatQuery(decodeURIComponent(options.scene)); |
|
||||
const { d, t } = query; |
|
||||
if (!d || !t) { |
|
||||
uni.showToast({ |
|
||||
title: '二维码参数错误', |
|
||||
icon: 'none', |
|
||||
duration: 3000, |
|
||||
}); |
|
||||
} |
|
||||
this.siteId = d; |
|
||||
this.type = +t; |
|
||||
this.getSignInfo({ param: { id: d, type: t } }); |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 获取场所的基本信息 |
|
||||
* @param {object} params 提交给后端的参数 |
|
||||
*/ |
|
||||
getSignInfo(params) { |
|
||||
this.timer && clearInterval(this.timer); |
|
||||
if (!this.token) { |
|
||||
this.timer = setTimeout(() => { |
|
||||
this.getSignInfo(params); |
|
||||
}, 100); |
|
||||
} else { |
|
||||
this.getSiteByQrId(params); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 获取当前的地址位置 |
|
||||
// 注意用国测局的数据 map只支持gcj02 |
|
||||
getLocation() { |
|
||||
showLoading(); |
|
||||
uni.getLocation({ |
|
||||
// type: 'gcj02', |
|
||||
success: res => { |
|
||||
this.longitude = res.longitude; |
|
||||
this.latitude = res.latitude; |
|
||||
hideLoading(); |
|
||||
console.log('当前位置的经度:' + res.longitude); |
|
||||
console.log('当前位置的纬度:' + res.latitude); |
|
||||
}, |
|
||||
fail: err => { |
|
||||
showModal('获取定位失败, 请打开GPS后重试'); |
|
||||
console.error(err); |
|
||||
}, |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 扫码打卡 |
|
||||
* @param {string} siteId 场所id |
|
||||
*/ |
|
||||
async handleSign(siteId) { |
|
||||
try { |
|
||||
if (!this.latitude || !this.longitude) { |
|
||||
showToast('位置信息有误, 请打开定位后重试'); |
|
||||
} |
|
||||
const params = { |
|
||||
param: { siteId, locationLatitude: this.latitude, locationLongitude: this.longitude }, |
|
||||
}; |
|
||||
await this.sign(params); |
|
||||
this.success = true; |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.sign-btn { |
|
||||
display: flex; |
|
||||
} |
|
||||
.success { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
padding-top: 100rpx; |
|
||||
|
|
||||
.cuIcon-roundcheckfill { |
|
||||
font-size: 200rpx; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,124 +0,0 @@ |
|||||
<template> |
|
||||
<view class="card radius shadow-warp bg-white"> |
|
||||
<view @tap="$refs.calendar.open()" class="card-head solid-bottom" hover-class="cc-active"> |
|
||||
<view class="card-head-avatar bg-orange"> |
|
||||
<view class="cuIcon-calendar"></view> |
|
||||
</view> |
|
||||
<view class="card-head-title">选择时间</view> |
|
||||
<view class="card-head-action" style="letter-spacing: 0.6">{{ date }}</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="menus-wrap"> |
|
||||
<button |
|
||||
:class="[ menu === item ? 'bg-purple': 'line-gray' ]" |
|
||||
:key="index" |
|
||||
@tap="handleClickMenu(item)" |
|
||||
class="cu-btn round" |
|
||||
v-for="(item, index) in menus" |
|
||||
>{{ item }}</button> |
|
||||
|
|
||||
</view> |
|
||||
<uni-calendar |
|
||||
:insert="false" |
|
||||
:range="true" |
|
||||
:show-month="true" |
|
||||
@confirm="handleChange" |
|
||||
ref="calendar" |
|
||||
/> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
const menus = ['昨天', '今天', '近7天', '近30天']; |
|
||||
|
|
||||
export default { |
|
||||
name: 'DateSelector', |
|
||||
data() { |
|
||||
const start = this.$moment().format('YYYY-MM-DD'); |
|
||||
const end = this.$moment().format('YYYY-MM-DD'); |
|
||||
return { |
|
||||
start, |
|
||||
end, |
|
||||
menu: '今天', |
|
||||
menus, |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: { |
|
||||
date() { |
|
||||
const { start, end } = this; |
|
||||
return start === end ? start : `${start} - ${end}`; |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
/** |
|
||||
* 日历确认选择了时间段 |
|
||||
* @param {object} value 日历返回对象 |
|
||||
*/ |
|
||||
handleChange(value) { |
|
||||
const { before, after } = value.range; |
|
||||
// 开始时间或者结束时间只有一个的时候 |
|
||||
// 就当选择了某一天 |
|
||||
if (before && !after) { |
|
||||
this.start = before; |
|
||||
this.end = before; |
|
||||
} else if (!before && after) { |
|
||||
this.end = after; |
|
||||
this.start = after; |
|
||||
} else if (before && after) { |
|
||||
this.start = before; |
|
||||
this.end = after; |
|
||||
} |
|
||||
this.menu = ''; |
|
||||
this.$emit('change', this.start, this.end); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 点选了快捷菜单 |
|
||||
* @param {string} menu 快捷时间菜单字符串 |
|
||||
*/ |
|
||||
handleClickMenu(menu) { |
|
||||
this.menu = menu; |
|
||||
let start = this.$moment().format('YYYY-MM-DD'); |
|
||||
let end = this.$moment().format('YYYY-MM-DD'); |
|
||||
switch (menu) { |
|
||||
case '昨天': |
|
||||
start = this.$moment() |
|
||||
.subtract(1, 'days') |
|
||||
.format('YYYY-MM-DD'); |
|
||||
end = this.$moment() |
|
||||
.subtract(1, 'days') |
|
||||
.format('YYYY-MM-DD'); |
|
||||
break; |
|
||||
case '近7天': |
|
||||
start = this.$moment() |
|
||||
.subtract(6, 'days') |
|
||||
.format('YYYY-MM-DD'); |
|
||||
end = this.$moment().format('YYYY-MM-DD'); |
|
||||
break; |
|
||||
case '近30天': |
|
||||
start = this.$moment() |
|
||||
.subtract(29, 'days') |
|
||||
.format('YYYY-MM-DD'); |
|
||||
end = this.$moment().format('YYYY-MM-DD'); |
|
||||
break; |
|
||||
default: |
|
||||
break; |
|
||||
} |
|
||||
this.start = start; |
|
||||
this.end = end; |
|
||||
this.$emit('change', start, end); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.menus-wrap { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: space-around; |
|
||||
padding: 40rpx; |
|
||||
} |
|
||||
</style> |
|
@ -1,90 +0,0 @@ |
|||||
<template> |
|
||||
<!-- 校园轨迹组件 --> |
|
||||
<view class="card radius shadow-warp bg-white"> |
|
||||
<view class="card-head solid-bottom"> |
|
||||
<view class="card-head-avatar bg-green"> |
|
||||
<view class="iconfont icon-wenduji_thermometer"></view> |
|
||||
</view> |
|
||||
<view class="card-head-title">健康上报</view> |
|
||||
<!-- <view class="card-head-action">icon</view> --> |
|
||||
</view> |
|
||||
|
|
||||
<view class="card-content"> |
|
||||
<view class="data-wrap"> |
|
||||
<view :key="index" class="data-item" v-for="(item, index) in shoolSignNumber"> |
|
||||
<view :class="[generateColor(item.name)]" class="data-text">{{ item.number }}</view> |
|
||||
<view class="data-title">{{ item.name }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState } from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
name: 'HealthData', |
|
||||
data() { |
|
||||
return {}; |
|
||||
}, |
|
||||
|
|
||||
computed: mapState('statistics', ['shoolSignNumber']), |
|
||||
|
|
||||
methods: { |
|
||||
/** |
|
||||
* 生成文本的颜色 |
|
||||
* @param {string} name 类目名称 |
|
||||
* @returns {string} color 颜色string |
|
||||
*/ |
|
||||
generateColor(name) { |
|
||||
let color = 'text-green'; |
|
||||
switch (name) { |
|
||||
case '发烧': |
|
||||
color = 'text-red'; |
|
||||
break; |
|
||||
case '其他': |
|
||||
color = 'text-purple'; |
|
||||
break; |
|
||||
case '未上报': |
|
||||
color = 'text-orange'; |
|
||||
break; |
|
||||
default: |
|
||||
color = 'text-green'; |
|
||||
break; |
|
||||
} |
|
||||
return color; |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.data-wrap { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: space-around; |
|
||||
padding: 40rpx 0; |
|
||||
|
|
||||
.data-item { |
|
||||
flex: 1; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
|
|
||||
.data-text { |
|
||||
font-size: 18px; |
|
||||
font-weight: 600; |
|
||||
margin-bottom: 4px; |
|
||||
} |
|
||||
|
|
||||
.data-title { |
|
||||
font-size: 13px; |
|
||||
color: $grey; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.icon-wenduji_thermometer { |
|
||||
font-size: 14px; |
|
||||
} |
|
||||
</style> |
|
@ -1,57 +0,0 @@ |
|||||
<template> |
|
||||
<!-- 校园轨迹组件 --> |
|
||||
<view class="card radius shadow-warp bg-white"> |
|
||||
<view class="card-head solid-bottom"> |
|
||||
<view class="card-head-avatar bg-purple"> |
|
||||
<view class="cuIcon-circle"></view> |
|
||||
</view> |
|
||||
<view class="card-head-title">校园打卡</view> |
|
||||
<!-- <view class="card-head-action">icon</view> --> |
|
||||
</view> |
|
||||
|
|
||||
<view class="card-content"> |
|
||||
<view class="map-wrap"> |
|
||||
<history-map :markers="markers" /> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState } from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
name: 'LocationMap', |
|
||||
|
|
||||
computed: { |
|
||||
...mapState('statistics', ['schoolSigns']), |
|
||||
|
|
||||
// 坐标标注点 |
|
||||
markers() { |
|
||||
if (!this.schoolSigns) return null; |
|
||||
const result = []; |
|
||||
this.schoolSigns.forEach(item => { |
|
||||
const content = `${item.siteName}\n${item.number}人`; |
|
||||
const obj = { |
|
||||
id: Math.random(), |
|
||||
latitude: item.latitude, |
|
||||
longitude: item.longitude, |
|
||||
iconPath: '/static/location.png', |
|
||||
callout: { |
|
||||
content, |
|
||||
display: 'ALWAYS', |
|
||||
color: '#fff', |
|
||||
padding: 4, |
|
||||
bgColor: '#0A97C6', |
|
||||
borderRadius: 2, |
|
||||
textAlign: 'center', |
|
||||
}, |
|
||||
}; |
|
||||
result.push(obj); |
|
||||
}); |
|
||||
|
|
||||
return result; |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
@ -1,80 +0,0 @@ |
|||||
<template> |
|
||||
<view class="padding"> |
|
||||
<!-- 日期组件 --> |
|
||||
<date-selector @change="getData" /> |
|
||||
<!-- 健康上报组件 --> |
|
||||
<health-data /> |
|
||||
<!-- 校园轨迹组件 --> |
|
||||
<location-map /> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapActions } from 'vuex'; |
|
||||
import DateSelector from './components/date-selector'; |
|
||||
import HealthData from './components/health-data'; |
|
||||
import LocationMap from './components/location-map'; |
|
||||
|
|
||||
export default { |
|
||||
name: 'Statistics', |
|
||||
components: { DateSelector, LocationMap, HealthData }, |
|
||||
|
|
||||
onLoad() { |
|
||||
// 初始加载今天的数据 |
|
||||
const start = this.$moment().format('YYYY-MM-DD'); |
|
||||
const end = this.$moment().format('YYYY-MM-DD'); |
|
||||
this.getData(start, end); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
...mapActions('statistics', ['getSchoolSigns', 'getSchoolSignsNumber']), |
|
||||
/** |
|
||||
* 获取数据 |
|
||||
* @param {string} start 开始时间 yy-mm-dd |
|
||||
* @param {string} end 截止时间 yy-mm-dd |
|
||||
*/ |
|
||||
getData(start, end) { |
|
||||
const startTime = |
|
||||
this.$moment(start) |
|
||||
.startOf('day') |
|
||||
.format('x') - 0; |
|
||||
const endTime = |
|
||||
this.$moment(end) |
|
||||
.endOf('day') |
|
||||
.format('x') - 0; |
|
||||
// 获取校园打卡的数据 |
|
||||
this.getSchoolSignsData(startTime, endTime); |
|
||||
// 获取健康上报数目数据 |
|
||||
this.getSchoolSignsNumberData(startTime, endTime); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 获取校园打卡的数据 |
|
||||
* @param {number} startTime 开始时间 |
|
||||
* @param {number} endTime 截止时间 |
|
||||
*/ |
|
||||
getSchoolSignsData(startTime, endTime) { |
|
||||
try { |
|
||||
const params = { param: { startTime, endTime } }; |
|
||||
this.getSchoolSigns(params); |
|
||||
} catch (error) { |
|
||||
console.log('getSchoolSignsData error: ', error); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 获取健康上报的数目数据 |
|
||||
* @param {number} startTime 开始时间 |
|
||||
* @param {number} endTime 截止时间 |
|
||||
*/ |
|
||||
getSchoolSignsNumberData(startTime, endTime) { |
|
||||
try { |
|
||||
const params = { param: { startTime, endTime } }; |
|
||||
this.getSchoolSignsNumber(params); |
|
||||
} catch (error) { |
|
||||
console.log('getSchoolSignsNumberData error: ', error); |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
@ -1,196 +0,0 @@ |
|||||
<template> |
|
||||
<view class="padding-lg"> |
|
||||
<template v-if="userInfo"> |
|
||||
<view class="padding bg-purple shadow-blur radius margin-bottom-xl"> |
|
||||
<view> |
|
||||
<view class="text-xl text-bold margin-bottom">个人申报信息</view> |
|
||||
<view class="text-lg text-grey"> |
|
||||
<text class="margin-right">{{ userInfo.name }}</text> |
|
||||
<text>{{ post }}</text> |
|
||||
</view> |
|
||||
<!-- <view class="text-lg text-grey"> |
|
||||
身份证: |
|
||||
<text>{{ userInfo.idCard }}</text> |
|
||||
</view> --> |
|
||||
<view class="text-lg text-grey"> |
|
||||
手机号: |
|
||||
<text>{{ userInfo.phone }}</text> |
|
||||
</view> |
|
||||
<view class="text-lg text-grey"> |
|
||||
学号: |
|
||||
<text>{{ userInfo.no }}</text> |
|
||||
</view> |
|
||||
<view class="text-lg text-grey"> |
|
||||
登记时间: |
|
||||
<text>{{ time }}</text> |
|
||||
</view> |
|
||||
<view class="text-lg text-grey"> |
|
||||
健康状态: |
|
||||
<text>{{ level }}</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="padding-top-xl"> |
|
||||
<image |
|
||||
:src="userInfo.healthCodeList[0].healthCode" |
|
||||
class="img solid radius" |
|
||||
mode="aspectFit" |
|
||||
/> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 返回首页 --> |
|
||||
<button |
|
||||
@tap="openPage('/pages/index/index')" |
|
||||
class="shadow round bg-purple index-btn iconfont icon-home" |
|
||||
hover-class="cc-active" |
|
||||
>首页</button> |
|
||||
|
|
||||
</template> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState, mapActions } from 'vuex'; |
|
||||
import { formatQuery } from 'utils/util'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
userInfo: null, |
|
||||
// userInfo: { |
|
||||
// healthCodeList: [ |
|
||||
// { |
|
||||
// healthCode: 'https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/gh_33446d7f7a26_430.jpg', |
|
||||
// healthLevel: 0, |
|
||||
// time: Date.now(), |
|
||||
// }, |
|
||||
// ], |
|
||||
// id: '123', |
|
||||
// idCard: '1407241989****019X', |
|
||||
// no: '080800009', |
|
||||
// phone: '18603454788', |
|
||||
// post: 0, |
|
||||
// name: '冯教授', |
|
||||
// }, |
|
||||
timer: null, |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: { |
|
||||
...mapState('user', ['token']), |
|
||||
|
|
||||
// 身份 |
|
||||
post() { |
|
||||
if (!this.userInfo) return '学生'; |
|
||||
let str = '学生'; |
|
||||
switch (this.userInfo.post) { |
|
||||
case 0: |
|
||||
str = '学生'; |
|
||||
break; |
|
||||
case 1: |
|
||||
str = '老师'; |
|
||||
break; |
|
||||
case 2: |
|
||||
str = '工作人员'; |
|
||||
break; |
|
||||
default: |
|
||||
break; |
|
||||
} |
|
||||
return str; |
|
||||
}, |
|
||||
|
|
||||
// 健康状态 登记 |
|
||||
level() { |
|
||||
if (!this.userInfo || !this.userInfo.healthCodeList) return '正常'; |
|
||||
let str = '正常'; |
|
||||
switch (this.userInfo.healthCodeList[0].healthLevel) { |
|
||||
case 0: |
|
||||
str = '正常'; |
|
||||
break; |
|
||||
case 1: |
|
||||
str = '隔离中或疑似'; |
|
||||
break; |
|
||||
case 2: |
|
||||
str = '确诊'; |
|
||||
break; |
|
||||
default: |
|
||||
break; |
|
||||
} |
|
||||
return str; |
|
||||
}, |
|
||||
|
|
||||
time() { |
|
||||
if (!this.userInfo || !this.userInfo.healthCodeList) return; |
|
||||
return this.$moment(this.userInfo.healthCodeList[0].time - 0).format('YYYY-MM-DD HH:mm'); |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
onLoad(options) { |
|
||||
this.init(options); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
...mapActions('user', ['getUserInfo']), |
|
||||
|
|
||||
init(options) { |
|
||||
try { |
|
||||
console.log('options: ', options); |
|
||||
const query = formatQuery(decodeURIComponent(options.scene)); |
|
||||
const { d } = query; |
|
||||
if (!d) { |
|
||||
uni.showToast({ |
|
||||
title: '二维码参数错误', |
|
||||
icon: 'none', |
|
||||
duration: 3000, |
|
||||
}); |
|
||||
} |
|
||||
const params = { param: { userId: d } }; |
|
||||
this.getUserInfoData(params); |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 获取场所的基本信息 |
|
||||
* @param {object} params 提交给后端的参数 |
|
||||
*/ |
|
||||
async getUserInfoData(params) { |
|
||||
this.timer && clearInterval(this.timer); |
|
||||
if (!this.token) { |
|
||||
this.timer = setTimeout(() => { |
|
||||
this.getUserInfoData(params); |
|
||||
}, 100); |
|
||||
} else { |
|
||||
this.userInfo = await this.getUserInfo(params); |
|
||||
if (!this.userInfo.healthCodeList.length) { |
|
||||
showToast('健康码信息有误, 请重新生成'); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.img { |
|
||||
display: block; |
|
||||
width: 400rpx; |
|
||||
height: 400rpx; |
|
||||
margin: 0 auto; |
|
||||
} |
|
||||
|
|
||||
.index-btn { |
|
||||
position: fixed; |
|
||||
bottom: 40rpx; |
|
||||
right: 40rpx; |
|
||||
width: 96rpx; |
|
||||
height: 96rpx; |
|
||||
line-height: 96rpx; |
|
||||
padding: 0; |
|
||||
} |
|
||||
|
|
||||
.index-btn::after { |
|
||||
border: none; |
|
||||
} |
|
||||
</style> |
|
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 132 KiB |
Before Width: | Height: | Size: 207 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 4.1 KiB |
@ -1,12 +1,11 @@ |
|||||
import Vue from 'vue'; |
import Vue from 'vue'; |
||||
import Vuex from 'vuex'; |
import Vuex from 'vuex'; |
||||
import user from './modules/user/index'; |
import user from './modules/user/index'; |
||||
import site from './modules/site/index'; |
|
||||
import statistics from './modules/statistics/index'; |
|
||||
|
|
||||
Vue.use(Vuex); |
Vue.use(Vuex); |
||||
const store = new Vuex.Store({ |
const store = new Vuex.Store({ |
||||
modules: { user, site, statistics }, |
modules: { user }, |
||||
}); |
}); |
||||
|
|
||||
export default store; |
export default store; |
||||
|
@ -1,74 +0,0 @@ |
|||||
import { http } from 'plugins/request/index'; |
|
||||
import { showLoading, hideLoading, showToast, showModal } from 'utils/ui'; |
|
||||
import { SITES_INFO, SCAN_SIGN, SITE } from 'api/api'; |
|
||||
|
|
||||
const actions = { |
|
||||
/** |
|
||||
* 获取所有场所信息 |
|
||||
* @param {*} commit |
|
||||
*/ |
|
||||
getSites({ commit }) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
showLoading(); |
|
||||
http |
|
||||
.post(SITES_INFO) |
|
||||
.then(res => { |
|
||||
hideLoading(); |
|
||||
const { data } = res.data; |
|
||||
commit('setSites', data); |
|
||||
resolve(data); |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
hideLoading(); |
|
||||
showToast(data.msg || '获取场所信息失败'); |
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 根据二维码id获取场所信息 |
|
||||
* @param {*} commit |
|
||||
* @param {object} params 提交服务端的数据 |
|
||||
*/ |
|
||||
getSiteByQrId({ commit }, params) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
http |
|
||||
.post(SITE, params) |
|
||||
.then(res => { |
|
||||
const { data } = res.data; |
|
||||
commit('setSite', data); |
|
||||
resolve(data); |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
showToast(data.msg || '获取场所信息失败'); |
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 扫码打卡 提交打卡记录 |
|
||||
* @param {*} commit |
|
||||
* @param {object} params 提交服务端的数据 |
|
||||
*/ |
|
||||
sign({ commit }, params) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
showLoading(); |
|
||||
http |
|
||||
.post(SCAN_SIGN, params) |
|
||||
.then(res => { |
|
||||
hideLoading(); |
|
||||
const { data } = res.data; |
|
||||
resolve(data); |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
hideLoading(); |
|
||||
showToast(data.msg || '打卡失败'); |
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}; |
|
||||
|
|
||||
export default actions; |
|
@ -1,5 +0,0 @@ |
|||||
import state from './state'; |
|
||||
import mutations from './mutations'; |
|
||||
import actions from './actions.js'; |
|
||||
|
|
||||
export default { namespaced: true, state, actions, mutations }; |
|
@ -1,21 +0,0 @@ |
|||||
const mutations = { |
|
||||
/** |
|
||||
* 设置所有的场所值 |
|
||||
* @param {object} state |
|
||||
* @param {array} data |
|
||||
*/ |
|
||||
setSites(state, data) { |
|
||||
state.sites = data || []; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 设置当前场所的信息 |
|
||||
* @param {object} state |
|
||||
* @param {object} data |
|
||||
*/ |
|
||||
setSite(state, data) { |
|
||||
state.site = data || null; |
|
||||
}, |
|
||||
}; |
|
||||
|
|
||||
export default mutations; |
|
@ -1,6 +0,0 @@ |
|||||
const state = { |
|
||||
site: null, // 当前场所信息
|
|
||||
sites: [], // 所有的场所信息
|
|
||||
}; |
|
||||
|
|
||||
export default state; |
|
@ -1,79 +0,0 @@ |
|||||
import { http } from 'plugins/request/index'; |
|
||||
import { showLoading, hideLoading, showToast } from 'utils/ui'; |
|
||||
import { USER_SIGNS, SCHOOL_SIGNS, HEALTH_TYPE_STATISTICS } from 'api/api'; |
|
||||
|
|
||||
const actions = { |
|
||||
/** |
|
||||
* 获取用户的打卡记录 |
|
||||
* @param {*} commit |
|
||||
* @param {object} params 提交给后台的完整参数 |
|
||||
*/ |
|
||||
getUserSigns({ commit }, params) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
showLoading(); |
|
||||
http |
|
||||
.post(USER_SIGNS, params) |
|
||||
.then(res => { |
|
||||
hideLoading(); |
|
||||
const { data } = res.data; |
|
||||
commit('setUserSigns', data); |
|
||||
resolve(data); |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
hideLoading(); |
|
||||
showToast(data.msg || '查询数据失败'); |
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 获取校园打卡记录 展示热力图 |
|
||||
* @param {*} commit |
|
||||
* @param {object} params 提交服务端的完整参数 |
|
||||
*/ |
|
||||
getSchoolSigns({ commit }, params) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
showLoading(); |
|
||||
http |
|
||||
.post(SCHOOL_SIGNS, params) |
|
||||
.then(res => { |
|
||||
hideLoading(); |
|
||||
const { data } = res.data; |
|
||||
commit('setSchoolSigns', data); |
|
||||
resolve(data); |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
hideLoading(); |
|
||||
showToast(data.msg || '获取数据失败'); |
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 获取校园健康上报的 数据数目 |
|
||||
* @param {*} commit |
|
||||
* @param {object} params 提交给服务端的完整数据 |
|
||||
*/ |
|
||||
getSchoolSignsNumber({ commit }, params) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
showLoading(); |
|
||||
http |
|
||||
.post(HEALTH_TYPE_STATISTICS, params) |
|
||||
.then(res => { |
|
||||
hideLoading(); |
|
||||
const { data } = res.data; |
|
||||
commit('setShoolSignNumber', data); |
|
||||
resolve(data); |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
hideLoading(); |
|
||||
showToast(data.msg || '获取健康上报数据失败'); |
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}; |
|
||||
|
|
||||
export default actions; |
|
@ -1,5 +0,0 @@ |
|||||
import state from './state'; |
|
||||
import mutations from './mutations'; |
|
||||
import actions from './actions.js'; |
|
||||
|
|
||||
export default { namespaced: true, state, actions, mutations }; |
|
@ -1,36 +0,0 @@ |
|||||
const mutations = { |
|
||||
/** |
|
||||
* 设置userSigns 自己的打卡记录数据 |
|
||||
* @param {*} state |
|
||||
* @param {array} data |
|
||||
*/ |
|
||||
setUserSigns(state, data) { |
|
||||
state.userSigns = data || []; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 设置shoolSigns 校园的打卡记录 |
|
||||
* @param {*} state |
|
||||
* @param {array} data |
|
||||
*/ |
|
||||
setSchoolSigns(state, data) { |
|
||||
state.schoolSigns = data || []; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 设置校园健康统计数目 shoolSignNumbers |
|
||||
* @param {*} state |
|
||||
* @param {array} data |
|
||||
*/ |
|
||||
setShoolSignNumber(state, data) { |
|
||||
const arr = [ |
|
||||
{ name: '正常', number: '-' }, |
|
||||
{ name: '发烧', number: '-' }, |
|
||||
{ name: '其他', number: '-' }, |
|
||||
{ name: '未上报', number: '-' }, |
|
||||
]; |
|
||||
state.shoolSignNumber = data || arr; |
|
||||
}, |
|
||||
}; |
|
||||
|
|
||||
export default mutations; |
|
@ -1,12 +0,0 @@ |
|||||
const state = { |
|
||||
userSigns: [], // 用户个人打卡记录
|
|
||||
schoolSigns: [], // 校园的打卡记录
|
|
||||
shoolSignNumber: [ |
|
||||
{ name: '正常', number: '-' }, |
|
||||
{ name: '发烧', number: '-' }, |
|
||||
{ name: '其他', number: '-' }, |
|
||||
{ name: '未上报', number: '-' }, |
|
||||
], // 健康上报数目统计
|
|
||||
}; |
|
||||
|
|
||||
export default state; |
|
@ -1,145 +1,9 @@ |
|||||
import { showLoading, hideLoading, showModal, showToast } from 'utils/ui'; |
import { showLoading, hideLoading, showModal, showToast } from 'utils/ui'; |
||||
import { mpLogin, signIn, ddLogin } from 'utils/user'; |
import { mpLogin, signIn, ddLogin } from 'utils/user'; |
||||
import { UPDATE_USER, USER_ID_EXCHANGE_TOKEN } from 'api/user'; |
|
||||
import { GET_USER_INFO, HEALTH_TYPE_STATUS } from 'api/api'; |
|
||||
import { http } from 'plugins/request/index'; |
import { http } from 'plugins/request/index'; |
||||
|
|
||||
const actions = { |
const actions = { |
||||
// 登录
|
|
||||
login({ commit }) { |
|
||||
return new Promise(async (resolve, reject) => { |
|
||||
let params = null; |
|
||||
// #ifdef MP-WEIXIN
|
|
||||
params = await mpLogin(); |
|
||||
// #endif
|
|
||||
// #ifdef MP-DINGTALK
|
|
||||
params = await ddLogin(); |
|
||||
// #endif
|
|
||||
signIn(params) |
|
||||
.then(data => { |
|
||||
console.log('login data: ', data); |
|
||||
commit('setToken', data.token); |
|
||||
commit('setUser', data); |
|
||||
|
|
||||
resolve(data); |
|
||||
}) |
|
||||
.catch(err => { |
|
||||
console.log('login err: ', err); |
|
||||
showModal(err.msg || '登录失败'); |
|
||||
reject(err); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* signIn 提交登录信息 |
|
||||
* @param {any} commit |
|
||||
* @param {string} params 登录提交的参数 |
|
||||
*/ |
|
||||
signIn({ commit }, params) { |
|
||||
return signIn(params) |
|
||||
.then(data => { |
|
||||
commit('setToken', data.token); |
|
||||
commit('setUser', data); |
|
||||
}) |
|
||||
.catch(err => showModal(err)); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 上传用户的微信信息 |
|
||||
* @param {*} commit |
|
||||
* @param {object} params 提交的完整数据 |
|
||||
*/ |
|
||||
updateUserInfo({ commit }, params) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
http |
|
||||
.post(UPDATE_USER, params) |
|
||||
.then(res => { |
|
||||
const { data } = res.data; |
|
||||
commit('updateUser', { type: 'wxInfo', value: params }); |
|
||||
resolve(data); |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
showToast(data.msg || '保存用户信息失败'); |
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 查询基本信息 |
|
||||
* @param {*} commit |
|
||||
* @param {object} params 提交的完整数据 |
|
||||
*/ |
|
||||
getUserInfo({ commit }, params) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
showLoading(); |
|
||||
http |
|
||||
.post(GET_USER_INFO, params) |
|
||||
.then(res => { |
|
||||
hideLoading(); |
|
||||
const { data } = res.data; |
|
||||
resolve(data); |
|
||||
// 获取自己的信息采取设置
|
|
||||
// 扫别人健康码的时候不用设置
|
|
||||
if (params.param.token) { |
|
||||
commit('setUserInfo', data); |
|
||||
} |
|
||||
|
|
||||
if (data.healthCodeList && data.healthCodeList.length > 0) { |
|
||||
const oldCode = data.healthCodeList[0].healthCode; |
|
||||
commit('setHealthCode', oldCode); |
|
||||
} |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
hideLoading(); |
|
||||
// showToast(data.msg || '查询个人信息失败');
|
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 查询健康状态类型 |
|
||||
* @param {*} commit |
|
||||
*/ |
|
||||
async getHealthTypeStatus({ commit }) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
http |
|
||||
.post(HEALTH_TYPE_STATUS) |
|
||||
.then(res => { |
|
||||
const { data } = res.data; |
|
||||
resolve(data); |
|
||||
commit('setStatus', data); |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
showToast(data.msg || '查询健康类型失败'); |
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 通过userId换取token |
|
||||
* @param {*} commit |
|
||||
* @param {object} params 提交的完整参数 |
|
||||
*/ |
|
||||
getTokenByUserId({ commit }, params) { |
|
||||
return new Promise((resolve, reject) => { |
|
||||
http |
|
||||
.get(USER_ID_EXCHANGE_TOKEN, params) |
|
||||
.then(res => { |
|
||||
const { data } = res.data; |
|
||||
commit('setToken', data.token); |
|
||||
commit('setUser', data); |
|
||||
resolve(data); |
|
||||
}) |
|
||||
.catch(data => { |
|
||||
showToast(data.msg || '获取token失败'); |
|
||||
reject(data); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}; |
}; |
||||
|
|
||||
export default actions; |
export default actions; |
||||
|
@ -1,11 +1,6 @@ |
|||||
const state = { |
const state = { |
||||
token: '', |
token: '', |
||||
user: null, |
user: null, |
||||
healthCode: '', // 健康码
|
|
||||
userInfo: null, // 个人基本信息
|
|
||||
healthyInfo: null, // 健康打卡信息
|
|
||||
pagePath: '', //页面跳转参数
|
|
||||
status: [], // 健康状态类型
|
|
||||
}; |
}; |
||||
|
|
||||
export default state; |
export default state; |
||||
|