补卡申请

ZhangLei 2024-04-23 18:08:20 +08:00
parent 54027768f0
commit f6cfa38403
5 changed files with 299 additions and 60 deletions

View File

@ -175,6 +175,23 @@
}
}
]
},
{
"root": "pages/make-card",
"pages": [
{
"path": "list",
"style": {
"navigationBarTitleText": "补卡申请"
}
},
{
"path": "create",
"style": {
"navigationBarTitleText": "补卡申请"
}
}
]
}
],
"globalStyle": {

View File

@ -0,0 +1,28 @@
<template>
<view class="card-shadow bg-white rounded-19rpx p-base space-y-10rpx">
<view class="text-30rpx">补卡申请</view>
<view class="text-24rpx text-hex-999999 flex">
<view class="text-24rpx w-140rpx">补卡原因</view>
<view class="">{{ item.reason }}</view>
</view>
<view class="text-24rpx text-hex-999999 flex">
<view class="text-24rpx w-140rpx">补卡类别</view>
<view class="">{{ item.sign_time == 1 ? "上班打卡" : "下班打卡" }}</view>
</view>
<view class="flex items-center text-hex-999999 flex">
<view class="text-24rpx w-140rpx"> 补卡时间</view>
<view class="text-24rpx">{{ valueFormat }}</view>
</view>
<view class="text-30rpx">{{ item.workflow_check.check_status_text }}</view>
</view>
</template>
<script setup>
import { computed } from "vue"
import { timeFormat } from "@climblee/uv-ui/libs/function/index"
const props = defineProps({
item: Object
})
const valueFormat = computed(() => {
return timeFormat(props.item.date, "yyyy-MM-dd hh:mm")
})
</script>

View File

@ -0,0 +1,137 @@
<template>
<view>
<CuNavbar title="补卡申请">
<template #right>
<view class="text-24rpx text-white" @click="submit"></view>
</template>
</CuNavbar>
<view class="card-shadow px-base">
<uv-form labelPosition="left" :model="form" :rules="rules" ref="formRef" errorType="toast" labelWidth="250rpx">
<uv-form-item required label="补卡时间" prop="date">
<uv-input
placeholder="请选择日期"
readonly
@click="openDatePicker"
inputAlign="right"
:border="`none`"
v-model="form.date"
>
</uv-input>
</uv-form-item>
<uv-line color="#f5f5f5"></uv-line>
<uv-form-item required label="补卡类型" prop="sign_time">
<uv-input
placeholder="请选择"
@click="openPicker"
readonly
inputAlign="right"
:border="`none`"
v-model="form.sign_time"
>
</uv-input>
</uv-form-item>
<uv-line color="#f5f5f5"></uv-line>
<uv-form-item required label="补卡理由" prop="reason" labelPosition="top">
<uv-textarea v-model="form.reason" count placeholder="请输入" :border="`none`" :maxlength="200"></uv-textarea>
</uv-form-item>
<uv-line color="#f5f5f5"></uv-line>
<uv-form-item required label="外勤" prop="isOutSide">
<view class="flex flex-1 justify-end">
<uv-switch size="20" v-model="form.isOutSide"></uv-switch>
</view>
</uv-form-item>
<uv-form-item v-if="form.isOutSide" required label="外勤事由" prop="outside_remarks" labelPosition="top">
<uv-textarea
v-model="form.outside_remarks"
count
placeholder="请输入"
:border="`none`"
:maxlength="200"
></uv-textarea>
</uv-form-item>
</uv-form>
</view>
<uv-picker ref="pickerRef" :columns="columns" @confirm="confirmPicker"></uv-picker>
<uv-datetime-picker placeholder="请选择日期" ref="datetimePicker" mode="datetime" @confirm="confirmDatePicker">
</uv-datetime-picker>
<uv-modal ref="modalRef" title="提示" content="确定提交吗?" @confirm="onSubmit" :showCancelButton="true"></uv-modal>
</view>
</template>
<script setup>
import CuNavbar from "@/components/cu-navbar/index"
import { ref, reactive, computed } from "vue"
import { onLoad } from "@dcloudio/uni-app"
import { http } from "@/utils/request"
import { timeFormat } from "@climblee/uv-ui/libs/function/index"
const columns = [["上班打卡", "下班打卡"]]
const formRef = ref(null)
const datetimePicker = ref(null)
const pickerRef = ref(null)
const modalRef = ref(null)
const id = ref(0)
const loading = ref(false)
const form = reactive({
date: "",
sign_time: "",
reason: "",
outside_remarks: "",
isOutSide: false
})
const openPicker = () => {
pickerRef.value.open()
}
const openDatePicker = () => {
datetimePicker.value.open()
}
const confirmDatePicker = e => {
form.date = timeFormat(e.value, "yyyy-MM-dd hh:mm")
}
const confirmPicker = e => {
form.sign_time = e.value[0]
}
const rules = reactive({
date: [{ required: true, message: "请选择时间" }],
sign_time: [{ required: true, message: "请选择类型" }],
reason: [{ required: true, message: "请输入补卡理由" }],
outside_remarks: [{ required: true, message: "请输入补卡理由" }]
})
onLoad(options => {
id.value = options.id
})
const submit = () => {
formRef.value.validate().then(res => {
modalRef.value.open()
})
}
const onSubmit = async () => {
if (loading.value) return
loading.value = true
try {
await http.request({
url: `/hr/sign-repairs`,
method: "POST",
header: {
Accept: "application/json"
},
data: {
date: form.date,
sign_time: form.sign_time == "上班打卡" ? 1 : 2,
reason: form.reason,
outside_remarks: form.outside_remarks
}
})
uni.showToast({
title: "提交成功",
icon: "none"
})
formRef.value.resetFields()
uni.navigateBack()
} catch (error) {
console.log(error)
} finally {
loading.value = false
}
}
</script>

View File

@ -0,0 +1,58 @@
<template>
<view>
<CuNavbar title="补卡申请">
<template #right>
<view @click="goPath('/pages/make-card/create')" class="text-24rpx text-white">申请</view>
</template>
</CuNavbar>
<uv-sticky bgColor="#fff">
<uv-tabs
:activeStyle="{ color: '#ee2c37' }"
:scrollable="false"
lineColor="#ee2c37"
:list="tabList"
@change="tabChange"
></uv-tabs>
</uv-sticky>
<MescrollItem ref="mescrollItem0" :top="88" :i="0" :index="tabIndex" :apiUrl="tabList[0].apiUrl">
<template v-slot="{ list }">
<view class="space-y-15rpx p-base">
<view v-for="(item, i) in list" :key="i">
<Item :item="item"></Item>
</view>
</view>
</template>
</MescrollItem>
</view>
</template>
<script setup>
import CuNavbar from "@/components/cu-navbar/index"
import { ref } from "vue"
import { onPageScroll, onReachBottom, onShow } from "@dcloudio/uni-app"
import useMescrollMore from "@/uni_modules/mescroll-uni/hooks/useMescrollMore.js"
import MescrollItem from "@/components/mescroll-api/more.vue"
import Item from "./components/item.vue"
const tabList = ref([
{
name: "我的补卡",
apiUrl: "/hr/sign-repairs"
},
{
name: "补卡申请"
}
])
const mescrollItem0 = ref(null)
const mescrollItem1 = ref(null)
const mescrollItems = [mescrollItem0, mescrollItem1]
const { tabIndex, getMescroll, scrollToLastY } = useMescrollMore(mescrollItems, onPageScroll, onReachBottom)
const goPath = url => {
uni.navigateTo({
url
})
}
const tabChange = ({ index }) => {
tabIndex.value = index
scrollToLastY()
}
</script>

View File

@ -3,7 +3,11 @@
<CuNavbar :isBack="false" title="我的">
<template #right>
<view class="h-full flex-center">
<image @click="goPath('/pages/setting/index')" class="w-32rpx h-32rpx" src="/static/images/setting.svg"></image>
<image
@click="goPath('/pages/setting/index')"
class="w-32rpx h-32rpx"
src="/static/images/setting.svg"
></image>
</view>
</template>
</CuNavbar>
@ -11,107 +15,102 @@
<view class="card" v-for="(item, i) in opList" :key="i">
<TitleComp :title="item.title"></TitleComp>
<view class="grid grid-cols-3 mt-20rpx gap-20rpx">
<OpItem
v-for="(child, ii) in item.children"
:key="ii"
:data="child"
></OpItem>
<OpItem v-for="(child, ii) in item.children" :key="ii" :data="child"></OpItem>
</view>
</view>
</view>
</view>
</template>
<script setup>
import TitleComp from '@/components/title-comp/index'
import OpItem from './components/op-item.vue'
import CuNavbar from '@/components/cu-navbar/index'
import TitleComp from "@/components/title-comp/index"
import OpItem from "./components/op-item.vue"
import CuNavbar from "@/components/cu-navbar/index"
const opList = [
{
title: '门店数据',
title: "门店数据",
children: [
{
icon: 'order',
title: '业绩数据',
url: '/pages/data/performance/index',
icon: "order",
title: "业绩数据",
url: "/pages/data/performance/index"
},
{
icon: 'folder',
title: '提成数据',
url: '/pages/data/brokerage/index',
},
],
icon: "folder",
title: "提成数据",
url: "/pages/data/brokerage/index"
}
]
},
{
title: '办公管理',
title: "办公管理",
children: [
{
icon: 'photo-fill',
title: '员工管理',
url: '/pages/user/index',
icon: "photo-fill",
title: "员工管理",
url: "/pages/user/index"
},
{
icon: 'lock',
title: '我的任务',
url: '/pages/task/index',
icon: "lock",
title: "我的任务",
url: "/pages/task/index"
},
{
icon: 'home-fill',
title: '报销管理',
url: '/pages/expense-account/index',
icon: "home-fill",
title: "报销管理",
url: "/pages/expense-account/index"
},
{
icon: 'map-fill',
title: '升职申请',
url: '/pages/work/list',
icon: "map-fill",
title: "升职申请",
url: "/pages/work/list"
},
{
icon: 'grid-fill',
title: '补卡申请',
url: '',
icon: "grid-fill",
title: "补卡申请",
url: "/pages/make-card/list"
},
{
icon: 'car',
title: '请假申请',
url: '',
icon: "car",
title: "请假申请",
url: ""
},
{
icon: 'setting-fill',
title: '出差报备',
url: '',
icon: "setting-fill",
title: "出差报备",
url: ""
},
{
icon: 'server-man',
title: '加班报备',
url: '',
icon: "server-man",
title: "加班报备",
url: ""
},
{
icon: 'camera',
title: '合同管理',
url: '',
},
],
icon: "camera",
title: "合同管理",
url: ""
}
]
},
{
title: '天天向上',
title: "天天向上",
children: [
{
icon: 'account',
title: '培训课件',
url: '',
icon: "account",
title: "培训课件",
url: ""
},
{
icon: 'twitte',
title: '培训考试',
url: '',
},
],
},
icon: "twitte",
title: "培训考试",
url: ""
}
]
}
]
const goPath = (url) => {
const goPath = url => {
uni.navigateTo({
url
})
}
</script>