Merge branch 'develop' into develop_daisy
This commit is contained in:
commit
fdfae11edf
@ -109,6 +109,7 @@
|
|||||||
"@dcloudio/vite-plugin-uni": "3.0.0-4020920240930001",
|
"@dcloudio/vite-plugin-uni": "3.0.0-4020920240930001",
|
||||||
"@esbuild/darwin-arm64": "0.20.2",
|
"@esbuild/darwin-arm64": "0.20.2",
|
||||||
"@esbuild/darwin-x64": "0.20.2",
|
"@esbuild/darwin-x64": "0.20.2",
|
||||||
|
"@iconify-json/bytesize": "^1.2.2",
|
||||||
"@iconify-json/carbon": "^1.2.4",
|
"@iconify-json/carbon": "^1.2.4",
|
||||||
"@rollup/rollup-darwin-x64": "^4.28.0",
|
"@rollup/rollup-darwin-x64": "^4.28.0",
|
||||||
"@types/node": "^20.17.9",
|
"@types/node": "^20.17.9",
|
||||||
|
|||||||
20
pnpm-lock.yaml
generated
20
pnpm-lock.yaml
generated
@ -72,8 +72,8 @@ importers:
|
|||||||
specifier: 3.4.21
|
specifier: 3.4.21
|
||||||
version: 3.4.21(typescript@5.7.2)
|
version: 3.4.21(typescript@5.7.2)
|
||||||
wot-design-uni:
|
wot-design-uni:
|
||||||
specifier: 1.5.1
|
specifier: 1.4.0
|
||||||
version: 1.5.1(vue@3.4.21(typescript@5.7.2))
|
version: 1.4.0(vue@3.4.21(typescript@5.7.2))
|
||||||
z-paging:
|
z-paging:
|
||||||
specifier: ^2.8.4
|
specifier: ^2.8.4
|
||||||
version: 2.8.4
|
version: 2.8.4
|
||||||
@ -105,6 +105,9 @@ importers:
|
|||||||
'@esbuild/darwin-x64':
|
'@esbuild/darwin-x64':
|
||||||
specifier: 0.20.2
|
specifier: 0.20.2
|
||||||
version: 0.20.2
|
version: 0.20.2
|
||||||
|
'@iconify-json/bytesize':
|
||||||
|
specifier: ^1.2.2
|
||||||
|
version: 1.2.2
|
||||||
'@iconify-json/carbon':
|
'@iconify-json/carbon':
|
||||||
specifier: ^1.2.4
|
specifier: ^1.2.4
|
||||||
version: 1.2.4
|
version: 1.2.4
|
||||||
@ -1223,6 +1226,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
|
resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
|
||||||
deprecated: Use @eslint/object-schema instead
|
deprecated: Use @eslint/object-schema instead
|
||||||
|
|
||||||
|
'@iconify-json/bytesize@1.2.2':
|
||||||
|
resolution: {integrity: sha512-lI/wtPosh84caAS+UcudpeKiQk9ShfVoeaUTtzgOOBUhwQvjDuSiiHqe84v5NluHuIIFW64Fa3kuoGoluxWgpA==}
|
||||||
|
|
||||||
'@iconify-json/carbon@1.2.4':
|
'@iconify-json/carbon@1.2.4':
|
||||||
resolution: {integrity: sha512-DhW2jjMVGwV0DLHc0cmDYohdtGxMra8UuwgjHrryPy+rQX4gXhJwCBBVP2h2UG/92AoRCTn7zUJve4WvY5MLYg==}
|
resolution: {integrity: sha512-DhW2jjMVGwV0DLHc0cmDYohdtGxMra8UuwgjHrryPy+rQX4gXhJwCBBVP2h2UG/92AoRCTn7zUJve4WvY5MLYg==}
|
||||||
|
|
||||||
@ -5456,8 +5462,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
wot-design-uni@1.5.1:
|
wot-design-uni@1.4.0:
|
||||||
resolution: {integrity: sha512-jiDRuF8r7+xAldc4Dp+2T1VnqDnOoMWsXu6aRpDg2QG7ZH+/bJl7W8H8hHbKFgA9lu1By/HCDmpG7JC45nYtBw==}
|
resolution: {integrity: sha512-h6sjrgfg7mP0nJwGTiHn/iTLPFyRswMpQV6MKhWN3skTnXe+FAyndvtXofpXp+uLkTXefGfw5BPI0uuCMD874w==}
|
||||||
engines: {HBuilderX: ^3.8.7}
|
engines: {HBuilderX: ^3.8.7}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: '>=3.2.47'
|
vue: '>=3.2.47'
|
||||||
@ -7190,6 +7196,10 @@ snapshots:
|
|||||||
|
|
||||||
'@humanwhocodes/object-schema@2.0.3': {}
|
'@humanwhocodes/object-schema@2.0.3': {}
|
||||||
|
|
||||||
|
'@iconify-json/bytesize@1.2.2':
|
||||||
|
dependencies:
|
||||||
|
'@iconify/types': 2.0.0
|
||||||
|
|
||||||
'@iconify-json/carbon@1.2.4':
|
'@iconify-json/carbon@1.2.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@iconify/types': 2.0.0
|
'@iconify/types': 2.0.0
|
||||||
@ -12236,7 +12246,7 @@ snapshots:
|
|||||||
|
|
||||||
word-wrap@1.2.5: {}
|
word-wrap@1.2.5: {}
|
||||||
|
|
||||||
wot-design-uni@1.5.1(vue@3.4.21(typescript@5.7.2)):
|
wot-design-uni@1.4.0(vue@3.4.21(typescript@5.7.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.4.21(typescript@5.7.2)
|
vue: 3.4.21(typescript@5.7.2)
|
||||||
|
|
||||||
|
|||||||
81
src/components/BottomPop/BottomPop.vue
Normal file
81
src/components/BottomPop/BottomPop.vue
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<wd-popup
|
||||||
|
v-model="visible"
|
||||||
|
custom-style="border-top-left-radius: 0.3125rem;
|
||||||
|
border-top-right-radius: 0.3125rem;background-color:#f6f8fc"
|
||||||
|
position="bottom"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<view class="box-border">
|
||||||
|
<view class="flex p-3 flex-justify-center">
|
||||||
|
<view class="font-bold text-4">{{ title }}</view>
|
||||||
|
<wd-icon
|
||||||
|
class="position-absolute right-3 top-4.5 color-gray"
|
||||||
|
name="close"
|
||||||
|
size="15"
|
||||||
|
@click="handleClose"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<slot name="child"></slot>
|
||||||
|
</view>
|
||||||
|
<wd-button
|
||||||
|
v-if="!noSure"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
onSure()
|
||||||
|
handleClose()
|
||||||
|
}
|
||||||
|
"
|
||||||
|
class="mx-3 my-5"
|
||||||
|
block
|
||||||
|
>
|
||||||
|
确定
|
||||||
|
</wd-button>
|
||||||
|
<view v-else class="mx-3 my-5"></view>
|
||||||
|
</view>
|
||||||
|
</wd-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const props = defineProps({
|
||||||
|
// 标题
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 关闭回调
|
||||||
|
onclose: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
// 是否显示
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
// 确定回调
|
||||||
|
onSure: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
// 不要确定按钮
|
||||||
|
noSure: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const visible = ref(props.show)
|
||||||
|
watchEffect(() => {
|
||||||
|
visible.value = props.show
|
||||||
|
})
|
||||||
|
const handleClose = () => {
|
||||||
|
visible.value = false
|
||||||
|
props.onclose()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
//
|
||||||
|
</style>
|
||||||
68
src/components/CommonItemItem/CommonItem.vue
Normal file
68
src/components/CommonItemItem/CommonItem.vue
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<view class="mx-2">
|
||||||
|
<view class="flex flex-row items-center py-3.5">
|
||||||
|
<view class="mr-0.5" :class="isMust ? 'color-red' : 'color-transparent'">*</view>
|
||||||
|
<view v-if="text">{{ text }}</view>
|
||||||
|
<view v-if="$slots.leftChild">
|
||||||
|
<slot name="leftChild"></slot>
|
||||||
|
</view>
|
||||||
|
<view v-if="$slots.child" class="flex-1 flex flex-row mx-2">
|
||||||
|
<slot name="child" class="flex-1"></slot>
|
||||||
|
</view>
|
||||||
|
<view v-if="!$slots.child" class="flex-1 flex flex-row flex-justify-end items-center">
|
||||||
|
<view v-if="!value" class="color-gray">{{ hint }}</view>
|
||||||
|
<view v-else class="color-[#656567]">{{ value }}</view>
|
||||||
|
<wd-icon
|
||||||
|
v-if="isNext"
|
||||||
|
name="arrow-right ml-1.5 mr-0.5"
|
||||||
|
class="text-gray"
|
||||||
|
size="22"
|
||||||
|
></wd-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!noLine" class="hpx bg-gray-100 mx-2.5"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const props = defineProps({
|
||||||
|
// 标题
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 是否必填
|
||||||
|
isMust: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 显示的值
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 是否显示下一步
|
||||||
|
isNext: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 没有下划线
|
||||||
|
noLine: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 无value时的提示
|
||||||
|
hint: {
|
||||||
|
type: String,
|
||||||
|
default: '请选择'
|
||||||
|
}
|
||||||
|
// 没有child时使用选择模版
|
||||||
|
})
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
page {
|
||||||
|
background-color: #f6f8fc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
91
src/pages/attendance/AttendanceClockIn.vue
Normal file
91
src/pages/attendance/AttendanceClockIn.vue
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view v-if="canClockIn">
|
||||||
|
<view class="bg-white rounded-2 p-4 box-border mx-3">
|
||||||
|
<view v-for="(item, index) in clockInList" :key="index">
|
||||||
|
<view class="flex flex-row flex-justify-between items-center">
|
||||||
|
<view class="font-bold text-4">{{ item.title }}</view>
|
||||||
|
<view class="color-[#3372FA]">{{ item.status }}</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
:class="item.title == '上班' ? '' : 'inline-block'"
|
||||||
|
class="hpx bg-gray-100 my-3"
|
||||||
|
></view>
|
||||||
|
<view v-if="item.isClockIn == false">
|
||||||
|
<view @click="goRules()" class="color-[#3372FA]">考勤 ></view>
|
||||||
|
<view
|
||||||
|
class="gradual w-30 h-30 mx-a rounded-36 mt-15 shadow shadow-blue-400 shadow-lg flex flex-col items-center justify-center color-white"
|
||||||
|
>
|
||||||
|
<view class="text-6.5 font-bold">
|
||||||
|
{{ time.getHours().toString().padStart(2, '0') }}:{{
|
||||||
|
time.getMinutes().toString().padStart(2, '0')
|
||||||
|
}}
|
||||||
|
</view>
|
||||||
|
<view class="text-3 font-300">点击打卡</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-row flex-justify-center items-center my-5">
|
||||||
|
<view class="i-carbon-location-filled color-[#3372FA]"></view>
|
||||||
|
<view class="ml-1 text-3">你已在打卡范围内</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else>
|
||||||
|
<view class="bg-white rounded-2 pt-20 pb-15 box-border mx-3 pt-2">
|
||||||
|
<view class="text-center">
|
||||||
|
<image src="/static/images/icon_wechat.png" class="w-30 h30" />
|
||||||
|
</view>
|
||||||
|
<view class="text-center mt-2 color-gray">你所在考勤组无法手机打卡</view>
|
||||||
|
<view class="text-center color-gray">请在考勤机或者门禁设备上打卡</view>
|
||||||
|
</view>
|
||||||
|
<view class="w-100% h-17 bg-[#3372FA] mt-2 rounded-2" @click="goHelper"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
const canClockIn = ref(true)
|
||||||
|
const time = ref(new Date())
|
||||||
|
onMounted(() => {
|
||||||
|
setInterval(() => {
|
||||||
|
time.value = new Date()
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
const clockInList = ref([
|
||||||
|
{
|
||||||
|
title: '上班',
|
||||||
|
status: '正常',
|
||||||
|
isClockIn: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '下班',
|
||||||
|
status: '未打卡',
|
||||||
|
isClockIn: false
|
||||||
|
}
|
||||||
|
])
|
||||||
|
const goRules = () => {
|
||||||
|
console.log('goRules')
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/attendance-rules'
|
||||||
|
})
|
||||||
|
// todo goRules
|
||||||
|
}
|
||||||
|
const goHelper = () => {
|
||||||
|
// todo goHelper
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.gradual {
|
||||||
|
background: linear-gradient(to bottom, #50a0f5, #1e6eed);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
111
src/pages/attendance/AttendanceSet.vue
Normal file
111
src/pages/attendance/AttendanceSet.vue
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="mx-4 pt-2">
|
||||||
|
<view
|
||||||
|
class="my-2 p-3.5 flex flex-justify-between rounded-2.2 items-center bg-white"
|
||||||
|
@click="goAddGroup"
|
||||||
|
>
|
||||||
|
<view class="color-[#3372FA]">添加考勤组</view>
|
||||||
|
<wd-icon name="add-circle" class="color-[#3372FA]" size="20"></wd-icon>
|
||||||
|
</view>
|
||||||
|
<view class="my-2 p-3.5 flex flex-justify-between rounded-2.2 items-center bg-white">
|
||||||
|
<view class="flex flex-col">
|
||||||
|
<view>考勤</view>
|
||||||
|
<view class="text-gray mt-1 text-3">固定班制</view>
|
||||||
|
</view>
|
||||||
|
<wd-icon name="arrow-right" class="text-gray" size="20"></wd-icon>
|
||||||
|
</view>
|
||||||
|
<view class="text-gray mt-4 ml-3 text-3 mb-2">其他设置</view>
|
||||||
|
<view class="flex flex-row flex-justify-between">
|
||||||
|
<view
|
||||||
|
@click="goClasses()"
|
||||||
|
class="p-3.5 bg-white rounded-2.2 flex-1 mr-1 flex flex-row items-center"
|
||||||
|
>
|
||||||
|
<image src="/static/images/icon_wechat.png" class="w-6 h-6 mr-2" />
|
||||||
|
<view class="text-3">班次管理</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
@click="goIssueRecord"
|
||||||
|
class="p-3.5 bg-white rounded-2.2 flex-1 ml-1 flex flex-row items-center"
|
||||||
|
>
|
||||||
|
<image src="/static/images/icon_wechat.png" class="w-6 h-6 mr-2" />
|
||||||
|
<view class="text-3">下发记录</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="text-gray mt-4 ml-3 text-3 mb-2">了解详情</view>
|
||||||
|
<view class="flex flex-wrap bg-white rounded-2.2 px-3 py-1.5 flex-justify-between">
|
||||||
|
<view
|
||||||
|
v-for="(item, index) in [
|
||||||
|
'电脑网页端',
|
||||||
|
'微信小程序',
|
||||||
|
'人脸-指纹-卡片',
|
||||||
|
'假勤-补卡申请',
|
||||||
|
'打卡问题检测',
|
||||||
|
'打卡-缺卡提醒'
|
||||||
|
]"
|
||||||
|
:key="index"
|
||||||
|
class="my-1.5 bg-[#F6F8FC] w-4.8/10 py-3.5 px-2 rounded-2.2 box-border flex flex-row items-center"
|
||||||
|
>
|
||||||
|
<image src="/static/images/icon_wechat.png" class="w-5 h-5" mode="scaleToFill" />
|
||||||
|
<view class="text-center text-2.5 custom-color-black ml-1">{{ item }}</view>
|
||||||
|
<wd-icon name="arrow-right" class="text-gray flex-1 text-right" size="20"></wd-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { TabBarItem } from '@/typings'
|
||||||
|
|
||||||
|
const list = ref<Array<TabBarItem>>([
|
||||||
|
{
|
||||||
|
title: '首页',
|
||||||
|
isDot: true,
|
||||||
|
icon: 'home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '我的',
|
||||||
|
value: 0,
|
||||||
|
icon: '/static/tabbar/home.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '最大值',
|
||||||
|
value: 200,
|
||||||
|
icon: '/static/tabbar/home.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '客服',
|
||||||
|
value: 3,
|
||||||
|
icon: '/static/tabbar/home.png'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
function goAddGroup() {
|
||||||
|
// todo goAddGroup
|
||||||
|
console.log('goAddGroup')
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/attendance-add-group/attendance-add-group'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const goClasses = () => {
|
||||||
|
console.log('goClasses')
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/classes-manage'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const goIssueRecord = () => {
|
||||||
|
console.log('goIssueRecord')
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/issue-record'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
113
src/pages/attendance/AttendanceStatistics.vue
Normal file
113
src/pages/attendance/AttendanceStatistics.vue
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="flex flex-col flex-1">
|
||||||
|
<wd-tabs v-model="tabIndex" color="#3372FA" inactiveColor="gray">
|
||||||
|
<block v-for="item in tabs" :key="item">
|
||||||
|
<wd-tab :title="item"></wd-tab>
|
||||||
|
</block>
|
||||||
|
</wd-tabs>
|
||||||
|
<view v-if="tabIndex == 0" class="flex-1 flex flex-col px-3 pt-4">
|
||||||
|
<view class="flex flex-row items-center">
|
||||||
|
<wd-icon name="arrow-left" class="text-gray" size="20"></wd-icon>
|
||||||
|
<view class="w-30 text-center">
|
||||||
|
{{ new Date(teamDateTime).getFullYear() }}年{{ new Date(teamDateTime).getMonth() + 1 }}月
|
||||||
|
</view>
|
||||||
|
<wd-icon name="arrow-right" class="text-gray" size="20"></wd-icon>
|
||||||
|
<view class="color-[#3372FA] flex-1 text-end text-3">查看/导出月报</view>
|
||||||
|
</view>
|
||||||
|
<view class="rounded-2 bg-white mt-4 p-3.5 flex flex-col">
|
||||||
|
<wd-calendar-view
|
||||||
|
v-model="teamDateTime"
|
||||||
|
@change="handleChange"
|
||||||
|
:min-date="new Date(new Date().getFullYear(), new Date().getMonth(), 1).getTime()"
|
||||||
|
:max-date="new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0).getTime()"
|
||||||
|
/>
|
||||||
|
<view class="h-px bg-gray-300 my-4"></view>
|
||||||
|
<wd-circle
|
||||||
|
class="flex flex-row flex-justify-center mt-2"
|
||||||
|
v-model="current"
|
||||||
|
:size="100"
|
||||||
|
:strokeWidth="20"
|
||||||
|
></wd-circle>
|
||||||
|
<view class="text-5 font-500 text-center mt-3">0/13</view>
|
||||||
|
<view class="text-3 color-gray text-center">打卡人数/应到人数</view>
|
||||||
|
<view class="flex flex-row flex-justify-between mt-4 mx-5">
|
||||||
|
<view v-for="(item, index) in statusList" :key="index" class="flex flex-col items-center">
|
||||||
|
<view class="font-bold">{{ item.value }}</view>
|
||||||
|
<view class="text-3 color-gray">{{ item.name }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="w-100% h-17 bg-blue mt-2 rounded-2" @click="goCheck"></view>
|
||||||
|
<view class="w-100% h-17 bg-gray mt-2 rounded-2" @click="goProblem"></view>
|
||||||
|
</view>
|
||||||
|
<view v-if="tabIndex == 1" class="flex-1 flex flex-col px-3 pt-4">
|
||||||
|
<view class="flex flex-row items-center">
|
||||||
|
<wd-icon name="arrow-left" class="text-gray" size="20"></wd-icon>
|
||||||
|
<view class="w-30 text-center">
|
||||||
|
{{ new Date(teamDateTime).getFullYear() }}年{{ new Date(teamDateTime).getMonth() + 1 }}月
|
||||||
|
</view>
|
||||||
|
<wd-icon name="arrow-right" class="text-gray" size="20"></wd-icon>
|
||||||
|
<view class="color-[#3372FA] flex-1 text-end text-3">查看月报</view>
|
||||||
|
</view>
|
||||||
|
<view class="rounded-2 bg-white mt-4 p-3.5 flex flex-col">
|
||||||
|
<wd-calendar-view
|
||||||
|
v-model="myDateTime"
|
||||||
|
@change="handleChange"
|
||||||
|
:min-date="new Date(new Date().getFullYear(), new Date().getMonth(), 1).getTime()"
|
||||||
|
:max-date="new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0).getTime()"
|
||||||
|
/>
|
||||||
|
<view class="h-px bg-gray-300 my-4"></view>
|
||||||
|
<view class="flex flex-row flex-justify-between items-center">
|
||||||
|
<view class="text-4 font-500 text-center">
|
||||||
|
{{ new Date(myDateTime).getFullYear() }}年{{ new Date(myDateTime).getMonth() + 1 }}月{{
|
||||||
|
new Date(myDateTime).getDate()
|
||||||
|
}}日
|
||||||
|
</view>
|
||||||
|
<view class="color-gray text-3">休息</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
//
|
||||||
|
const tabs = ['团队统计', '我的统计']
|
||||||
|
const statusList = ref([
|
||||||
|
{ name: '未打卡', value: 13 },
|
||||||
|
{ name: '迟到', value: 0 },
|
||||||
|
{ name: '请假', value: 0 }
|
||||||
|
])
|
||||||
|
const tabIndex = ref(0)
|
||||||
|
const teamDateTime = ref(Date.now())
|
||||||
|
const myDateTime = ref(Date.now())
|
||||||
|
const current = ref<number>(17)
|
||||||
|
function handleChange({ value }) {
|
||||||
|
console.log(value)
|
||||||
|
}
|
||||||
|
function goCheck() {
|
||||||
|
console.log('goCheck')
|
||||||
|
}
|
||||||
|
function goProblem() {
|
||||||
|
console.log('goProblem')
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
console.log('mounted')
|
||||||
|
current.value = Math.random() * 100
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.wd-circle {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
73
src/pages/attendance/allowed-time.vue
Normal file
73
src/pages/attendance/allowed-time.vue
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="flex flex-col h-100vh">
|
||||||
|
<TopNavigation title="打卡时间限制"></TopNavigation>
|
||||||
|
<view class="bg-[#E2EAFA] px-3 py-2 color-[#3372FA] text-3.3">
|
||||||
|
可设置每次上下班是否需要打卡、允许打卡的时间范围
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y class="flex-1">
|
||||||
|
<view class="" v-for="(item, index) in times" :key="index">
|
||||||
|
<view class="color-gray text-3.3 p-3">上班时间段{{ index + 1 }}</view>
|
||||||
|
<view class="bg-white" v-for="(t, i) in item.times" :key="i">
|
||||||
|
<CommonItem :text="'上班' + t" :isNext="false" hint="" noLine>
|
||||||
|
<template v-slot:child>
|
||||||
|
<wd-switch v-model="item.switch[i]" class="ml-a" />
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
<view class="flex flex-row flex-justify-between mx-4">
|
||||||
|
<view class="bg-[#f6f8fc] rounded-2 p-2 w-48% box-border">
|
||||||
|
<view class="text-2.8 color-gray">最早打卡时间</view>
|
||||||
|
<view class="flex flex-row items-center mt-1.5">
|
||||||
|
<view class="color-[#3372FA] text-3">未设置</view>
|
||||||
|
<view class="i-carbon-next-outline ml-1 text-2.3 color-gray"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg-[#f6f8fc] rounded-2 p-2 w-48% box-border">
|
||||||
|
<view class="text-2.8 color-gray">最早打卡时间</view>
|
||||||
|
<view class="flex flex-row items-center mt-1.5">
|
||||||
|
<view class="color-[#3372FA] text-3">未设置</view>
|
||||||
|
<view class="i-carbon-next-outline ml-1 text-2.3 color-gray"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
:class="i != item.times.length - 1 ? '' : 'invisible'"
|
||||||
|
class="hpx mx-4 mt-3 bg-gray-200"
|
||||||
|
></view>
|
||||||
|
</view>
|
||||||
|
<!-- <view v-if="index == times.length - 1">若未设置,</view>s -->
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="mt-a w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200">
|
||||||
|
<wd-button :round="false" block>保存</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||||
|
|
||||||
|
const times = ref([
|
||||||
|
{
|
||||||
|
times: ['07:00', '09:00'],
|
||||||
|
switch: [true, false]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
times: ['07:00', '09:00'],
|
||||||
|
switch: [true, false]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
//
|
||||||
|
</style>
|
||||||
@ -0,0 +1,227 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<BottomPop
|
||||||
|
:show="showType"
|
||||||
|
title="考勤类型"
|
||||||
|
:onclose="
|
||||||
|
() => {
|
||||||
|
showType = false
|
||||||
|
typeIndex = typeSelectIndex
|
||||||
|
}
|
||||||
|
"
|
||||||
|
:onSure="
|
||||||
|
() => {
|
||||||
|
typeSelectIndex = typeIndex
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template v-slot:child>
|
||||||
|
<view class="px-4">
|
||||||
|
<view
|
||||||
|
class="bg-white rounded-2 mt-2"
|
||||||
|
@click="typeIndex = index"
|
||||||
|
v-for="(item, index) in typeList"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view class="flex flex-row items-center p-3 box-border">
|
||||||
|
<view class="flex flex-1 flex-col flex-justify-items-start">
|
||||||
|
<view class="">{{ item.title }}</view>
|
||||||
|
<view class="mt-1 text-3.3">{{ item.desc }}</view>
|
||||||
|
<view class="mt-1 text-2.8 color-gray">{{ item.desc2 }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-show="typeIndex == index">
|
||||||
|
<wd-icon name="check" class="color-[#3372FA] mr-2"></wd-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</BottomPop>
|
||||||
|
|
||||||
|
<BottomPop
|
||||||
|
:show="showWay"
|
||||||
|
title="打卡方式选择"
|
||||||
|
:onclose="
|
||||||
|
() => {
|
||||||
|
showWay = false
|
||||||
|
}
|
||||||
|
"
|
||||||
|
noSure
|
||||||
|
>
|
||||||
|
<template v-slot:child>
|
||||||
|
<view class="px-4">
|
||||||
|
<view class="bg-white rounded-2 mt-2">
|
||||||
|
<view
|
||||||
|
class="flex flex-row items-center p-3 box-border"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
wayIndex = index
|
||||||
|
showWay = false
|
||||||
|
}
|
||||||
|
"
|
||||||
|
v-for="(item, index) in wayList"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view class="flex flex-1 flex-col flex-justify-items-start">
|
||||||
|
<view class="">{{ item.title }}</view>
|
||||||
|
<view class="mt-1 text-2.8 color-gray">{{ item.desc }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-show="wayIndex == index">
|
||||||
|
<wd-icon name="check" class="color-[#3372FA] mr-2"></wd-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</BottomPop>
|
||||||
|
|
||||||
|
<TopNavigation title="添加考勤组"></TopNavigation>
|
||||||
|
<view class="h-[calc(100vh-60px)] p-3 box-border">
|
||||||
|
<view class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem text="考勤组名称" isMust :isNext="false" value="" hint="" noLine></CommonItem>
|
||||||
|
<view class="flex items-center px-4.3 pb-3 box-border">
|
||||||
|
<input
|
||||||
|
class="w-100%"
|
||||||
|
v-model="name"
|
||||||
|
placeholder="必填"
|
||||||
|
placeholder-class="color-gray"
|
||||||
|
:maxlength="15"
|
||||||
|
@input="nameInput"
|
||||||
|
/>
|
||||||
|
<view
|
||||||
|
@click="name = ''"
|
||||||
|
v-show="name"
|
||||||
|
class="i-carbon-close-filled color-gray text-4"
|
||||||
|
></view>
|
||||||
|
<view class="text-3 self-center color-gray ml-1">{{ name.length }}/{{ 15 }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="hpx bg-gray-100 mx-2.5"></view>
|
||||||
|
<CommonItem
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
showType = true
|
||||||
|
}
|
||||||
|
"
|
||||||
|
text="考勤类型"
|
||||||
|
noLine
|
||||||
|
:value="typeList[typeSelectIndex].title"
|
||||||
|
></CommonItem>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem @click="goStaff()" text="考勤人员" isMust value=""></CommonItem>
|
||||||
|
<CommonItem
|
||||||
|
@click="goTime()"
|
||||||
|
text="考勤时间"
|
||||||
|
noLine
|
||||||
|
value="周一至周五,09:00-17:00"
|
||||||
|
></CommonItem>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
showWay = true
|
||||||
|
}
|
||||||
|
"
|
||||||
|
text="打卡方式"
|
||||||
|
:value="wayList[wayIndex].title"
|
||||||
|
></CommonItem>
|
||||||
|
<CommonItem
|
||||||
|
text="打卡设备"
|
||||||
|
:isMust="wayIndex == 0"
|
||||||
|
:noLine="wayIndex == 0"
|
||||||
|
value=""
|
||||||
|
hint="未选择"
|
||||||
|
></CommonItem>
|
||||||
|
<CommonItem text="打卡地点" v-show="wayIndex == 1" value="" hint="未设置"></CommonItem>
|
||||||
|
<CommonItem text="打卡WIFI" v-show="wayIndex == 1" noLine value="" hint="未设置"></CommonItem>
|
||||||
|
</view>
|
||||||
|
<view @click="goOutsideRule()" v-show="wayIndex == 1" class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem text="外勤规则" noLine value="允许外勤卡" hint=""></CommonItem>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem text="加班统计规则" noLine value="未开启" hint=""></CommonItem>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="fixed bottom-0 left-0 w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||||
|
>
|
||||||
|
<wd-button :round="false" block>保存</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import BottomPop from '@/components/BottomPop/BottomPop.vue'
|
||||||
|
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||||
|
const showType = ref(true)
|
||||||
|
const typeIndex = ref(0)
|
||||||
|
const typeSelectIndex = ref(0)
|
||||||
|
const showWay = ref(false)
|
||||||
|
const wayIndex = ref(0)
|
||||||
|
const name = ref('')
|
||||||
|
const nameInput = () => {
|
||||||
|
console.log(name.value)
|
||||||
|
}
|
||||||
|
const typeList = [
|
||||||
|
{
|
||||||
|
title: '固定班制',
|
||||||
|
desc: '人员每周按照相同时间上下班',
|
||||||
|
desc2: '适用于办公室坐班,例如每周一至五上班,朝9晚5'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '自由班制',
|
||||||
|
desc: '无固定上下班时间,可随时打卡',
|
||||||
|
desc2: '适用于计时工种、灵活用工等'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '排班制',
|
||||||
|
desc: '排班制人员按每日所排班次上下班',
|
||||||
|
desc2: '适用于工厂、门店等,例如三班倒、做—休一'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const wayList = [
|
||||||
|
{
|
||||||
|
title: '设备打卡',
|
||||||
|
desc: '适用于内勤打卡,有效避免打卡等作弊行为'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '设备+手机打卡',
|
||||||
|
desc: '选择后可开启外勤打卡'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const outsideRule = {
|
||||||
|
allow: false,
|
||||||
|
takePhoto: false,
|
||||||
|
remark: false,
|
||||||
|
selectPhoto: false
|
||||||
|
}
|
||||||
|
const goOutsideRule = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/attendance-add-group/outside-rules'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const goStaff = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/attendance-add-group/attendance-staff'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const goTime = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/attendance-add-group/attendance-time'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
page {
|
||||||
|
background-color: #f6f8fc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<TopNavigation title="考勤人员"></TopNavigation>
|
||||||
|
<view class="h-[calc(100vh-60px)] p-3 box-border">
|
||||||
|
<view class="bg-white flex flex flex-row flex-justify-center items-center rounded-2 py-1.5">
|
||||||
|
<wd-icon name="search" class="color-gray text-3.3 ml-2"></wd-icon>
|
||||||
|
<view class="color-gray ml-2">搜索</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
page {
|
||||||
|
background-color: #f6f8fc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
172
src/pages/attendance/attendance-add-group/attendance-time.vue
Normal file
172
src/pages/attendance/attendance-add-group/attendance-time.vue
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<BottomPop
|
||||||
|
:show="showHoliday"
|
||||||
|
title="请选择"
|
||||||
|
:onclose="
|
||||||
|
() => {
|
||||||
|
showHoliday = false
|
||||||
|
}
|
||||||
|
"
|
||||||
|
noSure
|
||||||
|
>
|
||||||
|
<template v-slot:child>
|
||||||
|
<view class="px-4">
|
||||||
|
<view class="bg-white rounded-2 mt-2">
|
||||||
|
<view
|
||||||
|
class="flex flex-row items-center p-3 box-border"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
holidayIndex = index
|
||||||
|
showHoliday = false
|
||||||
|
}
|
||||||
|
"
|
||||||
|
v-for="(item, index) in holidayList"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view class="flex flex-1 flex-col flex-justify-items-start">
|
||||||
|
<view class="">{{ item.title }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-show="holidayIndex == index">
|
||||||
|
<wd-icon name="check" class="color-[#3372FA] mr-2"></wd-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</BottomPop>
|
||||||
|
<view class="h-100vh flex flex-col">
|
||||||
|
<TopNavigation title="考勤时间"></TopNavigation>
|
||||||
|
<scroll-view scroll-y class="px-4 box-border flex-1">
|
||||||
|
<view v-for="(item, index) in rules" :key="index">
|
||||||
|
<view class="flex flex-justify-between items-center mx-3.5 pb-2 pt-5">
|
||||||
|
<view class="color-gray text-3">规则{{ index + 1 }}</view>
|
||||||
|
<view @click="rules.splice(index, 1)" v-show="rules.length > 1" class="text-3 color-red">
|
||||||
|
删除
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2 p-3.5">
|
||||||
|
<view class="must mb-2">周时间选择</view>
|
||||||
|
<view class="flex flex-row flex-justify-between">
|
||||||
|
<view
|
||||||
|
@click="checkOtherRule(t, i)"
|
||||||
|
:class="t.isSelect ? selectCss : noSelectCss"
|
||||||
|
v-for="(t, i) in item.dayList"
|
||||||
|
:key="i"
|
||||||
|
>
|
||||||
|
{{ t.name }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="hpx bg-gray-100 my-3"></view>
|
||||||
|
<view class="flex" @click="goSelectClasses">
|
||||||
|
<view class="must flex-1">上下班时间</view>
|
||||||
|
<view class="color-gray">{{ item.title }} {{ item.time }}</view>
|
||||||
|
<wd-icon name="arrow-right ml-1.5 mr-0.5" class="text-gray" size="20"></wd-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
v-show="rules.length < 7"
|
||||||
|
@click="rules.push({ dayList: cloneDayList(), title: '', time: '' })"
|
||||||
|
class="flex flex-justify-center items-center flex-row py-3 box-border bg-white rounded-2 mt-2"
|
||||||
|
>
|
||||||
|
<wd-icon name="add-circle mr-2" class="color-[#3372FA]" size="17"></wd-icon>
|
||||||
|
<view class="color-[#3372FA]">添加规则</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-justify-between items-center mx-3.5 pb-2 pt-5 color-gray text-3">
|
||||||
|
特殊规则
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2">
|
||||||
|
<CommonItem text="节假日自动排休" value="" hint="" :isNext="false">
|
||||||
|
<template v-slot:child>
|
||||||
|
<wd-switch v-model="isAutoRest" class="ml-a"></wd-switch>
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
<CommonItem
|
||||||
|
v-show="isAutoRest"
|
||||||
|
@click="showHoliday = true"
|
||||||
|
text="节假日计划"
|
||||||
|
value="按中国大陆法定节假日"
|
||||||
|
hint=""
|
||||||
|
></CommonItem>
|
||||||
|
<CommonItem @click="goSpecial" text="特殊日期" value="已设置" hint="" noLine></CommonItem>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="mt-a w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200">
|
||||||
|
<wd-button :round="false" block>保存</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||||
|
|
||||||
|
const baseCss = 'rounded-100 w-8 h-8 flex items-center justify-center font-bold text-3 border'
|
||||||
|
const selectCss = `${baseCss} bg-[#3372FA] color-white border-[#3372FA] border-solid`
|
||||||
|
const noSelectCss = `${baseCss} border-gray border-dashed`
|
||||||
|
const isAutoRest = ref(false)
|
||||||
|
const showHoliday = ref(false)
|
||||||
|
const holidayIndex = ref(0)
|
||||||
|
const holidayList = [{ title: '按中国大陆法定节假日' }]
|
||||||
|
const dayList = [
|
||||||
|
{ name: '一', value: 1, isSelect: false },
|
||||||
|
{ name: '二', value: 2, isSelect: false },
|
||||||
|
{ name: '三', value: 3, isSelect: false },
|
||||||
|
{ name: '四', value: 4, isSelect: false },
|
||||||
|
{ name: '五', value: 5, isSelect: false },
|
||||||
|
{ name: '六', value: 6, isSelect: false },
|
||||||
|
{ name: '日', value: 7, isSelect: false }
|
||||||
|
]
|
||||||
|
const cloneDayList = () => {
|
||||||
|
return dayList.map(day => ({ ...day }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = ref([
|
||||||
|
{
|
||||||
|
dayList: cloneDayList(),
|
||||||
|
title: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
const checkOtherRule = (t, i) => {
|
||||||
|
if (!t.isSelect) {
|
||||||
|
rules.value.forEach(item => {
|
||||||
|
item.dayList[i].isSelect = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
t.isSelect = !t.isSelect
|
||||||
|
}
|
||||||
|
const goSelectClasses = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/classes-manage?isSelect=true'
|
||||||
|
})
|
||||||
|
// goSelectClass
|
||||||
|
}
|
||||||
|
const goSpecial = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/attendance-add-group/special-date-set'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.must {
|
||||||
|
position: relative;
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
left: -1em;
|
||||||
|
color: red;
|
||||||
|
content: '*';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
</style>
|
||||||
61
src/pages/attendance/attendance-add-group/outside-rules.vue
Normal file
61
src/pages/attendance/attendance-add-group/outside-rules.vue
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<TopNavigation title="外勤规则"></TopNavigation>
|
||||||
|
<view class="h-[calc(100vh-60px)] p-3 box-border">
|
||||||
|
<view class="bg-white rounded-2.2">
|
||||||
|
<CommonItem text="允许外勤打卡" noLine value="">
|
||||||
|
<template v-slot:child>
|
||||||
|
<wd-switch v-model="outsideRules.allow" class="ml-a" />
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
</view>
|
||||||
|
<view v-show="outsideRules.allow" class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem text="外勤打卡必须拍照" value="">
|
||||||
|
<template v-slot:child>
|
||||||
|
<wd-switch v-model="outsideRules.takePhoto" class="ml-a" />
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
<CommonItem text="外勤卡必须填写备注" value="">
|
||||||
|
<template v-slot:child>
|
||||||
|
<wd-switch v-model="outsideRules.remark" class="ml-a" />
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
<CommonItem text="允许从手机相册选择照片" noLine value="">
|
||||||
|
<template v-slot:child>
|
||||||
|
<wd-switch v-model="outsideRules.selectPhoto" class="ml-a" />
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="fixed bottom-0 left-0 w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||||
|
>
|
||||||
|
<wd-button :round="false" block>保存</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||||
|
import { OutsideRules } from '@/typings'
|
||||||
|
const checked = ref(false)
|
||||||
|
const outsideRules = ref<OutsideRules>({
|
||||||
|
allow: false,
|
||||||
|
takePhoto: false,
|
||||||
|
remark: false,
|
||||||
|
selectPhoto: false
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
page {
|
||||||
|
background-color: #f6f8fc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="h-100vh flex flex-col">
|
||||||
|
<TopNavigation title="特殊日期"></TopNavigation>
|
||||||
|
<wd-tabs v-model="tabsIndex">
|
||||||
|
<block v-for="item in tabs" :key="item">
|
||||||
|
<wd-tab :title="item.title"></wd-tab>
|
||||||
|
</block>
|
||||||
|
</wd-tabs>
|
||||||
|
<view class="flex-1 flex flex-col p-3">
|
||||||
|
<scroll-view scroll-y class="flex-1 box-border">
|
||||||
|
<view class="bg-white rounded-2">
|
||||||
|
<CommonItem
|
||||||
|
text="添加"
|
||||||
|
@click="
|
||||||
|
tabsIndex == 0 ? mustDate.push(cloneBestDate()) : unMustDate.push(cloneBestDate())
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template v-slot:child>
|
||||||
|
<wd-icon name="add-circle" class="ml-a" size="18"></wd-icon>
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="mt-5"
|
||||||
|
v-for="(item, index) in tabsIndex == 0 ? mustDate : unMustDate"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view class="flex flex-justify-between px-3 mb-2">
|
||||||
|
<view class="color-gray text-3">{{ tabs[tabsIndex].title }}({{ index + 1 }})</view>
|
||||||
|
<view
|
||||||
|
@click="tabsIndex == 0 ? mustDate.splice(index, 1) : unMustDate.splice(index, 1)"
|
||||||
|
class="color-red text-3"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2">
|
||||||
|
<CommonItem text="日期" :value="item.data" :noLine="tabsIndex != 0"></CommonItem>
|
||||||
|
<CommonItem
|
||||||
|
v-show="tabsIndex == 0"
|
||||||
|
text="上下班时间"
|
||||||
|
:value="item.time"
|
||||||
|
noLine
|
||||||
|
></CommonItem>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
<view class="mt-a w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200">
|
||||||
|
<wd-button :round="false" block>确定</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||||
|
|
||||||
|
const tabsIndex = ref(0)
|
||||||
|
const mustDate = ref([])
|
||||||
|
const unMustDate = ref([])
|
||||||
|
const bestDate = [
|
||||||
|
{
|
||||||
|
date: '',
|
||||||
|
time: ''
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const cloneBestDate = () => {
|
||||||
|
return bestDate.map(t => ({ ...t }))
|
||||||
|
}
|
||||||
|
const tabs = ref([
|
||||||
|
{
|
||||||
|
title: '必须打卡的日期'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '不用打卡的日期'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
//
|
||||||
|
</style>
|
||||||
42
src/pages/attendance/attendance-rules.vue
Normal file
42
src/pages/attendance/attendance-rules.vue
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="h-100vh flex flex-col">
|
||||||
|
<TopNavigation title="考勤规则"></TopNavigation>
|
||||||
|
<view class="px-4 pt-5 text-3">
|
||||||
|
<view class="color-gray text-3 ml-3.5 mb-2">考勤</view>
|
||||||
|
<view class="bg-white rounded-2 p-3.5">
|
||||||
|
<view class="font-bold text-3.5">今日考勤时间</view>
|
||||||
|
<view class="mt-3">上班时间不固定,可自由打卡</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2 p-3.5 mt-2">
|
||||||
|
<view class="font-bold text-3.5">打卡方式</view>
|
||||||
|
<view class="mt-3">在设备上打卡</view>
|
||||||
|
<view class="mt-2">手机定位打卡</view>
|
||||||
|
<view class="inline-flex flex-row items-center bg-gray-100 rounded-2 mt-1.5 p-1.5">
|
||||||
|
<view class="i-carbon-location-filled color-[#3372FA]"></view>
|
||||||
|
<view class="ml-0.5 text-3">宏发科技园H1栋</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2 p-3.5 mt-2">
|
||||||
|
<view class="font-bold text-3.5">其他</view>
|
||||||
|
<view class="mt-3">允许外勤打卡</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
//
|
||||||
|
</style>
|
||||||
53
src/pages/attendance/attendance.vue
Normal file
53
src/pages/attendance/attendance.vue
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="h-[calc(100vh-50px)] flex flex-col">
|
||||||
|
<TopNavigation :title="titleTab[curIndex]"></TopNavigation>
|
||||||
|
<scroll-view class="flex-1 box-border" scroll-y>
|
||||||
|
<view v-for="(item, index) in pages" :key="index" v-show="curIndex == index">
|
||||||
|
<component :is="item"></component>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
<CustomTabBar :list="list" :default-index="0" @change="change"></CustomTabBar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import AttendanceClockIn from './AttendanceClockIn.vue'
|
||||||
|
import AttendanceStatistics from './AttendanceStatistics.vue'
|
||||||
|
import AttendanceSet from './AttendanceSet.vue'
|
||||||
|
import { TabBarItem } from '@/typings'
|
||||||
|
const pages = [AttendanceClockIn, AttendanceStatistics, AttendanceSet]
|
||||||
|
const titleTab = ['考勤打卡', '考勤统计', '设置']
|
||||||
|
const list = ref<Array<TabBarItem>>([
|
||||||
|
{
|
||||||
|
title: '打卡',
|
||||||
|
icon: 'home'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '统计',
|
||||||
|
icon: 'notification'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '设置',
|
||||||
|
icon: 'setting'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
const curIndex = ref(0)
|
||||||
|
const change = (data: { value: number }) => {
|
||||||
|
curIndex.value = data.value
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
page {
|
||||||
|
background-color: #f6f8fc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
128
src/pages/attendance/classes-add-edit.vue
Normal file
128
src/pages/attendance/classes-add-edit.vue
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="h-100vh flex flex-col">
|
||||||
|
<TopNavigation title="新增班次"></TopNavigation>
|
||||||
|
<view class="flex-1 p-3 box-border">
|
||||||
|
<view class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem text="班次名称" isMust :isNext="false" value="" hint="" noLine></CommonItem>
|
||||||
|
<view class="flex items-center px-4.3 pb-3 box-border">
|
||||||
|
<input
|
||||||
|
class="w-100%"
|
||||||
|
v-model="name"
|
||||||
|
placeholder="必填"
|
||||||
|
placeholder-class="color-gray"
|
||||||
|
:maxlength="8"
|
||||||
|
/>
|
||||||
|
<view
|
||||||
|
@click="name = ''"
|
||||||
|
v-show="name"
|
||||||
|
class="i-carbon-close-filled color-gray text-4"
|
||||||
|
></view>
|
||||||
|
<view class="text-3 self-center color-gray ml-1">{{ name.length }}/{{ 8 }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-for="(item, index) in times" :key="index">
|
||||||
|
<view class="flex items-center my-3 flex-justify-between text-3">
|
||||||
|
<view class="color-gray ml-4.2">上下班时段{{ index + 1 }}</view>
|
||||||
|
<view v-show="times.length > 1" @click="times.splice(index, 1)" class="color-red mr-4">
|
||||||
|
删除
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem text="上班" value="09:00"></CommonItem>
|
||||||
|
<CommonItem text="下班" value="17:00"></CommonItem>
|
||||||
|
<view
|
||||||
|
@click="times.push({ start: '09:00', end: '17:00' })"
|
||||||
|
v-show="index == times.length - 1 && times.length < 3"
|
||||||
|
class="flex flex-justify-center items-center flex-row py-4 box-border"
|
||||||
|
>
|
||||||
|
<wd-icon name="add-circle mr-2" class="color-[#3372FA]" size="17"></wd-icon>
|
||||||
|
<view class="color-[#3372FA]">添加时段</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem @click="goAllowedTime" text="允许打卡时间" value="" hint=""></CommonItem>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem @click="goFlexblePunching" text="弹性打卡" value="" hint="不设置"></CommonItem>
|
||||||
|
</view>
|
||||||
|
<view v-show="times.length == 1" class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem value="" :noLine="haveRest ? false : true">
|
||||||
|
<template v-slot:leftChild>
|
||||||
|
<view>
|
||||||
|
<view>休息时间</view>
|
||||||
|
<view class="color-gray mt-1">中途休息时间不计入出勤时长</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-slot:child>
|
||||||
|
<wd-switch v-model="haveRest" class="ml-a" />
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
<CommonItem v-show="haveRest" text="休息开始时间" value="12:00"></CommonItem>
|
||||||
|
<CommonItem v-show="haveRest" text="休息结束时间" value="13:00"></CommonItem>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
v-if="!isEdit"
|
||||||
|
class="fixed bottom-0 left-0 w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||||
|
>
|
||||||
|
<wd-button :round="false" block>保存</wd-button>
|
||||||
|
</view>
|
||||||
|
<view v-else class="flex flex-row flex-justify-between p-4">
|
||||||
|
<view class="flex-1 mr-2">
|
||||||
|
<wd-button
|
||||||
|
size="large"
|
||||||
|
custom-style="background:#E9EBEF;color:#3372FA"
|
||||||
|
:round="false"
|
||||||
|
block
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</wd-button>
|
||||||
|
</view>
|
||||||
|
<view class="flex-1 ml-2">
|
||||||
|
<wd-button size="large" :round="false" block>保存</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||||
|
onLoad(options => {
|
||||||
|
isEdit.value = options.isEdit ?? false
|
||||||
|
})
|
||||||
|
const isEdit = ref(false)
|
||||||
|
const name = ref('')
|
||||||
|
const haveRest = ref(false)
|
||||||
|
const times = ref([
|
||||||
|
{
|
||||||
|
start: '09:00',
|
||||||
|
end: '17:00'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const goFlexblePunching = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/flexible-punching'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const goAllowedTime = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/allowed-time'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
//
|
||||||
|
</style>
|
||||||
159
src/pages/attendance/classes-manage.vue
Normal file
159
src/pages/attendance/classes-manage.vue
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="h-100vh flex flex-col">
|
||||||
|
<TopNavigation title="班次管理"></TopNavigation>
|
||||||
|
<view class="flex items-center bg-gray-200 p-2 mx-3 rounded">
|
||||||
|
<wd-icon name="search" class="text-gray mr-2"></wd-icon>
|
||||||
|
<input
|
||||||
|
v-model="key"
|
||||||
|
type="text"
|
||||||
|
placeholder="搜索班次名称"
|
||||||
|
placeholder-class="text-gray"
|
||||||
|
class="w-100%"
|
||||||
|
/>
|
||||||
|
<view v-show="key" class="i-carbon-close-filled color-gray text-4"></view>
|
||||||
|
</view>
|
||||||
|
<view @click="goClassesAddOrEdit(false)" class="bg-white rounded-2.2 mt-2 mx-3">
|
||||||
|
<CommonItem text="添加班次" noLine value="">
|
||||||
|
<template v-slot:child>
|
||||||
|
<wd-icon name="add-circle" class="ml-a" size="20"></wd-icon>
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
</view>
|
||||||
|
<scroll-view
|
||||||
|
ref="scrollView"
|
||||||
|
scroll-y
|
||||||
|
class="mt-2 flex-1 px-3 box-border"
|
||||||
|
refresher-enabled
|
||||||
|
:refresher-threshold="45"
|
||||||
|
@refresherrefresh="onRefresh()"
|
||||||
|
:refresher-triggered="scrollViewStatus"
|
||||||
|
>
|
||||||
|
<view class="bg-white rounded-2.2">
|
||||||
|
<CommonItem
|
||||||
|
@click="selectIndex = index"
|
||||||
|
v-for="(item, index) in classList"
|
||||||
|
:key="index"
|
||||||
|
value=""
|
||||||
|
>
|
||||||
|
<template v-slot:leftChild>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view
|
||||||
|
v-if="isSelect"
|
||||||
|
:class="
|
||||||
|
selectIndex == index
|
||||||
|
? 'i-carbon-checkmark-filled color-[#3372FA]'
|
||||||
|
: 'i-carbon-circle-outline color-gray'
|
||||||
|
"
|
||||||
|
class="text-5 mr-3"
|
||||||
|
></view>
|
||||||
|
<view>
|
||||||
|
<view>{{ item.name }}</view>
|
||||||
|
<view class="color-gray mt-1">{{ item.time }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-slot:child>
|
||||||
|
<view
|
||||||
|
@click="goClassesAddOrEdit(true)"
|
||||||
|
class="ml-a i-bytesize-compose color-gray"
|
||||||
|
></view>
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
</view>
|
||||||
|
<view class="ml-3 mt-1 text-3 color-gray">添加班次后,请至考勤组中选择和使用</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view
|
||||||
|
v-if="isSelect"
|
||||||
|
class="mt-a w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||||
|
>
|
||||||
|
<wd-button :round="false" block>确定</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||||
|
const selectIndex = ref(-1)
|
||||||
|
const isSelect = ref(false)
|
||||||
|
const scrollViewStatus = ref(true)
|
||||||
|
const key = ref('')
|
||||||
|
const onRefresh = () => {
|
||||||
|
console.log('refresh')
|
||||||
|
setTimeout(() => {
|
||||||
|
scrollViewStatus.value = true
|
||||||
|
scrollViewStatus.value = false
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
onLoad(options => {
|
||||||
|
isSelect.value = options.isSelect ?? false
|
||||||
|
})
|
||||||
|
const goClassesAddOrEdit = (isEdit: boolean) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/classes-add-edit?isEdit=' + isEdit
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const classList = ref([
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '默认班次',
|
||||||
|
time: '09:00-17:00'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
page {
|
||||||
|
background-color: #f6f8fc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
80
src/pages/attendance/flexible-punching.vue
Normal file
80
src/pages/attendance/flexible-punching.vue
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<TopNavigation title="弹性打卡"></TopNavigation>
|
||||||
|
<view class="bg-white rounded-2.2 mt-2">
|
||||||
|
<CommonItem
|
||||||
|
@click="selectIndex = index"
|
||||||
|
v-for="(item, index) in setList"
|
||||||
|
:key="index"
|
||||||
|
:text="item.title"
|
||||||
|
value=""
|
||||||
|
hint=""
|
||||||
|
:isNext="false"
|
||||||
|
>
|
||||||
|
<template v-slot:child>
|
||||||
|
<view class="ml-a px-3 rounded-3 bg-[#F6F7FB] text-center">
|
||||||
|
<wd-icon
|
||||||
|
name="check"
|
||||||
|
class="color-[#3372FA]"
|
||||||
|
:class="selectIndex == index ? '' : 'invisible'"
|
||||||
|
></wd-icon>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
</view>
|
||||||
|
<view class="bg-white rounded-2.2 mt-1.5">
|
||||||
|
<CommonItem v-show="selectIndex == 1" text="" value="10分钟" hint="">
|
||||||
|
<template v-slot:leftChild>
|
||||||
|
<view>
|
||||||
|
<view>上班最多可晚到</view>
|
||||||
|
<view class="color-gray mt-1 text-3">晚到10分钟内不算迟到</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
<CommonItem v-show="selectIndex == 1" text="" value="10分钟" hint="">
|
||||||
|
<template v-slot:leftChild>
|
||||||
|
<view>
|
||||||
|
<view>上班最多可早走</view>
|
||||||
|
<view class="color-gray mt-1 text-3">早走10分钟内不算迟到</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</CommonItem>
|
||||||
|
<CommonItem v-show="selectIndex == 2" text="最多晚到晚走" value="10分钟" hint=""></CommonItem>
|
||||||
|
<CommonItem v-show="selectIndex == 2" text="最多早到早走" value="10分钟" hint=""></CommonItem>
|
||||||
|
<view
|
||||||
|
class="fixed bottom-0 left-0 w-full p-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||||
|
>
|
||||||
|
<wd-button :round="false" block>确定</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import CommonItem from '@/components/CommonItemItem/CommonItem.vue'
|
||||||
|
const setList = [
|
||||||
|
{
|
||||||
|
title: '不设置',
|
||||||
|
isSelect: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '晚到、早走几分钟不记为异常',
|
||||||
|
isSelect: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '允许晚到晚走、早到早走',
|
||||||
|
isSelect: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const selectIndex = ref(-1)
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
152
src/pages/attendance/issue-record-detail.vue
Normal file
152
src/pages/attendance/issue-record-detail.vue
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="h-100vh flex flex-col">
|
||||||
|
<TopNavigation title="下发记录详情"></TopNavigation>
|
||||||
|
<wd-tabs v-model="tabsIndex">
|
||||||
|
<block v-for="item in tabs" :key="item">
|
||||||
|
<wd-tab :title="`${item.title}(${item.num})`"></wd-tab>
|
||||||
|
</block>
|
||||||
|
</wd-tabs>
|
||||||
|
|
||||||
|
<view v-show="tabsIndex == 0" class="flex overflow-x-auto whitespace-nowrap mt-4">
|
||||||
|
<view
|
||||||
|
@click="tagIndex = index"
|
||||||
|
v-for="(item, index) in tagList"
|
||||||
|
:key="index"
|
||||||
|
:class="tagIndex === index ? 'color-[#3372FA]' : ''"
|
||||||
|
class="bg-white px-3 py-1.5 rounded-20 color-gray text-3 ml-3"
|
||||||
|
>
|
||||||
|
{{ item.name }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y class="flex-1 p-3 box-border">
|
||||||
|
<view v-for="(item, index) in detailList" :key="index" class="bg-white rounded-2 p-3 mb-2">
|
||||||
|
<view class="flex flex-row flex-justify-between">
|
||||||
|
<view>
|
||||||
|
<view>{{ item.name }}</view>
|
||||||
|
<view class="text-3 color-gray">{{ item.organization }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="text-2.5 color-gray">{{ item.time }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="hpx bg-gray-100 my-3"></view>
|
||||||
|
<view class="flex flex-row items-center mt-1.5">
|
||||||
|
<view class="i-carbon-virtual-machine text-3 color-gray"></view>
|
||||||
|
<view class="w-15 ml-2.5 color-gray text-3">考勤机:</view>
|
||||||
|
<view class="text-3">{{ item.machine }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-row items-center mt-1.5">
|
||||||
|
<view class="i-carbon-virtual-machine text-3 color-gray"></view>
|
||||||
|
<view class="w-15 ml-2.5 color-gray text-3">通行凭证:</view>
|
||||||
|
<view class="text-3">{{ item.certificate }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-row items-center mt-1.5">
|
||||||
|
<view class="i-carbon-virtual-machine text-3 color-gray"></view>
|
||||||
|
<view class="w-15 ml-2.5 color-gray text-3">权限操作:</view>
|
||||||
|
<view class="text-3">{{ item.operation }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="tabsIndex == 0" class="flex flex-row items-center mt-1.5">
|
||||||
|
<view class="i-carbon-virtual-machine text-3 color-gray"></view>
|
||||||
|
<view class="w-15 ml-2.5 color-gray text-3">失败原因:</view>
|
||||||
|
<view class="text-3 color-red">{{ item.fail }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const tagList = [
|
||||||
|
{
|
||||||
|
name: '全部'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '人脸不符合要求'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '设备离线'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '设备未响应'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '其他'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const detailList = [
|
||||||
|
{
|
||||||
|
time: '2025-01-07 14:32:19',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
name: 'HikMall_321312312',
|
||||||
|
organization: '192312312的互联',
|
||||||
|
machine: 'DS-K(L40231232)',
|
||||||
|
certificate: '指纹1',
|
||||||
|
operation: '下发权限',
|
||||||
|
fail: '设备离线,请稍后再试'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2025-01-07 14:32:19',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
name: 'HikMall_321312312',
|
||||||
|
organization: '192312312的互联',
|
||||||
|
machine: 'DS-K(L40231232)',
|
||||||
|
certificate: '指纹1',
|
||||||
|
operation: '下发权限',
|
||||||
|
fail: '设备离线,请稍后再试'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2025-01-07 14:32:19',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
name: 'HikMall_321312312',
|
||||||
|
organization: '192312312的互联',
|
||||||
|
machine: 'DS-K(L40231232)',
|
||||||
|
certificate: '指纹1',
|
||||||
|
operation: '下发权限',
|
||||||
|
fail: '设备离线,请稍后再试'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2025-01-07 14:32:19',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
name: 'HikMall_321312312',
|
||||||
|
organization: '192312312的互联',
|
||||||
|
machine: 'DS-K(L40231232)',
|
||||||
|
certificate: '指纹1',
|
||||||
|
operation: '下发权限',
|
||||||
|
fail: '设备离线,请稍后再试'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2025-01-07 14:32:19',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
name: 'HikMall_321312312',
|
||||||
|
organization: '192312312的互联',
|
||||||
|
machine: 'DS-K(L40231232)',
|
||||||
|
certificate: '指纹1',
|
||||||
|
operation: '下发权限',
|
||||||
|
fail: '设备离线,请稍后再试'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const tabs = [
|
||||||
|
{
|
||||||
|
title: '成功',
|
||||||
|
num: detailList.length
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '失败',
|
||||||
|
num: detailList.length
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const tagIndex = ref(0)
|
||||||
|
const tabsIndex = ref(0)
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
//
|
||||||
|
</style>
|
||||||
126
src/pages/attendance/issue-record.vue
Normal file
126
src/pages/attendance/issue-record.vue
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
layout: 'default',
|
||||||
|
style: {
|
||||||
|
navigationStyle: 'custom'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="h-100vh flex flex-col">
|
||||||
|
<TopNavigation title="下发记录"></TopNavigation>
|
||||||
|
<view class="bg-orange-100 p-2 color-orange text-3.3">
|
||||||
|
此处仅展示考勤组中打卡设备的下发记录
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y class="flex-1 p-3.5 box-border">
|
||||||
|
<view
|
||||||
|
@click="goDetail"
|
||||||
|
v-for="(item, index) in recordList"
|
||||||
|
:key="index"
|
||||||
|
class="bg-white rounded-2 p-3 mb-2"
|
||||||
|
>
|
||||||
|
<view class="flex flex-row flex-justify-between items-center">
|
||||||
|
<view class="flex flex-col">
|
||||||
|
<view>{{ item.dec }}</view>
|
||||||
|
<view class="color-gray mt-1.5">{{ item.time }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-row items-center">
|
||||||
|
<view class="color-[#3372FA]">{{ item.status }}</view>
|
||||||
|
<view class="i-carbon-chevron-right ml-2 text-2.5"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="hpx bg-gray-100 my-3"></view>
|
||||||
|
<view class="flex flex-row flex-justify-around">
|
||||||
|
<view class="flex flex-col items-center">
|
||||||
|
<view class="font-bold text-5">{{ item.success }}</view>
|
||||||
|
<view class="text-3">成功</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-col items-center">
|
||||||
|
<view class="font-bold text-5">{{ item.fail }}</view>
|
||||||
|
<view class="text-3">失败</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex flex-col items-center">
|
||||||
|
<view class="font-bold text-5">{{ item.total }}</view>
|
||||||
|
<view class="text-3">总数</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view
|
||||||
|
class="flex flex-row flex-justify-between px-4 py-3 box-border border-solid border-0 border-t-1 border-gray-200"
|
||||||
|
>
|
||||||
|
<view class="flex-1 mr-2">
|
||||||
|
<wd-button custom-style="background:#E9EBEF;color:#3372FA" :round="false" block>
|
||||||
|
刷新纪录
|
||||||
|
</wd-button>
|
||||||
|
</view>
|
||||||
|
<view class="flex-1 ml-2">
|
||||||
|
<wd-button :round="false" block>手动下发</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const recordList = ref([
|
||||||
|
{
|
||||||
|
time: '2025-01-07 10:19:28',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
status: '已完成',
|
||||||
|
success: 1,
|
||||||
|
fail: 1,
|
||||||
|
total: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2025-01-07 10:19:28',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
status: '已完成',
|
||||||
|
success: 1,
|
||||||
|
fail: 1,
|
||||||
|
total: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2025-01-07 10:19:28',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
status: '已完成',
|
||||||
|
success: 1,
|
||||||
|
fail: 1,
|
||||||
|
total: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2025-01-07 10:19:28',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
status: '已完成',
|
||||||
|
success: 1,
|
||||||
|
fail: 1,
|
||||||
|
total: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2025-01-07 10:19:28',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
status: '已完成',
|
||||||
|
success: 1,
|
||||||
|
fail: 1,
|
||||||
|
total: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time: '2025-01-07 10:19:28',
|
||||||
|
dec: '系统自动操作下发',
|
||||||
|
status: '已完成',
|
||||||
|
success: 1,
|
||||||
|
fail: 1,
|
||||||
|
total: 1
|
||||||
|
}
|
||||||
|
])
|
||||||
|
const goDetail = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/issue-record-detail'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
//
|
||||||
|
</style>
|
||||||
@ -1,7 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<view></view>
|
<view @click="goAttendance()">考勤</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
const goAttendance = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/attendance/attendance'
|
||||||
|
})
|
||||||
|
// todo goAttendance
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss"></style>
|
<style scoped lang="scss"></style>
|
||||||
|
|||||||
5
src/types/uni-pages.d.ts
vendored
5
src/types/uni-pages.d.ts
vendored
@ -6,6 +6,7 @@
|
|||||||
interface NavigateToOptions {
|
interface NavigateToOptions {
|
||||||
url: "/pages/home/home" |
|
url: "/pages/home/home" |
|
||||||
"/pages/application-list/application-list" |
|
"/pages/application-list/application-list" |
|
||||||
|
"/pages/attendance/attendance" |
|
||||||
"/pages/code/code" |
|
"/pages/code/code" |
|
||||||
"/pages/get-code/get-code" |
|
"/pages/get-code/get-code" |
|
||||||
"/pages/info-publish/info-publish" |
|
"/pages/info-publish/info-publish" |
|
||||||
@ -15,7 +16,9 @@ interface NavigateToOptions {
|
|||||||
"/pages/mine/mine" |
|
"/pages/mine/mine" |
|
||||||
"/pages/notification/notification" |
|
"/pages/notification/notification" |
|
||||||
"/pages/reset-password/reset-password" |
|
"/pages/reset-password/reset-password" |
|
||||||
"/pages/workbench/workbench";
|
"/pages/workbench/workbench" |
|
||||||
|
"/pages/attendance/attendance-add-group/attendance-add-group" |
|
||||||
|
"/pages/attendance/attendance-add-group/outside-rules";
|
||||||
}
|
}
|
||||||
interface RedirectToOptions extends NavigateToOptions {}
|
interface RedirectToOptions extends NavigateToOptions {}
|
||||||
|
|
||||||
|
|||||||
@ -48,3 +48,9 @@ export enum PlatId {
|
|||||||
miniProgram = 3,
|
miniProgram = 3,
|
||||||
pc = 4
|
pc = 4
|
||||||
}
|
}
|
||||||
|
export type OutsideRules = {
|
||||||
|
allow: boolean
|
||||||
|
takePhoto: boolean
|
||||||
|
remark: boolean
|
||||||
|
selectPhoto: boolean
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user