增加轮休申请 临时外出申请菜单
This commit is contained in:
parent
5921d123cf
commit
69c2047690
283
src/pages.json
283
src/pages.json
|
|
@ -1,136 +1,149 @@
|
|||
{
|
||||
"pages": [
|
||||
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
// {
|
||||
// "path": "pages/index/index",
|
||||
// "style": {
|
||||
// "navigationBarTitleText": "uni-app"
|
||||
// }
|
||||
// },
|
||||
// 首页
|
||||
{
|
||||
"path": "pages/login/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "首页"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/face/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "人脸录入",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/clock/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "考勤打卡",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
// 我的
|
||||
{
|
||||
"path": "pages/my/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的"
|
||||
}
|
||||
},
|
||||
// 出差报备
|
||||
{
|
||||
"path": "pages/evection/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "出差报备"
|
||||
}
|
||||
},
|
||||
// 报备记录列表
|
||||
{
|
||||
"path": "pages/evection/recordList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "报备记录"
|
||||
}
|
||||
},
|
||||
// 报备记录列表
|
||||
{
|
||||
"path": "pages/evection/details",
|
||||
"style": {
|
||||
"navigationBarTitleText": "出差报备详情"
|
||||
}
|
||||
},
|
||||
// 休假报备
|
||||
{
|
||||
"path": "pages/holiday/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "休假报备"
|
||||
}
|
||||
},
|
||||
// 报备记录列表
|
||||
{
|
||||
"path": "pages/holiday/recordList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "报备记录"
|
||||
}
|
||||
},
|
||||
// 报备记录列表
|
||||
{
|
||||
"path": "pages/holiday/details",
|
||||
"style": {
|
||||
"navigationBarTitleText": "休假报备详情"
|
||||
}
|
||||
},
|
||||
//修改密码
|
||||
{
|
||||
"path": "pages/password/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "修改密码"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/panel/index",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : "面板",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/clock/detail",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : "人脸考勤",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tabBar": {
|
||||
"color": "#2c2c2c",
|
||||
"selectedColor": "#1296db",
|
||||
"borderStyle": "black",
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"iconWidth": "24px",
|
||||
"list": [{
|
||||
"pagePath": "pages/index/index",
|
||||
"text": "首页",
|
||||
"iconPath": "static/home.png",
|
||||
"selectedIconPath": "static/homeSelected.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/my/index",
|
||||
"text": "我的",
|
||||
"iconPath": "static/workSpace.png",
|
||||
"selectedIconPath": "static/workSpaceSelected.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8"
|
||||
}
|
||||
}
|
||||
"pages": [
|
||||
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||
// {
|
||||
// "path": "pages/index/index",
|
||||
// "style": {
|
||||
// "navigationBarTitleText": "uni-app"
|
||||
// }
|
||||
// },
|
||||
// 首页
|
||||
{
|
||||
"path": "pages/login/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "首页"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/face/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "人脸录入",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/clock/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "考勤打卡",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
// 我的
|
||||
{
|
||||
"path": "pages/my/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "我的"
|
||||
}
|
||||
},
|
||||
// 出差报备
|
||||
{
|
||||
"path": "pages/evection/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "出差报备"
|
||||
}
|
||||
},
|
||||
// 报备记录列表
|
||||
{
|
||||
"path": "pages/evection/recordList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "报备记录"
|
||||
}
|
||||
},
|
||||
// 报备记录列表
|
||||
{
|
||||
"path": "pages/evection/details",
|
||||
"style": {
|
||||
"navigationBarTitleText": "出差报备详情"
|
||||
}
|
||||
},
|
||||
// 休假报备
|
||||
{
|
||||
"path": "pages/holiday/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "休假报备"
|
||||
}
|
||||
},
|
||||
// 报备记录列表
|
||||
{
|
||||
"path": "pages/holiday/recordList",
|
||||
"style": {
|
||||
"navigationBarTitleText": "报备记录"
|
||||
}
|
||||
},
|
||||
// 报备记录列表
|
||||
{
|
||||
"path": "pages/holiday/details",
|
||||
"style": {
|
||||
"navigationBarTitleText": "休假报备详情"
|
||||
}
|
||||
},
|
||||
//修改密码
|
||||
{
|
||||
"path": "pages/password/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "修改密码"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/panel/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "面板",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/clock/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "人脸考勤",
|
||||
"navigationBarBackgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
// 轮休申请
|
||||
{
|
||||
"path": "pages/stagger-holidays/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "轮休申请"
|
||||
}
|
||||
},
|
||||
// 临时外出申请
|
||||
{
|
||||
"path": "pages/temporary-outing/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "临时外出申请"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tabBar": {
|
||||
"color": "#2c2c2c",
|
||||
"selectedColor": "#1296db",
|
||||
"borderStyle": "black",
|
||||
"backgroundColor": "#FFFFFF",
|
||||
"iconWidth": "24px",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/index/index",
|
||||
"text": "首页",
|
||||
"iconPath": "static/home.png",
|
||||
"selectedIconPath": "static/homeSelected.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/my/index",
|
||||
"text": "我的",
|
||||
"iconPath": "static/workSpace.png",
|
||||
"selectedIconPath": "static/workSpaceSelected.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,217 +1,233 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- 用户信息区域 -->
|
||||
<view class="user-info">
|
||||
<image class="avatar" :src="userInfo.avatar" mode="aspectFill"></image>
|
||||
<view class="user-detail">
|
||||
<text class="username">{{userInfo.name}}</text>
|
||||
<text class="phone">{{userInfo.phone}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="container">
|
||||
<!-- 用户信息区域 -->
|
||||
<view class="user-info">
|
||||
<image class="avatar" :src="userInfo.avatar" mode="aspectFill"></image>
|
||||
<view class="user-detail">
|
||||
<text class="username">{{ userInfo.name }}</text>
|
||||
<text class="phone">{{ userInfo.phone }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 插画区域 -->
|
||||
<view class="illustration">
|
||||
<image src="/static/banner.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
<!-- 插画区域 -->
|
||||
<view class="illustration">
|
||||
<image src="/static/banner.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
|
||||
<!-- 申请报备区域 -->
|
||||
<view class="section">
|
||||
<view class="section-title">申请报备</view>
|
||||
<view class="grid-box">
|
||||
<view class="grid-item" @click="handleNavigate('/pages/evection/index')">
|
||||
<image src="/static/evection.png" mode="aspectFit"></image>
|
||||
<text class="centered-text">出差报备</text>
|
||||
</view>
|
||||
<view class="grid-item" @click="handleNavigate('/pages/holiday/index')">
|
||||
<image src="/static/holiday.png" mode="aspectFit"></image>
|
||||
<text class="centered-text">休假报备</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 申请报备区域 -->
|
||||
<view class="section">
|
||||
<view class="section-title">申请报备</view>
|
||||
<view class="grid-box">
|
||||
<view class="grid-item" @click="handleNavigate('/pages/evection/index')">
|
||||
<image src="/static/evection.png" mode="aspectFit"></image>
|
||||
<text class="centered-text">出差报备</text>
|
||||
</view>
|
||||
<view class="grid-item" @click="handleNavigate('/pages/holiday/index')">
|
||||
<image src="/static/holiday.png" mode="aspectFit"></image>
|
||||
<text class="centered-text">休假报备</text>
|
||||
</view>
|
||||
<view class="grid-item" @click="handleNavigate('/pages/stagger-holidays/index')">
|
||||
<image src="/static/lx_icon.png" mode="aspectFit"></image>
|
||||
<text class="centered-text">轮休申请</text>
|
||||
</view>
|
||||
<view class="grid-item" @click="handleNavigate('/pages/temporary-outing/index')">
|
||||
<image src="/static/go_out.png" mode="aspectFit"></image>
|
||||
<text class="centered-text">临时外出申请</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 考勤打卡区域 -->
|
||||
<view class="section" v-if="isPd==1">
|
||||
<view class="section-title">考勤打卡</view>
|
||||
<view class="grid-box">
|
||||
<view class="grid-item" @click="handleNavigate('/pages/clock/index')">
|
||||
<image src="/static/clockIn.png" mode="aspectFit"></image>
|
||||
<text class="centered-text">考勤打卡</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 考勤打卡区域 -->
|
||||
<view class="section" v-if="isPd == 1">
|
||||
<view class="section-title">考勤打卡</view>
|
||||
<view class="grid-box">
|
||||
<view class="grid-item" @click="handleNavigate('/pages/clock/index')">
|
||||
<image src="/static/clockIn.png" mode="aspectFit"></image>
|
||||
<text class="centered-text">考勤打卡</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {selectFaceInfo,getUsetInfo} from "@/api/index.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: {
|
||||
token: '',
|
||||
userId: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
avatar: '/static/defaultHead.png'
|
||||
},
|
||||
isPd: 0,
|
||||
}
|
||||
import { selectFaceInfo, getUsetInfo } from '@/api/index.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: {
|
||||
token: '',
|
||||
userId: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
avatar: '/static/defaultHead.png',
|
||||
},
|
||||
isPd: 0,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 在组件挂载后读取存储的数据
|
||||
this.userInfo.token = uni.getStorageSync('token') || ''
|
||||
this.userInfo.userId = uni.getStorageSync('userId') || ''
|
||||
this.userInfo.name = uni.getStorageSync('username') || ''
|
||||
this.userInfo.phone = uni.getStorageSync('phone') || ''
|
||||
if (/^1\d{10}$/.test(this.userInfo.phone)) {
|
||||
this.userInfo.phone = this.maskPhoneNumber(this.userInfo.phone)
|
||||
}
|
||||
this.isPd = uni.getStorageSync('isPd') || 0
|
||||
console.log('isPd', this.isPd)
|
||||
if (Number(this.isPd) !== 0) {
|
||||
this.selectFaceInfoEvent()
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {
|
||||
this.getUsetInfoEvent()
|
||||
},
|
||||
methods: {
|
||||
// 获取用户信息
|
||||
getUsetInfoEvent() {
|
||||
getUsetInfo(uni.getStorageSync('userId')).then((res) => {
|
||||
if (res.res == 1) {
|
||||
if (res.obj && res.obj.appliedFace) {
|
||||
if (
|
||||
res.obj.appliedFace == '' ||
|
||||
res.obj.appliedFace == null ||
|
||||
res.obj.appliedFace == 'null'
|
||||
) {
|
||||
this.userInfo.avatar = '/static/defaultHead.png'
|
||||
} else {
|
||||
this.userInfo.avatar = res.obj.appliedFace
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
mounted() {
|
||||
// 在组件挂载后读取存储的数据
|
||||
this.userInfo.token = uni.getStorageSync('token') || '';
|
||||
this.userInfo.userId = uni.getStorageSync('userId') || '';
|
||||
this.userInfo.name = uni.getStorageSync('username') || '';
|
||||
this.userInfo.phone = uni.getStorageSync('phone') || '';
|
||||
if(/^1\d{10}$/.test(this.userInfo.phone)) {
|
||||
this.userInfo.phone = this.maskPhoneNumber(this.userInfo.phone)
|
||||
}
|
||||
this.isPd = uni.getStorageSync('isPd') || 0;
|
||||
console.log("isPd", this.isPd)
|
||||
if(Number(this.isPd) !== 0) {
|
||||
this.selectFaceInfoEvent()
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
onShow() {
|
||||
this.getUsetInfoEvent()
|
||||
},
|
||||
methods: {
|
||||
// 获取用户信息
|
||||
getUsetInfoEvent() {
|
||||
getUsetInfo(uni.getStorageSync('userId')).then(res => {
|
||||
if(res.res == 1) {
|
||||
if(res.obj && res.obj.appliedFace) {
|
||||
if(res.obj.appliedFace == '' || res.obj.appliedFace == null || res.obj.appliedFace == 'null') {
|
||||
this.userInfo.avatar = '/static/defaultHead.png'
|
||||
}else{
|
||||
this.userInfo.avatar = res.obj.appliedFace
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
maskPhoneNumber(phoneNumber) {
|
||||
return phoneNumber.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||
},
|
||||
|
||||
// 提示用户录入人脸
|
||||
selectFaceInfoEvent() {
|
||||
selectFaceInfo().then(res => {
|
||||
if(res.obj == '103') {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您当前还未录入人脸信息,请先录入',
|
||||
success: res => {
|
||||
if(res.confirm) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/face/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
handleNavigate(url) {
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
maskPhoneNumber(phoneNumber) {
|
||||
return phoneNumber.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
|
||||
},
|
||||
|
||||
// 提示用户录入人脸
|
||||
selectFaceInfoEvent() {
|
||||
selectFaceInfo().then((res) => {
|
||||
if (res.obj == '103') {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您当前还未录入人脸信息,请先录入',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/face/index',
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleNavigate(url) {
|
||||
uni.navigateTo({
|
||||
url,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
padding: 30rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
padding: 30rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.user-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.user-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.username {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
.username {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.phone {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
.phone {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.illustration {
|
||||
margin: 40rpx 0;
|
||||
text-align: center;
|
||||
.illustration {
|
||||
margin: 40rpx 0;
|
||||
text-align: center;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
}
|
||||
}
|
||||
image {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 40rpx;
|
||||
.section {
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.grid-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -10rpx;
|
||||
.grid-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
// margin: 0 -10rpx;
|
||||
|
||||
.grid-item {
|
||||
width: calc(30% - 20rpx);
|
||||
margin: 10rpx;
|
||||
padding: 30rpx;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
.grid-item {
|
||||
// width: calc(30% - 20rpx);
|
||||
width: calc((100% - 10rpx) / 2);
|
||||
margin-right: 10rpx;
|
||||
margin-top: 10rpx;
|
||||
padding: 30rpx;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
image {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
image {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.centered-text {
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
.grid-item:nth-child(2n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.centered-text {
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,440 +1,454 @@
|
|||
<template>
|
||||
<view class="login-container">
|
||||
<!-- 顶部图标和标题 -->
|
||||
<view class="header">
|
||||
<image class="logo" src="/static/logo.png" mode="aspectFit"></image>
|
||||
<text class="title">欢迎登录考勤系统</text>
|
||||
</view>
|
||||
<view class="login-container">
|
||||
<!-- 顶部图标和标题 -->
|
||||
<view class="header">
|
||||
<image class="logo" src="/static/logo.png" mode="aspectFit"></image>
|
||||
<text class="title">欢迎登录考勤系统</text>
|
||||
</view>
|
||||
|
||||
<!-- 表单区域 -->
|
||||
<view class="form-box">
|
||||
<!-- 手机号输入框 -->
|
||||
<view class="menu-item-left">
|
||||
<image style="width: 20px; height: 20px; margin-right: 5px; vertical-align: middle;"
|
||||
src="/static/phone.png" mode="aspectFit"></image>
|
||||
<text class="menu-text" style="vertical-align: middle;">手机号</text>
|
||||
</view>
|
||||
<view class="input-item">
|
||||
<uni-icons type="person" size="20" color="#999"></uni-icons>
|
||||
<input type="number" v-model="form.phone" placeholder="请输入手机号" maxlength="11" />
|
||||
</view>
|
||||
<!-- 表单区域 -->
|
||||
<view class="form-box">
|
||||
<!-- 手机号输入框 -->
|
||||
<view class="menu-item-left">
|
||||
<image
|
||||
style="width: 20px; height: 20px; margin-right: 5px; vertical-align: middle"
|
||||
src="/static/phone.png"
|
||||
mode="aspectFit"
|
||||
></image>
|
||||
<text class="menu-text" style="vertical-align: middle">手机号</text>
|
||||
</view>
|
||||
<view class="input-item">
|
||||
<uni-icons type="person" size="20" color="#999"></uni-icons>
|
||||
<input
|
||||
type="number"
|
||||
v-model="form.phone"
|
||||
placeholder="请输入手机号"
|
||||
maxlength="11"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="menu-item-left">
|
||||
<image style="width: 20px; height: 20px; margin-right: 5px; vertical-align: middle;"
|
||||
src="/static/password.png" mode="aspectFit"></image>
|
||||
<text class="menu-text" style="vertical-align: middle;">密码</text>
|
||||
</view>
|
||||
<!-- 密码输入框 -->
|
||||
<view class="input-item">
|
||||
<uni-icons type="locked" size="20" color="#999"></uni-icons>
|
||||
<input type="password" v-model="form.password" placeholder="请输入密码" />
|
||||
</view>
|
||||
<view class="menu-item-left">
|
||||
<image
|
||||
style="width: 20px; height: 20px; margin-right: 5px; vertical-align: middle"
|
||||
src="/static/password.png"
|
||||
mode="aspectFit"
|
||||
></image>
|
||||
<text class="menu-text" style="vertical-align: middle">密码</text>
|
||||
</view>
|
||||
<!-- 密码输入框 -->
|
||||
<view class="input-item">
|
||||
<uni-icons type="locked" size="20" color="#999"></uni-icons>
|
||||
<input type="password" v-model="form.password" placeholder="请输入密码" />
|
||||
</view>
|
||||
|
||||
<!-- 登录按钮 -->
|
||||
<button class="login-btn" @click="handleLogin">登录</button>
|
||||
<!-- 登录按钮 -->
|
||||
<button class="login-btn" @click="handleLogin">登录</button>
|
||||
|
||||
<!-- 一键登录链接 -->
|
||||
<!-- <view class="quick-login" @click="handleQuickLogin">
|
||||
<!-- 一键登录链接 -->
|
||||
<!-- <view class="quick-login" @click="handleQuickLogin">
|
||||
本机号码一键登录
|
||||
</view> -->
|
||||
|
||||
<button class="login-btn" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber">
|
||||
一键登录
|
||||
</button>
|
||||
<button class="login-btn" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber">
|
||||
一键登录
|
||||
</button>
|
||||
|
||||
<!-- https://blog.csdn.net/weixin_73318685/article/details/141530696 -->
|
||||
<!-- <button bindphoneoneclicklogin="onHandleLogin" open-type="phoneOneClickLogin">本机号码一键登录</button> -->
|
||||
</view>
|
||||
<!-- https://blog.csdn.net/weixin_73318685/article/details/141530696 -->
|
||||
<!-- <button bindphoneoneclicklogin="onHandleLogin" open-type="phoneOneClickLogin">本机号码一键登录</button> -->
|
||||
</view>
|
||||
|
||||
<!-- 版本号 -->
|
||||
<view class="version">{{version}}</view>
|
||||
</view>
|
||||
<!-- 版本号 -->
|
||||
<view class="version">{{ version }}</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
loginApi,
|
||||
getPhonenumberLogin,
|
||||
getPhonenumberByCode
|
||||
} from '../../api/index.js'
|
||||
import {
|
||||
encryptCBC,
|
||||
decryptCBC
|
||||
} from '../../utils/http.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
phone: '',
|
||||
password: ''
|
||||
},
|
||||
version: '1.0.6'
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// develop开发版 trial体验版 release正式版
|
||||
this.checkForUpdates();
|
||||
import { loginApi, getPhonenumberLogin, getPhonenumberByCode } from '../../api/index.js'
|
||||
import { encryptCBC, decryptCBC } from '../../utils/http.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
phone: '15240004260',
|
||||
password: 'GZkq@123456!',
|
||||
},
|
||||
version: '1.0.6',
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// develop开发版 trial体验版 release正式版
|
||||
this.checkForUpdates()
|
||||
|
||||
let miniProgram = wx.getAccountInfoSync().miniProgram
|
||||
if (miniProgram == 'release' || miniProgram == 'trial') {
|
||||
this.version = wx.getAccountInfoSync().miniProgram.version || this.version
|
||||
}
|
||||
var isLoginOut = uni.getStorageSync('isLoginOut');
|
||||
if (isLoginOut != "yes") {
|
||||
wx.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
const data = {
|
||||
code: res.code
|
||||
};
|
||||
getPhonenumberByCode(data).then(response => {
|
||||
console.log("responsessss", response)
|
||||
if (response.resMsg === 'success') {
|
||||
var phoneLogin = response.obj;
|
||||
console.log('phoneLogin', phoneLogin);
|
||||
if (phoneLogin != "" && phoneLogin != null) {
|
||||
this.getLogin(phoneLogin);
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("登录失败,请稍后再试");
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请允许授权,用于该服务',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 处理登录
|
||||
handleLogin() {
|
||||
if (!this.form.phone || !this.form.password) {
|
||||
uni.showToast({
|
||||
title: '请输入手机号和密码',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.form.phone.length != 11) {
|
||||
uni.showToast({
|
||||
title: '请输入正确的手机号',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
let miniProgram = wx.getAccountInfoSync().miniProgram
|
||||
if (miniProgram == 'release' || miniProgram == 'trial') {
|
||||
this.version = wx.getAccountInfoSync().miniProgram.version || this.version
|
||||
}
|
||||
var isLoginOut = uni.getStorageSync('isLoginOut')
|
||||
if (isLoginOut != 'yes') {
|
||||
wx.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
const data = {
|
||||
code: res.code,
|
||||
}
|
||||
getPhonenumberByCode(data)
|
||||
.then((response) => {
|
||||
console.log('responsessss', response)
|
||||
if (response.resMsg === 'success') {
|
||||
// var phoneLogin = response.obj;
|
||||
// console.log('phoneLogin', phoneLogin);
|
||||
// if (phoneLogin != "" && phoneLogin != null) {
|
||||
// this.getLogin(phoneLogin);
|
||||
// }
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('登录失败,请稍后再试')
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请允许授权,用于该服务',
|
||||
showCancel: false,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 处理登录
|
||||
handleLogin() {
|
||||
if (!this.form.phone || !this.form.password) {
|
||||
uni.showToast({
|
||||
title: '请输入手机号和密码',
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.form.phone.length != 11) {
|
||||
uni.showToast({
|
||||
title: '请输入正确的手机号',
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
wx.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
const data = {
|
||||
username: encryptCBC(this.form.phone), // 假设这里使用手机号作为用户名
|
||||
password: encryptCBC(this.form.password),
|
||||
flage: '1',
|
||||
code: res.code
|
||||
};
|
||||
// return
|
||||
loginApi(data).then(response => {
|
||||
if (response.status === 'success') {
|
||||
console.log('登录成功', response);
|
||||
uni.setStorageSync('token', response.token)
|
||||
uni.setStorageSync('userId', response.id)
|
||||
uni.setStorageSync('phone', response.phone)
|
||||
uni.setStorageSync('username', response.username)
|
||||
uni.setStorageSync('isCader', response.isCader)
|
||||
uni.setStorageSync('isFace', response.isFace)
|
||||
uni.setStorageSync('isPd', response.isPd)
|
||||
uni.setStorageSync('isLoginOut', "no");
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
title: '登录成功!',
|
||||
duration: 2000,
|
||||
success: () => {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 显示错误信息
|
||||
uni.showToast({
|
||||
title: response.msg || '登录失败,请稍后再试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('登录请求出错', error);
|
||||
uni.showToast({
|
||||
title: '网络请求异常,请检查您的网络连接',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请允许授权,用于该服务',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
wx.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
const data = {
|
||||
username: encryptCBC(this.form.phone), // 假设这里使用手机号作为用户名
|
||||
password: encryptCBC(this.form.password),
|
||||
flage: '1',
|
||||
code: res.code,
|
||||
}
|
||||
// return
|
||||
loginApi(data)
|
||||
.then((response) => {
|
||||
if (response.status === 'success') {
|
||||
console.log('登录成功', response)
|
||||
uni.setStorageSync('token', response.token)
|
||||
uni.setStorageSync('userId', response.id)
|
||||
uni.setStorageSync('phone', response.phone)
|
||||
uni.setStorageSync('username', response.username)
|
||||
uni.setStorageSync('isCader', response.isCader)
|
||||
uni.setStorageSync('isFace', response.isFace)
|
||||
uni.setStorageSync('isPd', response.isPd)
|
||||
uni.setStorageSync('isLoginOut', 'no')
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
title: '登录成功!',
|
||||
duration: 2000,
|
||||
success: () => {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index',
|
||||
})
|
||||
},
|
||||
})
|
||||
} else {
|
||||
// 显示错误信息
|
||||
uni.showToast({
|
||||
title: response.msg || '登录失败,请稍后再试',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('登录请求出错', error)
|
||||
uni.showToast({
|
||||
title: '网络请求异常,请检查您的网络连接',
|
||||
icon: 'none',
|
||||
})
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请允许授权,用于该服务',
|
||||
showCancel: false,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
// 手机号
|
||||
async onGetPhoneNumber(e) {
|
||||
console.log(e, '打印手机号信息');
|
||||
try {
|
||||
wx.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
const data = {
|
||||
code: res.code
|
||||
};
|
||||
this.sendCodeToGetPhonenumber(data, e);
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请允许授权,用于该服务',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('获取手机号失败:', error);
|
||||
}
|
||||
},
|
||||
// 手机号
|
||||
async onGetPhoneNumber(e) {
|
||||
console.log(e, '打印手机号信息')
|
||||
try {
|
||||
wx.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
const data = {
|
||||
code: res.code,
|
||||
}
|
||||
this.sendCodeToGetPhonenumber(data, e)
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请允许授权,用于该服务',
|
||||
showCancel: false,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('获取手机号失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
sendCodeToGetPhonenumber(data, e) {
|
||||
getPhonenumberByCode(data).then(response => {
|
||||
console.log("responsessss", response)
|
||||
if (response.resMsg === 'success') {
|
||||
var phoneLogin = response.obj;
|
||||
console.log('phoneLogin', phoneLogin);
|
||||
if (phoneLogin != "" && phoneLogin != null) {
|
||||
this.getLogin(phoneLogin);
|
||||
} else {
|
||||
console.log("没有获取到openid", e);
|
||||
if (e.detail.errMsg == "getPhoneNumber:ok") {
|
||||
var code = e.detail.code;
|
||||
this.sendPhoneInfoToServer(code);
|
||||
} else {
|
||||
console.error('用户拒绝提供手机号');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: response.msg || '登录失败,请稍后再试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
uni.showToast({
|
||||
title: '登录失败,请稍后再试',
|
||||
icon: 'none'
|
||||
});
|
||||
})
|
||||
},
|
||||
sendCodeToGetPhonenumber(data, e) {
|
||||
getPhonenumberByCode(data)
|
||||
.then((response) => {
|
||||
console.log('responsessss', response)
|
||||
if (response.resMsg === 'success') {
|
||||
var phoneLogin = response.obj
|
||||
console.log('phoneLogin', phoneLogin)
|
||||
if (phoneLogin != '' && phoneLogin != null) {
|
||||
this.getLogin(phoneLogin)
|
||||
} else {
|
||||
console.log('没有获取到openid', e)
|
||||
if (e.detail.errMsg == 'getPhoneNumber:ok') {
|
||||
var code = e.detail.code
|
||||
this.sendPhoneInfoToServer(code)
|
||||
} else {
|
||||
console.error('用户拒绝提供手机号')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: response.msg || '登录失败,请稍后再试',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.showToast({
|
||||
title: '登录失败,请稍后再试',
|
||||
icon: 'none',
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
sendPhoneInfoToServer(code) {
|
||||
var data = {
|
||||
code: code
|
||||
}
|
||||
getPhonenumberLogin(data).then(response => {
|
||||
console.log("responsessss", response)
|
||||
if (response.resMsg === 'success') {
|
||||
console.log('手机号', response.obj);
|
||||
var phoneLogin = response.obj;
|
||||
this.getLogin(phoneLogin)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: response.msg || '登录失败,请稍后再试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
uni.showToast({
|
||||
title: '登录失败,请稍后再试',
|
||||
icon: 'none'
|
||||
});
|
||||
})
|
||||
},
|
||||
sendPhoneInfoToServer(code) {
|
||||
var data = {
|
||||
code: code,
|
||||
}
|
||||
getPhonenumberLogin(data)
|
||||
.then((response) => {
|
||||
console.log('responsessss', response)
|
||||
if (response.resMsg === 'success') {
|
||||
console.log('手机号', response.obj)
|
||||
var phoneLogin = response.obj
|
||||
this.getLogin(phoneLogin)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: response.msg || '登录失败,请稍后再试',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.showToast({
|
||||
title: '登录失败,请稍后再试',
|
||||
icon: 'none',
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
getLogin(phoneLogin) {
|
||||
var username = decryptCBC(phoneLogin);
|
||||
console.log("useraname", username);
|
||||
wx.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
const data = {
|
||||
username: encryptCBC(username + "wechat"), // 假设这里使用手机号作为用户名
|
||||
flage: '1',
|
||||
code: res.code
|
||||
};
|
||||
// return
|
||||
loginApi(data).then(response => {
|
||||
if (response.status === 'success') {
|
||||
console.log('登录成功', response);
|
||||
uni.setStorageSync('token', response.token)
|
||||
uni.setStorageSync('userId', response.id)
|
||||
uni.setStorageSync('phone', response.phone)
|
||||
uni.setStorageSync('username', response.username)
|
||||
uni.setStorageSync('isCader', response.isCader)
|
||||
uni.setStorageSync('isFace', response.isFace)
|
||||
uni.setStorageSync('isPd', response.isPd)
|
||||
uni.setStorageSync('isLoginOut', "no");
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
title: '登录成功!',
|
||||
duration: 2000,
|
||||
success: () => {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 显示错误信息
|
||||
uni.showToast({
|
||||
title: response.msg || '登录失败,请稍后再试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('登录请求出错', error);
|
||||
uni.showToast({
|
||||
title: '网络请求异常,请检查您的网络连接',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请允许授权,用于该服务',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 检查并处理小程序更新
|
||||
*/
|
||||
checkForUpdates() {
|
||||
const updateManager = uni.getUpdateManager();
|
||||
getLogin(phoneLogin) {
|
||||
var username = decryptCBC(phoneLogin)
|
||||
console.log('useraname', username)
|
||||
wx.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
const data = {
|
||||
username: encryptCBC(username + 'wechat'), // 假设这里使用手机号作为用户名
|
||||
flage: '1',
|
||||
code: res.code,
|
||||
}
|
||||
// return
|
||||
loginApi(data)
|
||||
.then((response) => {
|
||||
if (response.status === 'success') {
|
||||
console.log('登录成功', response)
|
||||
uni.setStorageSync('token', response.token)
|
||||
uni.setStorageSync('userId', response.id)
|
||||
uni.setStorageSync('phone', response.phone)
|
||||
uni.setStorageSync('username', response.username)
|
||||
uni.setStorageSync('isCader', response.isCader)
|
||||
uni.setStorageSync('isFace', response.isFace)
|
||||
uni.setStorageSync('isPd', response.isPd)
|
||||
uni.setStorageSync('isLoginOut', 'no')
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
title: '登录成功!',
|
||||
duration: 2000,
|
||||
success: () => {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index',
|
||||
})
|
||||
},
|
||||
})
|
||||
} else {
|
||||
// 显示错误信息
|
||||
uni.showToast({
|
||||
title: response.msg || '登录失败,请稍后再试',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('登录请求出错', error)
|
||||
uni.showToast({
|
||||
title: '网络请求异常,请检查您的网络连接',
|
||||
icon: 'none',
|
||||
})
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '请允许授权,用于该服务',
|
||||
showCancel: false,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 检查并处理小程序更新
|
||||
*/
|
||||
checkForUpdates() {
|
||||
const updateManager = uni.getUpdateManager()
|
||||
|
||||
// 检查更新
|
||||
updateManager.onCheckForUpdate((res) => {
|
||||
console.log('[App] 是否有新版本:', res.hasUpdate);
|
||||
});
|
||||
// 检查更新
|
||||
updateManager.onCheckForUpdate((res) => {
|
||||
console.log('[App] 是否有新版本:', res.hasUpdate)
|
||||
})
|
||||
|
||||
// 监听新版本下载成功
|
||||
updateManager.onUpdateReady(() => {
|
||||
this.promptForUpdate(updateManager);
|
||||
});
|
||||
// 监听新版本下载成功
|
||||
updateManager.onUpdateReady(() => {
|
||||
this.promptForUpdate(updateManager)
|
||||
})
|
||||
|
||||
// 监听新版本下载失败
|
||||
updateManager.onUpdateFailed(() => {
|
||||
console.error('[App] 新版本下载失败');
|
||||
});
|
||||
},
|
||||
// 监听新版本下载失败
|
||||
updateManager.onUpdateFailed(() => {
|
||||
console.error('[App] 新版本下载失败')
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 提示用户应用新版本
|
||||
* @param {Object} updateManager - 更新管理对象
|
||||
*/
|
||||
promptForUpdate(updateManager) {
|
||||
uni.showModal({
|
||||
title: '更新提示',
|
||||
content: '新版本已准备好,是否重启应用?',
|
||||
showCancel: false,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
console.log('[App] 用户确认重启应用');
|
||||
updateManager.applyUpdate();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
onHandleLogin(e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 提示用户应用新版本
|
||||
* @param {Object} updateManager - 更新管理对象
|
||||
*/
|
||||
promptForUpdate(updateManager) {
|
||||
uni.showModal({
|
||||
title: '更新提示',
|
||||
content: '新版本已准备好,是否重启应用?',
|
||||
showCancel: false,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
console.log('[App] 用户确认重启应用')
|
||||
updateManager.applyUpdate()
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
onHandleLogin(e) {
|
||||
console.log(e)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.login-container {
|
||||
min-height: 100vh;
|
||||
padding: 0 50rpx;
|
||||
background-color: #fff;
|
||||
.login-container {
|
||||
min-height: 100vh;
|
||||
padding: 0 50rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.header {
|
||||
padding-top: 100rpx;
|
||||
// text-align: center;
|
||||
.header {
|
||||
padding-top: 100rpx;
|
||||
// text-align: center;
|
||||
|
||||
.logo {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
}
|
||||
.logo {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: block;
|
||||
margin-top: 20rpx;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
display: block;
|
||||
margin-top: 20rpx;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.form-box {
|
||||
margin-top: 80rpx;
|
||||
.form-box {
|
||||
margin-top: 80rpx;
|
||||
|
||||
.input-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
margin-bottom: 30rpx;
|
||||
padding: 0 20rpx;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
.input-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
margin-bottom: 30rpx;
|
||||
padding: 0 20rpx;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
margin-left: 20rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
input {
|
||||
flex: 1;
|
||||
margin-left: 20rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
margin-top: 60rpx;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
background-color: #4080FF;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
border-radius: 45rpx;
|
||||
}
|
||||
.login-btn {
|
||||
margin-top: 60rpx;
|
||||
height: 90rpx;
|
||||
line-height: 90rpx;
|
||||
background-color: #4080ff;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
border-radius: 45rpx;
|
||||
}
|
||||
|
||||
.quick-login {
|
||||
margin-top: 30rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
.quick-login {
|
||||
margin-top: 30rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.version {
|
||||
position: fixed;
|
||||
bottom: 60rpx;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.version {
|
||||
position: fixed;
|
||||
bottom: 60rpx;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,260 +1,271 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- 用户信息区域 -->
|
||||
<view class="user-info">
|
||||
<image class="avatar" :src="userInfo.avatar" mode="aspectFill"></image>
|
||||
<view class="user-detail">
|
||||
<text class="username">{{userInfo.name}}</text>
|
||||
<text class="phone">{{userInfo.phone}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="container">
|
||||
<!-- 用户信息区域 -->
|
||||
<view class="user-info">
|
||||
<image class="avatar" :src="userInfo.avatar" mode="aspectFill"></image>
|
||||
<view class="user-detail">
|
||||
<text class="username">{{ userInfo.name }}</text>
|
||||
<text class="phone">{{ userInfo.phone }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="menu-list">
|
||||
<view class="menu-item" @tap="onChangePassword">
|
||||
<view class="menu-item-left">
|
||||
<image style="width: 20px; height: 20px; margin-right: 10px;" src="/static/updatePassword.png"
|
||||
mode="aspectFit"></image>
|
||||
<text class="menu-text">修改密码</text>
|
||||
</view>
|
||||
<image style="width: 20px; height: 20px;" src="/static/more.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="menu-list">
|
||||
<view class="menu-item" @tap="onChangePassword">
|
||||
<view class="menu-item-left">
|
||||
<image
|
||||
style="width: 20px; height: 20px; margin-right: 10px"
|
||||
src="/static/updatePassword.png"
|
||||
mode="aspectFit"
|
||||
></image>
|
||||
<text class="menu-text">修改密码</text>
|
||||
</view>
|
||||
<image
|
||||
style="width: 20px; height: 20px"
|
||||
src="/static/more.png"
|
||||
mode="aspectFit"
|
||||
></image>
|
||||
</view>
|
||||
|
||||
<view class="menu-item" @tap="onCheckForUpdates">
|
||||
<view class="menu-item-left">
|
||||
<image style="width: 20px; height: 20px; margin-right: 10px;" src="/static/version.png"
|
||||
mode="aspectFit"></image>
|
||||
<text class="menu-text">检查新版本</text>
|
||||
</view>
|
||||
<text class="version">{{version}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="menu-item" @tap="onCheckForUpdates">
|
||||
<view class="menu-item-left">
|
||||
<image
|
||||
style="width: 20px; height: 20px; margin-right: 10px"
|
||||
src="/static/version.png"
|
||||
mode="aspectFit"
|
||||
></image>
|
||||
<text class="menu-text">检查新版本</text>
|
||||
</view>
|
||||
<text class="version">{{ version }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<button class="logout-btn" @tap="onLogout">退出登录</button>
|
||||
</view>
|
||||
<button class="logout-btn" @tap="onLogout">退出登录</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getUsetInfo
|
||||
} from "@/api/index.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: {
|
||||
name: '',
|
||||
phone: '',
|
||||
avatar: '/static/defaultHead.png'
|
||||
},
|
||||
version: '1.0.6'
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// develop开发版 trial体验版 release正式版
|
||||
let miniProgram = wx.getAccountInfoSync().miniProgram
|
||||
if (miniProgram == 'release' || miniProgram == 'trial') {
|
||||
this.version = wx.getAccountInfoSync().miniProgram.version || this.version
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.getUsetInfoEvent()
|
||||
},
|
||||
mounted() {
|
||||
// 在组件挂载后读取存储的数据
|
||||
this.userInfo.name = uni.getStorageSync('username') || '';
|
||||
this.userInfo.phone = uni.getStorageSync('phone') || '';
|
||||
if (/^1\d{10}$/.test(this.userInfo.phone)) {
|
||||
this.userInfo.phone = this.maskPhoneNumber(this.userInfo.phone)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取用户信息
|
||||
getUsetInfoEvent() {
|
||||
getUsetInfo(uni.getStorageSync('userId')).then(res => {
|
||||
if (res.res == 1) {
|
||||
if (res.obj && res.obj.appliedFace) {
|
||||
if (res.obj.appliedFace == '' || res.obj.appliedFace == null || res.obj.appliedFace ==
|
||||
'null') {
|
||||
this.userInfo.avatar = '/static/defaultHead.png'
|
||||
} else {
|
||||
this.userInfo.avatar = res.obj.appliedFace
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
maskPhoneNumber(phoneNumber) {
|
||||
return phoneNumber.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||
},
|
||||
onChangePassword() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/password/index'
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 检查并处理小程序更新
|
||||
*/
|
||||
onCheckForUpdates() {
|
||||
const updateManager = uni.getUpdateManager();
|
||||
import { getUsetInfo } from '@/api/index.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: {
|
||||
name: '',
|
||||
phone: '',
|
||||
avatar: '/static/defaultHead.png',
|
||||
},
|
||||
version: '1.0.6',
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// develop开发版 trial体验版 release正式版
|
||||
let miniProgram = wx.getAccountInfoSync().miniProgram
|
||||
if (miniProgram == 'release' || miniProgram == 'trial') {
|
||||
this.version = wx.getAccountInfoSync().miniProgram.version || this.version
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.getUsetInfoEvent()
|
||||
},
|
||||
mounted() {
|
||||
// 在组件挂载后读取存储的数据
|
||||
this.userInfo.name = uni.getStorageSync('username') || ''
|
||||
this.userInfo.phone = uni.getStorageSync('phone') || ''
|
||||
if (/^1\d{10}$/.test(this.userInfo.phone)) {
|
||||
this.userInfo.phone = this.maskPhoneNumber(this.userInfo.phone)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取用户信息
|
||||
getUsetInfoEvent() {
|
||||
getUsetInfo(uni.getStorageSync('userId')).then((res) => {
|
||||
if (res.res == 1) {
|
||||
if (res.obj && res.obj.appliedFace) {
|
||||
if (
|
||||
res.obj.appliedFace == '' ||
|
||||
res.obj.appliedFace == null ||
|
||||
res.obj.appliedFace == 'null'
|
||||
) {
|
||||
this.userInfo.avatar = '/static/defaultHead.png'
|
||||
} else {
|
||||
this.userInfo.avatar = res.obj.appliedFace
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
maskPhoneNumber(phoneNumber) {
|
||||
return phoneNumber.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
|
||||
},
|
||||
onChangePassword() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/password/index',
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 检查并处理小程序更新
|
||||
*/
|
||||
onCheckForUpdates() {
|
||||
const updateManager = uni.getUpdateManager()
|
||||
|
||||
// 检查更新
|
||||
updateManager.onCheckForUpdate((res) => {
|
||||
console.log('[App] 是否有新版本:', res.hasUpdate);
|
||||
if(!res.hasUpdate){
|
||||
uni.showToast({
|
||||
title: '已是最新版本',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
// 检查更新
|
||||
updateManager.onCheckForUpdate((res) => {
|
||||
console.log('[App] 是否有新版本:', res.hasUpdate)
|
||||
if (!res.hasUpdate) {
|
||||
uni.showToast({
|
||||
title: '已是最新版本',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 监听新版本下载成功
|
||||
updateManager.onUpdateReady(() => {
|
||||
this.promptForUpdate(updateManager);
|
||||
});
|
||||
// 监听新版本下载成功
|
||||
updateManager.onUpdateReady(() => {
|
||||
this.promptForUpdate(updateManager)
|
||||
})
|
||||
|
||||
// 监听新版本下载失败
|
||||
updateManager.onUpdateFailed(() => {
|
||||
console.error('[App] 新版本下载失败');
|
||||
});
|
||||
},
|
||||
// 监听新版本下载失败
|
||||
updateManager.onUpdateFailed(() => {
|
||||
console.error('[App] 新版本下载失败')
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 提示用户应用新版本
|
||||
* @param {Object} updateManager - 更新管理对象
|
||||
*/
|
||||
promptForUpdate(updateManager) {
|
||||
uni.showModal({
|
||||
title: '更新提示',
|
||||
content: '新版本已准备好,是否重启应用?',
|
||||
showCancel: false,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
console.log('[App] 用户确认重启应用');
|
||||
updateManager.applyUpdate();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
onLogout() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确认退出登录?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 执行退出登录逻辑
|
||||
uni.clearStorageSync()
|
||||
uni.setStorageSync('isLoginOut', "yes");
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 提示用户应用新版本
|
||||
* @param {Object} updateManager - 更新管理对象
|
||||
*/
|
||||
promptForUpdate(updateManager) {
|
||||
uni.showModal({
|
||||
title: '更新提示',
|
||||
content: '新版本已准备好,是否重启应用?',
|
||||
showCancel: false,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
console.log('[App] 用户确认重启应用')
|
||||
updateManager.applyUpdate()
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
onLogout() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确认退出登录?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 执行退出登录逻辑
|
||||
uni.clearStorageSync()
|
||||
uni.setStorageSync('isLoginOut', 'yes')
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/index',
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding: 32rpx;
|
||||
}
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.user-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.user-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.username {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
.username {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.phone {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
.phone {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
.menu-list {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 32rpx;
|
||||
border-bottom: 2rpx solid #f5f5f5;
|
||||
}
|
||||
.menu-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 32rpx;
|
||||
border-bottom: 2rpx solid #f5f5f5;
|
||||
}
|
||||
|
||||
.menu-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.menu-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.menu-item-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.menu-item-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
color: #666;
|
||||
}
|
||||
.iconfont {
|
||||
font-size: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.menu-text {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
}
|
||||
.menu-text {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.version {
|
||||
font-size: 32rpx;
|
||||
color: #999;
|
||||
}
|
||||
.version {
|
||||
font-size: 32rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.icon-arrow {
|
||||
color: #999;
|
||||
margin-right: 0;
|
||||
}
|
||||
.icon-arrow {
|
||||
color: #999;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
background-color: #4080FF;
|
||||
color: #fff;
|
||||
border-radius: 44rpx;
|
||||
font-size: 32rpx;
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
.logout-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
background-color: #4080ff;
|
||||
color: #fff;
|
||||
border-radius: 44rpx;
|
||||
font-size: 32rpx;
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
|
||||
/* 去除按钮默认边框 */
|
||||
.logout-btn::after {
|
||||
border: none;
|
||||
}
|
||||
/* 去除按钮默认边框 */
|
||||
.logout-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 按钮点击效果 */
|
||||
.logout-btn:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
/* 按钮点击效果 */
|
||||
.logout-btn:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,241 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<view class="form-container">
|
||||
<view class="form-item">
|
||||
<text class="label required">姓名</text>
|
||||
<input type="text" v-model="formData.userName" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假类型</text>
|
||||
<input type="text" v-model="formData.leaveType" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假开始时间</text>
|
||||
<input type="text" v-model="formData.leaveStartDate" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假结束时间</text>
|
||||
<input type="text" v-model="formData.leaveEndDate" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假时长(天)</text>
|
||||
<input type="number" v-model="formData.leaveDuration" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">地点</text>
|
||||
<input type="text" v-model="formData.location" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required" style="width: 300px;">是否请示领导同意</text>
|
||||
<input type="text" :value="formData.isAgree === '1' ? '是' : '否'" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">代理主持工作人员</text>
|
||||
<input type="text" v-model="formData.hostUserName" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假事由</text>
|
||||
<textarea v-model="formData.leaveReason" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">备注</text>
|
||||
<textarea v-model="formData.remark" disabled />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getLeaveReporting } from '../../api/index.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
uuid: '',
|
||||
datas:{
|
||||
uuid:''
|
||||
},
|
||||
formData: {
|
||||
userName: '',
|
||||
type:'',
|
||||
leaveType:'',
|
||||
travelersName: '',
|
||||
leaveStartDate: '',
|
||||
leaveEndDate: '',
|
||||
leaveDuration: '',
|
||||
location: '',
|
||||
isAgree: '1',
|
||||
hostUserName: '',
|
||||
leaveReason: '',
|
||||
remark: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.uuid = option.uuid
|
||||
console.log('接收到的id:', this.uuid)
|
||||
this.fetchEvectionDetail()
|
||||
},
|
||||
methods: {
|
||||
fetchEvectionDetail() {
|
||||
try {
|
||||
this.datas.uuid=this.uuid;
|
||||
getLeaveReporting(this.datas).then(response=>{
|
||||
if (response && response.data) {
|
||||
console.log("response.data",response.data)
|
||||
this.formData = {
|
||||
...this.formData,
|
||||
...response.data
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('获取出差详情失败:', error)
|
||||
uni.showToast({
|
||||
title: '获取出差详情失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 20rpx 0;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: #007AFF;
|
||||
}
|
||||
|
||||
.tab.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 120rpx;
|
||||
height: 4rpx;
|
||||
background: #007AFF;
|
||||
}
|
||||
|
||||
/* .tabs {
|
||||
display: flex;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 20rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: #4080FF;
|
||||
border-bottom: 4rpx solid #4080FF;
|
||||
} */
|
||||
|
||||
.form-container {
|
||||
background: #fff;
|
||||
padding: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.required::after {
|
||||
content: '*';
|
||||
color: #ff4d4f;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
|
||||
input, .picker-value {
|
||||
width: 95%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
padding: 0 20rpx;
|
||||
border: 2rpx solid #e5e5e5;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 95%;
|
||||
height: 160rpx;
|
||||
padding: 20rpx;
|
||||
border: 2rpx solid #e5e5e5;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.radio {
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
margin-top: 40rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: #4080FF;
|
||||
color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.error-message {
|
||||
color: #ff4d4f;
|
||||
font-size: 24rpx;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -0,0 +1,659 @@
|
|||
<template>
|
||||
<!-- 轮休申请 -->
|
||||
<view class="container">
|
||||
<view class="tabs">
|
||||
<text class="tab" :class="{ active: activeTab === 'form' }" @tap="switchTab('form')">
|
||||
轮休申请
|
||||
</text>
|
||||
<text
|
||||
class="tab"
|
||||
:class="{ active: activeTab === 'records' }"
|
||||
@tap="switchTab('records')"
|
||||
>
|
||||
轮休记录
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view v-if="activeTab === 'form'" class="form-container">
|
||||
<view>
|
||||
<text v-if="isFormDisabled" style="color: #3370ff; margin-bottom: 10px">
|
||||
请确认填写信息是否准确,保存后不可修改;若修改可联系相关工作人员在统计报表核对时修改
|
||||
</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label required">申请人</text>
|
||||
<input
|
||||
type="text"
|
||||
v-model="formData.userName"
|
||||
placeholder="请输入申请人姓名"
|
||||
disabled
|
||||
/>
|
||||
<text v-if="errors.userName" class="error-message">{{ errors.userName }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label required">职务</text>
|
||||
<input type="text" placeholder="请输入职务" disabled />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label required">所属部门</text>
|
||||
<input type="text" placeholder="请输入所属部门" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假类型</text>
|
||||
<picker
|
||||
@change="onLeaveTypeChange"
|
||||
:disabled="isFormDisabled"
|
||||
:value="leaveTypeIndex"
|
||||
:range="leaveTypes"
|
||||
range-key="label"
|
||||
>
|
||||
<view class="picker-value">
|
||||
{{ formData.leaveType ? formData.leaveType : '请选择休假类型' }}
|
||||
</view>
|
||||
</picker>
|
||||
<text v-if="errors.leaveType" class="error-message">{{ errors.leaveType }}</text>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">轮休开始时间</text>
|
||||
<picker
|
||||
mode="date"
|
||||
:value="formData.leaveStartDate"
|
||||
@change="onStartDateChange"
|
||||
:disabled="isFormDisabled"
|
||||
>
|
||||
<view class="picker-value">{{ formData.leaveStartDate }}</view>
|
||||
</picker>
|
||||
<text v-if="errors.leaveStartDate" class="error-message">
|
||||
{{ errors.leaveStartDate }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">轮休结束时间</text>
|
||||
<picker
|
||||
mode="date"
|
||||
:value="formData.leaveEndDate"
|
||||
@change="onEndDateChange"
|
||||
:disabled="isFormDisabled"
|
||||
>
|
||||
<view class="picker-value">{{ formData.leaveEndDate }}</view>
|
||||
</picker>
|
||||
<text v-if="errors.leaveEndDate" class="error-message">
|
||||
{{ errors.leaveEndDate }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假时长(天)</text>
|
||||
<input type="number" v-model="formData.leaveDuration" disabled />
|
||||
</view>
|
||||
|
||||
<!-- <view class="form-item">
|
||||
<text class="label">地点</text>
|
||||
<input
|
||||
type="text"
|
||||
v-model="formData.location"
|
||||
placeholder="请输入"
|
||||
:disabled="isFormDisabled"
|
||||
/>
|
||||
</view> -->
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required" style="width: 300px">是否请示领导同意</text>
|
||||
<radio-group @change="onApprovalChange">
|
||||
<label class="radio">
|
||||
<radio
|
||||
value="1"
|
||||
:disabled="isFormDisabled"
|
||||
checked
|
||||
:checked="formData.isAgree === '1'"
|
||||
/>
|
||||
是
|
||||
</label>
|
||||
<label class="radio">
|
||||
<radio
|
||||
value="0"
|
||||
:disabled="isFormDisabled"
|
||||
:checked="formData.isAgree === '0'"
|
||||
/>
|
||||
否
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<view class="form-item" style="margin-bottom: 20rpx">
|
||||
<text
|
||||
class="label required"
|
||||
style="display: block; margin-bottom: 10rpx; width: 300px"
|
||||
>
|
||||
代理主持工作人员
|
||||
</text>
|
||||
<view class="selected-values" style="margin-bottom: 10rpx">
|
||||
{{ hostUserNames }}
|
||||
</view>
|
||||
<view
|
||||
v-if="!isFormDisabled"
|
||||
class="toggle-button"
|
||||
@tap="toggleCheckboxGroups"
|
||||
style="
|
||||
background-color: #f0f0f0;
|
||||
width: 55px;
|
||||
line-height: 35px;
|
||||
text-align: center;
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 10rpx;
|
||||
display: inline-block;
|
||||
margin-bottom: 10rpx;
|
||||
"
|
||||
>
|
||||
{{ isCheckboxGroupVisibles ? '收起' : '展开' }}
|
||||
</view>
|
||||
<view
|
||||
class="checkbox-group-container"
|
||||
v-if="!isFormDisabled && isCheckboxGroupVisibles"
|
||||
>
|
||||
<checkbox-group
|
||||
@change="onHostUserChange"
|
||||
v-if="isCheckboxGroupVisibles"
|
||||
style="display: flex; flex-wrap: wrap"
|
||||
>
|
||||
<view
|
||||
class="search-container"
|
||||
style="display: flex; margin-bottom: 10rpx; width: 100%"
|
||||
>
|
||||
<input
|
||||
v-model="searchQuerys"
|
||||
placeholder="搜索人名"
|
||||
style="
|
||||
flex: 1;
|
||||
padding: 10rpx;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
height: 30px;
|
||||
"
|
||||
/>
|
||||
<button
|
||||
@tap="searchPersons"
|
||||
style="
|
||||
line-height: 22px;
|
||||
font-size: 13px;
|
||||
margin-left: 10rpx;
|
||||
padding: 10px 20px;
|
||||
background-color: #007aff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
搜索
|
||||
</button>
|
||||
</view>
|
||||
<label
|
||||
v-for="(option, index) in displayedPersonOptionss"
|
||||
:key="index"
|
||||
style="width: 33.33%; padding: 10rpx; box-sizing: border-box"
|
||||
>
|
||||
<checkbox
|
||||
:value="option.userId"
|
||||
:checked="option.checked"
|
||||
style="transform: scale(0.7)"
|
||||
/>
|
||||
<text style="font-size: 28rpx">{{ option.username }}</text>
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- <view class="form-item">
|
||||
<text class="label required">休假事由</text>
|
||||
<textarea
|
||||
v-model="formData.leaveReason"
|
||||
placeholder="请输入休假事由"
|
||||
:disabled="isFormDisabled"
|
||||
/>
|
||||
<text v-if="errors.leaveReason" class="error-message">
|
||||
{{ errors.leaveReason }}
|
||||
</text>
|
||||
</view> -->
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">备注</text>
|
||||
<textarea v-model="formData.remark" :disabled="isFormDisabled" />
|
||||
</view>
|
||||
|
||||
<view class="button-group">
|
||||
<button
|
||||
class="submit-btn"
|
||||
@tap="onSubmit"
|
||||
:disabled="isFormDisabled && !isDataUploaded"
|
||||
>
|
||||
{{ isDataUploaded ? '确认提交' : '保存' }}
|
||||
</button>
|
||||
<button class="cancel-btn" @tap="onCancel">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<RecordList v-if="activeTab === 'records'" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPersonSelect, addHoliday, getHolidayType, getDays } from '../../api/index.js'
|
||||
import RecordList from './recordList.vue'
|
||||
export default {
|
||||
components: {
|
||||
RecordList,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isFormDisabled: false,
|
||||
isDataUploaded: false,
|
||||
showConfirmDialog: false,
|
||||
searchQuerys: '',
|
||||
activeTab: 'form',
|
||||
formData: {
|
||||
userName: '',
|
||||
leaveType: null,
|
||||
leaveStartDate: '',
|
||||
leaveEndDate: '',
|
||||
leaveDuration: '',
|
||||
location: '',
|
||||
isAgree: '1',
|
||||
representative: '',
|
||||
hostUserId: '',
|
||||
hostUserName: '',
|
||||
leaveReason: '',
|
||||
remark: '',
|
||||
},
|
||||
userInfo: {
|
||||
token: '',
|
||||
userId: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
},
|
||||
leaveTypes: [],
|
||||
leaveTypeIndex: -1,
|
||||
today: new Date().toISOString().substr(0, 10), // 格式化为YYYY-MM-DD
|
||||
errors: {},
|
||||
hostUserOptions: [], // 人员选项列表
|
||||
filteredPersonOptionss: [],
|
||||
hostUserId: [], // 选中的ID列表
|
||||
hostUserNames: '', // 显示的选中名字
|
||||
isCheckboxGroupVisibles: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 在组件挂载后读取存储的数据
|
||||
this.userInfo.token = uni.getStorageSync('token') || ''
|
||||
this.userInfo.userId = uni.getStorageSync('userId') || ''
|
||||
this.userInfo.name = uni.getStorageSync('username') || ''
|
||||
this.userInfo.phone = uni.getStorageSync('phone') || ''
|
||||
this.formData.userName = uni.getStorageSync('username') || ''
|
||||
},
|
||||
created() {
|
||||
// this.gethostUserSelect()
|
||||
this.getHolidayType()
|
||||
},
|
||||
computed: {
|
||||
displayedPersonOptionss() {
|
||||
return this.filteredPersonOptionss.map((person) => ({
|
||||
...person,
|
||||
checked: this.hostUserId.includes(person.userId),
|
||||
}))
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleCheckboxGroups() {
|
||||
this.isCheckboxGroupVisibles = !this.isCheckboxGroupVisibles
|
||||
},
|
||||
switchTab(tab) {
|
||||
this.activeTab = tab
|
||||
},
|
||||
getHolidayType() {
|
||||
getHolidayType()
|
||||
.then((response) => {
|
||||
this.leaveTypes = response.data.map((type) => ({
|
||||
value: type.value,
|
||||
label: type.label || type.type, // 使用label如果存在,否则使用type
|
||||
}))
|
||||
if (this.leaveTypes.length > 0) {
|
||||
this.formData.leaveType = this.leaveTypes[0].label
|
||||
this.leaveTypeIndex = 0
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取休假类型失败:', error)
|
||||
// 可以在这里添加错误提示
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
onLeaveTypeChange(e) {
|
||||
const index = e.detail.value
|
||||
this.leaveTypeIndex = index
|
||||
this.formData.leaveType = this.leaveTypes[index].label
|
||||
console.log(this.formData.leaveType)
|
||||
console.log('休假类型已更改为:', this.formData.leaveType)
|
||||
},
|
||||
onStartDateChange(e) {
|
||||
const startDate = e.detail.value
|
||||
this.formData.leaveStartDate = startDate
|
||||
this.validateAndCalculateDuration(startDate, this.formData.leaveEndDate)
|
||||
},
|
||||
onEndDateChange(e) {
|
||||
const endDate = e.detail.value
|
||||
this.formData.leaveEndDate = endDate
|
||||
this.validateAndCalculateDuration(this.formData.leaveStartDate, endDate)
|
||||
},
|
||||
validateAndCalculateDuration(startDate, endDate) {
|
||||
// 清除之前的错误信息
|
||||
this.errors.leaveStartDate = ''
|
||||
this.errors.leaveEndDate = ''
|
||||
|
||||
// 转换日期为Date对象
|
||||
const start = new Date(startDate)
|
||||
const end = new Date(endDate)
|
||||
const today = new Date(this.today)
|
||||
|
||||
// 验证开始日期不能早于今天
|
||||
if (start < today) {
|
||||
this.errors.leaveStartDate = '开始日期不能早于今天'
|
||||
this.formData.leaveStartDate = ''
|
||||
return
|
||||
}
|
||||
|
||||
// 验证结束日期不能早于开始日期
|
||||
if (end < start) {
|
||||
this.errors.leaveEndDate = '结束日期不能早于开始日期'
|
||||
this.formData.leaveEndDate = ''
|
||||
return
|
||||
}
|
||||
|
||||
let dateData = {
|
||||
startTime: startDate,
|
||||
endTime: endDate,
|
||||
}
|
||||
if (startDate != null && startDate !== '' && endDate != null && endDate !== '') {
|
||||
getDays(dateData).then((response) => {
|
||||
if (response.status === 200) {
|
||||
console.log(response)
|
||||
this.formData.leaveDuration = response.data
|
||||
} else {
|
||||
this.formData.leaveDuration = ''
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onApprovalChange(e) {
|
||||
this.formData.isApproved = e.detail.value
|
||||
},
|
||||
onRepresentativeChange(e) {
|
||||
this.formData.representative = e.detail.value
|
||||
},
|
||||
validateForm() {
|
||||
this.errors = {}
|
||||
|
||||
if (!this.formData.userName.trim()) {
|
||||
this.errors.userName = '请输入姓名'
|
||||
}
|
||||
if (!this.formData.leaveType) {
|
||||
this.errors.leaveType = '请选择休假类型'
|
||||
}
|
||||
if (!this.formData.leaveStartDate) {
|
||||
this.errors.leaveStartDate = '请选择休假开始时间'
|
||||
}
|
||||
if (!this.formData.leaveEndDate) {
|
||||
this.errors.leaveEndDate = '请选择休假结束时间'
|
||||
}
|
||||
if (!this.formData.leaveDuration) {
|
||||
this.errors.leaveDuration = '请输入休假时长'
|
||||
}
|
||||
if (!this.formData.hostUserId) {
|
||||
this.errors.hostUserId = '请选择代理主持工作人员'
|
||||
}
|
||||
if (!this.formData.leaveReason.trim()) {
|
||||
this.errors.leaveReason = '请输入休假事由'
|
||||
}
|
||||
|
||||
return Object.keys(this.errors).length === 0
|
||||
},
|
||||
gethostUserSelect() {
|
||||
// 假设getPersonSelect是一个API调用函数,返回Promise
|
||||
getPersonSelect().then((response) => {
|
||||
this.hostUserOptions = response.data
|
||||
this.filteredPersonOptionss = [...this.hostUserOptions] // 初始化过滤后的选项
|
||||
console.log('this.hostUserOptions', this.hostUserOptions)
|
||||
})
|
||||
},
|
||||
searchPersons() {
|
||||
if (this.searchQuerys.trim() === '') {
|
||||
this.filteredPersonOptionss = [...this.hostUserOptions]
|
||||
} else {
|
||||
this.filteredPersonOptionss = this.hostUserOptions.filter((person) =>
|
||||
person.username.toLowerCase().includes(this.searchQuerys.toLowerCase()),
|
||||
)
|
||||
}
|
||||
// 确保已选中的选项始终显示在过滤结果中
|
||||
const selectedPersons = this.hostUserOptions.filter((person) =>
|
||||
this.hostUserId.includes(person.userId),
|
||||
)
|
||||
this.filteredPersonOptionss = [
|
||||
...new Set([...selectedPersons, ...this.filteredPersonOptionss]),
|
||||
]
|
||||
},
|
||||
onHostUserChange(e) {
|
||||
// 合并新选中的ID和之前已选中的ID
|
||||
this.hostUserId = [...new Set([...this.hostUserId, ...e.detail.value])]
|
||||
// 移除取消选中的ID
|
||||
|
||||
this.hostUserId = this.hostUserId.filter((id) => e.detail.value.includes(id))
|
||||
this.formData.hostUserId = this.hostUserId.join(',')
|
||||
this.updateSelectedNamess()
|
||||
},
|
||||
updateSelectedNamess() {
|
||||
this.hostUserNames = this.hostUserOptions
|
||||
.filter((person) => this.hostUserId.includes(person.userId))
|
||||
.map((person) => person.username)
|
||||
.join(', ')
|
||||
this.formData.hostUserName = this.hostUserNames
|
||||
},
|
||||
onSubmit() {
|
||||
// 实现表单提交逻辑
|
||||
if (this.validateForm()) {
|
||||
if (!this.isDataUploaded) {
|
||||
this.isFormDisabled = true
|
||||
console.log('禁用表单元素')
|
||||
// 在这里可以添加一些视觉反馈,比如改变按钮文字
|
||||
this.isDataUploaded = true
|
||||
} else {
|
||||
console.log('提交表单:', this.formData)
|
||||
addHoliday(this.formData).then((response) => {
|
||||
if (response.status == 200) {
|
||||
uni.showToast({
|
||||
title: '提交成功',
|
||||
icon: 'success',
|
||||
})
|
||||
// 成功后返回上一级
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1, // 返回上一级
|
||||
})
|
||||
}, 1500) // 可以根据需要调整这个延迟时间,以便用户可以看到成功的提示信息
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '提交失败,请稍后再试',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
// 重置表单状态
|
||||
this.isFormDisabled = false
|
||||
this.isDataUploaded = false
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '请填写所有必填项',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
},
|
||||
onCancel() {
|
||||
if (this.isDataUploaded) {
|
||||
// 如果按钮显示"确认提交",取消禁用并重置状态
|
||||
this.isFormDisabled = false
|
||||
this.isDataUploaded = false
|
||||
// 可能需要重置其他状态,比如:
|
||||
// this.resetForm(); // 假设你有一个重置表单的方法
|
||||
} else {
|
||||
// 否则,返回上一级
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 20rpx 0;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: #007aff;
|
||||
}
|
||||
|
||||
.tab.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 120rpx;
|
||||
height: 4rpx;
|
||||
background: #007aff;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
background: #fff;
|
||||
padding: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.required::after {
|
||||
content: '*';
|
||||
color: #ff4d4f;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
|
||||
.checkbox-group-container {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.checkbox-group-container::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.checkbox-group-container::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.checkbox-group-container::-webkit-scrollbar-thumb {
|
||||
background: #888;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.checkbox-group-container::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
||||
|
||||
input,
|
||||
.picker-value {
|
||||
width: 95%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
padding: 0 20rpx;
|
||||
border: 2rpx solid #e5e5e5;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 95%;
|
||||
height: 160rpx;
|
||||
padding: 20rpx;
|
||||
border: 2rpx solid #e5e5e5;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.radio {
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
margin-top: 40rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: #4080ff;
|
||||
color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: #ff4d4f;
|
||||
font-size: 24rpx;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
<view class="records-container">
|
||||
<view
|
||||
class="record-item"
|
||||
v-for="(record, index) in records"
|
||||
:key="index"
|
||||
@tap="showDetail(record.uuid)"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
<view class="record-header">
|
||||
<text class="label">姓名:</text>
|
||||
<text class="value">{{ record.userName }}</text>
|
||||
<text class="detail-link">详情</text>
|
||||
</view>
|
||||
<view class="record-content">
|
||||
<view class="record-row">
|
||||
<text class="label">休假类型:</text>
|
||||
<text class="value">{{ record.leaveType }}</text>
|
||||
</view>
|
||||
<view class="record-row">
|
||||
<text class="label">休假开始时间:</text>
|
||||
<text class="value">{{ record.leaveStartDate }}</text>
|
||||
</view>
|
||||
<view class="record-row">
|
||||
<text class="label">休假结束时间:</text>
|
||||
<text class="value">{{ record.leaveEndDate }}</text>
|
||||
</view>
|
||||
<view class="record-row">
|
||||
<text class="label">休假时长:</text>
|
||||
<text class="value">{{ record.leaveDuration }}天</text>
|
||||
</view>
|
||||
|
||||
<view class="btn-container">
|
||||
<text>详情</text>
|
||||
<text>修改</text>
|
||||
<text>删除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listLeaveReporting } from '../../api/index.js'
|
||||
export default {
|
||||
name: 'RecordList',
|
||||
data() {
|
||||
return {
|
||||
records: [{ userName: '李思思' }],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 在组件创建时获取记录列表
|
||||
this.fetchRecords()
|
||||
},
|
||||
methods: {
|
||||
fetchRecords() {
|
||||
listLeaveReporting().then((response) => {
|
||||
console.log('response', response)
|
||||
this.records = response.data
|
||||
this.records = [{ userName: '李思思' }]
|
||||
console.log('records', this.records)
|
||||
})
|
||||
},
|
||||
|
||||
showDetail(id) {
|
||||
console.log('id', id)
|
||||
// 跳转到详情页面
|
||||
uni.navigateTo({
|
||||
url: `/pages/holiday/details?uuid=${id}`,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.records-container {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.record-item {
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.record-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.detail-link {
|
||||
color: #007aff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.record-row {
|
||||
display: flex;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
font-size: 28rpx;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #333;
|
||||
font-size: 28rpx;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
text {
|
||||
width: 30%;
|
||||
height: 68rpx;
|
||||
line-height: 68rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
& text:first-child {
|
||||
border: 1px solid #4080ff;
|
||||
color: #4080ff;
|
||||
}
|
||||
& text:nth-child(2) {
|
||||
border: 1px solid #e6a23c;
|
||||
color: #e6a23c;
|
||||
}
|
||||
& text:last-child {
|
||||
border: 1px solid #f56c6c;
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<view class="form-container">
|
||||
<view class="form-item">
|
||||
<text class="label required">姓名</text>
|
||||
<input type="text" v-model="formData.userName" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假类型</text>
|
||||
<input type="text" v-model="formData.leaveType" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假开始时间</text>
|
||||
<input type="text" v-model="formData.leaveStartDate" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假结束时间</text>
|
||||
<input type="text" v-model="formData.leaveEndDate" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假时长(天)</text>
|
||||
<input type="number" v-model="formData.leaveDuration" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">地点</text>
|
||||
<input type="text" v-model="formData.location" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required" style="width: 300px;">是否请示领导同意</text>
|
||||
<input type="text" :value="formData.isAgree === '1' ? '是' : '否'" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">代理主持工作人员</text>
|
||||
<input type="text" v-model="formData.hostUserName" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假事由</text>
|
||||
<textarea v-model="formData.leaveReason" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">备注</text>
|
||||
<textarea v-model="formData.remark" disabled />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getLeaveReporting } from '../../api/index.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
uuid: '',
|
||||
datas:{
|
||||
uuid:''
|
||||
},
|
||||
formData: {
|
||||
userName: '',
|
||||
type:'',
|
||||
leaveType:'',
|
||||
travelersName: '',
|
||||
leaveStartDate: '',
|
||||
leaveEndDate: '',
|
||||
leaveDuration: '',
|
||||
location: '',
|
||||
isAgree: '1',
|
||||
hostUserName: '',
|
||||
leaveReason: '',
|
||||
remark: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.uuid = option.uuid
|
||||
console.log('接收到的id:', this.uuid)
|
||||
this.fetchEvectionDetail()
|
||||
},
|
||||
methods: {
|
||||
fetchEvectionDetail() {
|
||||
try {
|
||||
this.datas.uuid=this.uuid;
|
||||
getLeaveReporting(this.datas).then(response=>{
|
||||
if (response && response.data) {
|
||||
console.log("response.data",response.data)
|
||||
this.formData = {
|
||||
...this.formData,
|
||||
...response.data
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('获取出差详情失败:', error)
|
||||
uni.showToast({
|
||||
title: '获取出差详情失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 20rpx 0;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: #007AFF;
|
||||
}
|
||||
|
||||
.tab.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 120rpx;
|
||||
height: 4rpx;
|
||||
background: #007AFF;
|
||||
}
|
||||
|
||||
/* .tabs {
|
||||
display: flex;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 20rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: #4080FF;
|
||||
border-bottom: 4rpx solid #4080FF;
|
||||
} */
|
||||
|
||||
.form-container {
|
||||
background: #fff;
|
||||
padding: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.required::after {
|
||||
content: '*';
|
||||
color: #ff4d4f;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
|
||||
input, .picker-value {
|
||||
width: 95%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
padding: 0 20rpx;
|
||||
border: 2rpx solid #e5e5e5;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 95%;
|
||||
height: 160rpx;
|
||||
padding: 20rpx;
|
||||
border: 2rpx solid #e5e5e5;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.radio {
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
margin-top: 40rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: #4080FF;
|
||||
color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.error-message {
|
||||
color: #ff4d4f;
|
||||
font-size: 24rpx;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -0,0 +1,666 @@
|
|||
<template>
|
||||
<!-- 轮休申请 -->
|
||||
<view class="container">
|
||||
<view class="tabs">
|
||||
<text class="tab" :class="{ active: activeTab === 'form' }" @tap="switchTab('form')">
|
||||
外出申请
|
||||
</text>
|
||||
<text
|
||||
class="tab"
|
||||
:class="{ active: activeTab === 'records' }"
|
||||
@tap="switchTab('records')"
|
||||
>
|
||||
外出记录
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view v-if="activeTab === 'form'" class="form-container">
|
||||
<view>
|
||||
<text v-if="isFormDisabled" style="color: #3370ff; margin-bottom: 10px">
|
||||
请确认填写信息是否准确,保存后不可修改;若修改可联系相关工作人员在统计报表核对时修改
|
||||
</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label required">申请人</text>
|
||||
<input
|
||||
type="text"
|
||||
v-model="formData.userName"
|
||||
placeholder="请输入申请人姓名"
|
||||
disabled
|
||||
/>
|
||||
<text v-if="errors.userName" class="error-message">{{ errors.userName }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label required">职务</text>
|
||||
<input type="text" v-model="formData.userName" placeholder="请输入职务" disabled />
|
||||
<text v-if="errors.userName" class="error-message">{{ errors.userName }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label required">所属部门</text>
|
||||
<input
|
||||
type="text"
|
||||
v-model="formData.userName"
|
||||
placeholder="请输入所属部门"
|
||||
disabled
|
||||
/>
|
||||
<text v-if="errors.userName" class="error-message">{{ errors.userName }}</text>
|
||||
</view>
|
||||
|
||||
<!-- <view class="form-item">
|
||||
<text class="label required">休假类型</text>
|
||||
<picker
|
||||
@change="onLeaveTypeChange"
|
||||
:disabled="isFormDisabled"
|
||||
:value="leaveTypeIndex"
|
||||
:range="leaveTypes"
|
||||
range-key="label"
|
||||
>
|
||||
<view class="picker-value">
|
||||
{{ formData.leaveType ? formData.leaveType : '请选择休假类型' }}
|
||||
</view>
|
||||
</picker>
|
||||
<text v-if="errors.leaveType" class="error-message">{{ errors.leaveType }}</text>
|
||||
</view> -->
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">外出开始时间</text>
|
||||
<picker
|
||||
mode="date"
|
||||
:value="formData.leaveStartDate"
|
||||
@change="onStartDateChange"
|
||||
:disabled="isFormDisabled"
|
||||
>
|
||||
<view class="picker-value">{{ formData.leaveStartDate }}</view>
|
||||
</picker>
|
||||
<text v-if="errors.leaveStartDate" class="error-message">
|
||||
{{ errors.leaveStartDate }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">外出结束时间</text>
|
||||
<picker
|
||||
mode="date"
|
||||
:value="formData.leaveEndDate"
|
||||
@change="onEndDateChange"
|
||||
:disabled="isFormDisabled"
|
||||
>
|
||||
<view class="picker-value">{{ formData.leaveEndDate }}</view>
|
||||
</picker>
|
||||
<text v-if="errors.leaveEndDate" class="error-message">
|
||||
{{ errors.leaveEndDate }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">外出时长(天)</text>
|
||||
<input type="number" v-model="formData.leaveDuration" disabled />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">地点</text>
|
||||
<input
|
||||
type="text"
|
||||
v-model="formData.location"
|
||||
placeholder="请输入"
|
||||
:disabled="isFormDisabled"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required" style="width: 300px">是否请示领导同意</text>
|
||||
<radio-group @change="onApprovalChange">
|
||||
<label class="radio">
|
||||
<radio
|
||||
value="1"
|
||||
:disabled="isFormDisabled"
|
||||
checked
|
||||
:checked="formData.isAgree === '1'"
|
||||
/>
|
||||
是
|
||||
</label>
|
||||
<label class="radio">
|
||||
<radio
|
||||
value="0"
|
||||
:disabled="isFormDisabled"
|
||||
:checked="formData.isAgree === '0'"
|
||||
/>
|
||||
否
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
|
||||
<view class="form-item" style="margin-bottom: 20rpx">
|
||||
<text
|
||||
class="label required"
|
||||
style="display: block; margin-bottom: 10rpx; width: 300px"
|
||||
>
|
||||
代理主持工作人员
|
||||
</text>
|
||||
<view class="selected-values" style="margin-bottom: 10rpx">
|
||||
{{ hostUserNames }}
|
||||
</view>
|
||||
<view
|
||||
v-if="!isFormDisabled"
|
||||
class="toggle-button"
|
||||
@tap="toggleCheckboxGroups"
|
||||
style="
|
||||
background-color: #f0f0f0;
|
||||
width: 55px;
|
||||
line-height: 35px;
|
||||
text-align: center;
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 10rpx;
|
||||
display: inline-block;
|
||||
margin-bottom: 10rpx;
|
||||
"
|
||||
>
|
||||
{{ isCheckboxGroupVisibles ? '收起' : '展开' }}
|
||||
</view>
|
||||
<view
|
||||
class="checkbox-group-container"
|
||||
v-if="!isFormDisabled && isCheckboxGroupVisibles"
|
||||
>
|
||||
<checkbox-group
|
||||
@change="onHostUserChange"
|
||||
v-if="isCheckboxGroupVisibles"
|
||||
style="display: flex; flex-wrap: wrap"
|
||||
>
|
||||
<view
|
||||
class="search-container"
|
||||
style="display: flex; margin-bottom: 10rpx; width: 100%"
|
||||
>
|
||||
<input
|
||||
v-model="searchQuerys"
|
||||
placeholder="搜索人名"
|
||||
style="
|
||||
flex: 1;
|
||||
padding: 10rpx;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
height: 30px;
|
||||
"
|
||||
/>
|
||||
<button
|
||||
@tap="searchPersons"
|
||||
style="
|
||||
line-height: 22px;
|
||||
font-size: 13px;
|
||||
margin-left: 10rpx;
|
||||
padding: 10px 20px;
|
||||
background-color: #007aff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
搜索
|
||||
</button>
|
||||
</view>
|
||||
<label
|
||||
v-for="(option, index) in displayedPersonOptionss"
|
||||
:key="index"
|
||||
style="width: 33.33%; padding: 10rpx; box-sizing: border-box"
|
||||
>
|
||||
<checkbox
|
||||
:value="option.userId"
|
||||
:checked="option.checked"
|
||||
style="transform: scale(0.7)"
|
||||
/>
|
||||
<text style="font-size: 28rpx">{{ option.username }}</text>
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label required">休假事由</text>
|
||||
<textarea
|
||||
v-model="formData.leaveReason"
|
||||
placeholder="请输入休假事由"
|
||||
:disabled="isFormDisabled"
|
||||
/>
|
||||
<text v-if="errors.leaveReason" class="error-message">
|
||||
{{ errors.leaveReason }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="label">备注</text>
|
||||
<textarea v-model="formData.remark" :disabled="isFormDisabled" />
|
||||
</view>
|
||||
|
||||
<view class="button-group">
|
||||
<button
|
||||
class="submit-btn"
|
||||
@tap="onSubmit"
|
||||
:disabled="isFormDisabled && !isDataUploaded"
|
||||
>
|
||||
{{ isDataUploaded ? '确认提交' : '保存' }}
|
||||
</button>
|
||||
<button class="cancel-btn" @tap="onCancel">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<RecordList v-if="activeTab === 'records'" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPersonSelect, addHoliday, getHolidayType, getDays } from '../../api/index.js'
|
||||
import RecordList from './recordList.vue'
|
||||
export default {
|
||||
components: {
|
||||
RecordList,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isFormDisabled: false,
|
||||
isDataUploaded: false,
|
||||
showConfirmDialog: false,
|
||||
searchQuerys: '',
|
||||
activeTab: 'form',
|
||||
formData: {
|
||||
userName: '',
|
||||
leaveType: null,
|
||||
leaveStartDate: '',
|
||||
leaveEndDate: '',
|
||||
leaveDuration: '',
|
||||
location: '',
|
||||
isAgree: '1',
|
||||
representative: '',
|
||||
hostUserId: '',
|
||||
hostUserName: '',
|
||||
leaveReason: '',
|
||||
remark: '',
|
||||
},
|
||||
userInfo: {
|
||||
token: '',
|
||||
userId: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
},
|
||||
leaveTypes: [],
|
||||
leaveTypeIndex: -1,
|
||||
today: new Date().toISOString().substr(0, 10), // 格式化为YYYY-MM-DD
|
||||
errors: {},
|
||||
hostUserOptions: [], // 人员选项列表
|
||||
filteredPersonOptionss: [],
|
||||
hostUserId: [], // 选中的ID列表
|
||||
hostUserNames: '', // 显示的选中名字
|
||||
isCheckboxGroupVisibles: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 在组件挂载后读取存储的数据
|
||||
this.userInfo.token = uni.getStorageSync('token') || ''
|
||||
this.userInfo.userId = uni.getStorageSync('userId') || ''
|
||||
this.userInfo.name = uni.getStorageSync('username') || ''
|
||||
this.userInfo.phone = uni.getStorageSync('phone') || ''
|
||||
this.formData.userName = uni.getStorageSync('username') || ''
|
||||
},
|
||||
created() {
|
||||
this.gethostUserSelect()
|
||||
this.getHolidayType()
|
||||
},
|
||||
computed: {
|
||||
displayedPersonOptionss() {
|
||||
return this.filteredPersonOptionss.map((person) => ({
|
||||
...person,
|
||||
checked: this.hostUserId.includes(person.userId),
|
||||
}))
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleCheckboxGroups() {
|
||||
this.isCheckboxGroupVisibles = !this.isCheckboxGroupVisibles
|
||||
},
|
||||
switchTab(tab) {
|
||||
this.activeTab = tab
|
||||
},
|
||||
getHolidayType() {
|
||||
getHolidayType()
|
||||
.then((response) => {
|
||||
this.leaveTypes = response.data.map((type) => ({
|
||||
value: type.value,
|
||||
label: type.label || type.type, // 使用label如果存在,否则使用type
|
||||
}))
|
||||
if (this.leaveTypes.length > 0) {
|
||||
this.formData.leaveType = this.leaveTypes[0].label
|
||||
this.leaveTypeIndex = 0
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取休假类型失败:', error)
|
||||
// 可以在这里添加错误提示
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
onLeaveTypeChange(e) {
|
||||
const index = e.detail.value
|
||||
this.leaveTypeIndex = index
|
||||
this.formData.leaveType = this.leaveTypes[index].label
|
||||
console.log(this.formData.leaveType)
|
||||
console.log('休假类型已更改为:', this.formData.leaveType)
|
||||
},
|
||||
onStartDateChange(e) {
|
||||
const startDate = e.detail.value
|
||||
this.formData.leaveStartDate = startDate
|
||||
this.validateAndCalculateDuration(startDate, this.formData.leaveEndDate)
|
||||
},
|
||||
onEndDateChange(e) {
|
||||
const endDate = e.detail.value
|
||||
this.formData.leaveEndDate = endDate
|
||||
this.validateAndCalculateDuration(this.formData.leaveStartDate, endDate)
|
||||
},
|
||||
validateAndCalculateDuration(startDate, endDate) {
|
||||
// 清除之前的错误信息
|
||||
this.errors.leaveStartDate = ''
|
||||
this.errors.leaveEndDate = ''
|
||||
|
||||
// 转换日期为Date对象
|
||||
const start = new Date(startDate)
|
||||
const end = new Date(endDate)
|
||||
const today = new Date(this.today)
|
||||
|
||||
// 验证开始日期不能早于今天
|
||||
if (start < today) {
|
||||
this.errors.leaveStartDate = '开始日期不能早于今天'
|
||||
this.formData.leaveStartDate = ''
|
||||
return
|
||||
}
|
||||
|
||||
// 验证结束日期不能早于开始日期
|
||||
if (end < start) {
|
||||
this.errors.leaveEndDate = '结束日期不能早于开始日期'
|
||||
this.formData.leaveEndDate = ''
|
||||
return
|
||||
}
|
||||
|
||||
let dateData = {
|
||||
startTime: startDate,
|
||||
endTime: endDate,
|
||||
}
|
||||
if (startDate != null && startDate !== '' && endDate != null && endDate !== '') {
|
||||
getDays(dateData).then((response) => {
|
||||
if (response.status === 200) {
|
||||
console.log(response)
|
||||
this.formData.leaveDuration = response.data
|
||||
} else {
|
||||
this.formData.leaveDuration = ''
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
onApprovalChange(e) {
|
||||
this.formData.isApproved = e.detail.value
|
||||
},
|
||||
onRepresentativeChange(e) {
|
||||
this.formData.representative = e.detail.value
|
||||
},
|
||||
validateForm() {
|
||||
this.errors = {}
|
||||
|
||||
if (!this.formData.userName.trim()) {
|
||||
this.errors.userName = '请输入姓名'
|
||||
}
|
||||
if (!this.formData.leaveType) {
|
||||
this.errors.leaveType = '请选择休假类型'
|
||||
}
|
||||
if (!this.formData.leaveStartDate) {
|
||||
this.errors.leaveStartDate = '请选择休假开始时间'
|
||||
}
|
||||
if (!this.formData.leaveEndDate) {
|
||||
this.errors.leaveEndDate = '请选择休假结束时间'
|
||||
}
|
||||
if (!this.formData.leaveDuration) {
|
||||
this.errors.leaveDuration = '请输入休假时长'
|
||||
}
|
||||
if (!this.formData.hostUserId) {
|
||||
this.errors.hostUserId = '请选择代理主持工作人员'
|
||||
}
|
||||
if (!this.formData.leaveReason.trim()) {
|
||||
this.errors.leaveReason = '请输入休假事由'
|
||||
}
|
||||
|
||||
return Object.keys(this.errors).length === 0
|
||||
},
|
||||
gethostUserSelect() {
|
||||
// 假设getPersonSelect是一个API调用函数,返回Promise
|
||||
getPersonSelect().then((response) => {
|
||||
this.hostUserOptions = response.data
|
||||
this.filteredPersonOptionss = [...this.hostUserOptions] // 初始化过滤后的选项
|
||||
console.log('this.hostUserOptions', this.hostUserOptions)
|
||||
})
|
||||
},
|
||||
searchPersons() {
|
||||
if (this.searchQuerys.trim() === '') {
|
||||
this.filteredPersonOptionss = [...this.hostUserOptions]
|
||||
} else {
|
||||
this.filteredPersonOptionss = this.hostUserOptions.filter((person) =>
|
||||
person.username.toLowerCase().includes(this.searchQuerys.toLowerCase()),
|
||||
)
|
||||
}
|
||||
// 确保已选中的选项始终显示在过滤结果中
|
||||
const selectedPersons = this.hostUserOptions.filter((person) =>
|
||||
this.hostUserId.includes(person.userId),
|
||||
)
|
||||
this.filteredPersonOptionss = [
|
||||
...new Set([...selectedPersons, ...this.filteredPersonOptionss]),
|
||||
]
|
||||
},
|
||||
onHostUserChange(e) {
|
||||
// 合并新选中的ID和之前已选中的ID
|
||||
this.hostUserId = [...new Set([...this.hostUserId, ...e.detail.value])]
|
||||
// 移除取消选中的ID
|
||||
|
||||
this.hostUserId = this.hostUserId.filter((id) => e.detail.value.includes(id))
|
||||
this.formData.hostUserId = this.hostUserId.join(',')
|
||||
this.updateSelectedNamess()
|
||||
},
|
||||
updateSelectedNamess() {
|
||||
this.hostUserNames = this.hostUserOptions
|
||||
.filter((person) => this.hostUserId.includes(person.userId))
|
||||
.map((person) => person.username)
|
||||
.join(', ')
|
||||
this.formData.hostUserName = this.hostUserNames
|
||||
},
|
||||
onSubmit() {
|
||||
// 实现表单提交逻辑
|
||||
if (this.validateForm()) {
|
||||
if (!this.isDataUploaded) {
|
||||
this.isFormDisabled = true
|
||||
console.log('禁用表单元素')
|
||||
// 在这里可以添加一些视觉反馈,比如改变按钮文字
|
||||
this.isDataUploaded = true
|
||||
} else {
|
||||
console.log('提交表单:', this.formData)
|
||||
addHoliday(this.formData).then((response) => {
|
||||
if (response.status == 200) {
|
||||
uni.showToast({
|
||||
title: '提交成功',
|
||||
icon: 'success',
|
||||
})
|
||||
// 成功后返回上一级
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({
|
||||
delta: 1, // 返回上一级
|
||||
})
|
||||
}, 1500) // 可以根据需要调整这个延迟时间,以便用户可以看到成功的提示信息
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '提交失败,请稍后再试',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
// 重置表单状态
|
||||
this.isFormDisabled = false
|
||||
this.isDataUploaded = false
|
||||
})
|
||||
}
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '请填写所有必填项',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
},
|
||||
onCancel() {
|
||||
if (this.isDataUploaded) {
|
||||
// 如果按钮显示"确认提交",取消禁用并重置状态
|
||||
this.isFormDisabled = false
|
||||
this.isDataUploaded = false
|
||||
// 可能需要重置其他状态,比如:
|
||||
// this.resetForm(); // 假设你有一个重置表单的方法
|
||||
} else {
|
||||
// 否则,返回上一级
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 20rpx 0;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
color: #007aff;
|
||||
}
|
||||
|
||||
.tab.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 120rpx;
|
||||
height: 4rpx;
|
||||
background: #007aff;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
background: #fff;
|
||||
padding: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.required::after {
|
||||
content: '*';
|
||||
color: #ff4d4f;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
|
||||
.checkbox-group-container {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
}
|
||||
|
||||
.checkbox-group-container::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.checkbox-group-container::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.checkbox-group-container::-webkit-scrollbar-thumb {
|
||||
background: #888;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.checkbox-group-container::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
||||
|
||||
input,
|
||||
.picker-value {
|
||||
width: 95%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
padding: 0 20rpx;
|
||||
border: 2rpx solid #e5e5e5;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 95%;
|
||||
height: 160rpx;
|
||||
padding: 20rpx;
|
||||
border: 2rpx solid #e5e5e5;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.radio {
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
margin-top: 40rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: #4080ff;
|
||||
color: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: #ff4d4f;
|
||||
font-size: 24rpx;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<view class="records-container">
|
||||
<view
|
||||
class="record-item"
|
||||
v-for="(record, index) in records"
|
||||
:key="index"
|
||||
@tap="showDetail(record.uuid)"
|
||||
style="cursor: pointer"
|
||||
>
|
||||
<view class="record-header">
|
||||
<text class="label">姓名:</text>
|
||||
<text class="value">{{ record.userName }}</text>
|
||||
<text class="detail-link">详情</text>
|
||||
</view>
|
||||
<view class="record-content">
|
||||
<view class="record-row">
|
||||
<text class="label">休假类型:</text>
|
||||
<text class="value">{{ record.leaveType }}</text>
|
||||
</view>
|
||||
<view class="record-row">
|
||||
<text class="label">休假开始时间:</text>
|
||||
<text class="value">{{ record.leaveStartDate }}</text>
|
||||
</view>
|
||||
<view class="record-row">
|
||||
<text class="label">休假结束时间:</text>
|
||||
<text class="value">{{ record.leaveEndDate }}</text>
|
||||
</view>
|
||||
<view class="record-row">
|
||||
<text class="label">休假时长:</text>
|
||||
<text class="value">{{ record.leaveDuration }}天</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn-container">
|
||||
<text>详情</text>
|
||||
<text>修改</text>
|
||||
<text>删除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listLeaveReporting } from '../../api/index.js'
|
||||
export default {
|
||||
name: 'RecordList',
|
||||
data() {
|
||||
return {
|
||||
records: [{ userName: '李思思' }],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 在组件创建时获取记录列表
|
||||
this.fetchRecords()
|
||||
},
|
||||
methods: {
|
||||
fetchRecords() {
|
||||
listLeaveReporting().then((response) => {
|
||||
console.log('response', response)
|
||||
// this.records = response.data
|
||||
console.log('records', this.records)
|
||||
})
|
||||
},
|
||||
|
||||
showDetail(id) {
|
||||
console.log('id', id)
|
||||
// 跳转到详情页面
|
||||
uni.navigateTo({
|
||||
url: `/pages/holiday/details?uuid=${id}`,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.records-container {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.record-item {
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.record-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.detail-link {
|
||||
color: #007aff;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.record-row {
|
||||
display: flex;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
font-size: 28rpx;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #333;
|
||||
font-size: 28rpx;
|
||||
flex: 1;
|
||||
}
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
text {
|
||||
width: 30%;
|
||||
height: 68rpx;
|
||||
line-height: 68rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
& text:first-child {
|
||||
border: 1px solid #4080ff;
|
||||
color: #4080ff;
|
||||
}
|
||||
& text:nth-child(2) {
|
||||
border: 1px solid #e6a23c;
|
||||
color: #e6a23c;
|
||||
}
|
||||
& text:last-child {
|
||||
border: 1px solid #f56c6c;
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
Loading…
Reference in New Issue