feat: 修改审批组件支持行内格式+添加虚拟键盘组件+添加邀约组件

This commit is contained in:
范鹏 2025-01-16 18:38:45 +08:00
parent 3bfcf05ad9
commit dc3d862e62
14 changed files with 399 additions and 114 deletions

View File

@ -240,7 +240,11 @@
"type": "page"
},
{
"path": "pages/select-member-or-department/select-member-or-department",
"path": "pages/select/select-access-control",
"type": "page"
},
{
"path": "pages/select/select-organization",
"type": "page",
"style": {
"navigationStyle": "custom",

View File

@ -1,5 +1,6 @@
<template>
<view class="pb-3">
<Visitor></Visitor>
<view class="bg-white mx-4 p-2 rounded-2">
<Input
:id="0"
@ -68,14 +69,14 @@
title="图片21378912378923718982371217389712397837889713247893428793142897134728900978"
></Description>
<wd-divider color="#bcbfbe"></wd-divider>
<MemberOrDepartment :id="10" title="成员" type="member" :multiple="true"></MemberOrDepartment>
<NavigatorSelector :id="10" title="成员" type="member" :multiple="true"></NavigatorSelector>
<wd-divider color="#bcbfbe"></wd-divider>
<MemberOrDepartment
<NavigatorSelector
:id="11"
title="部门"
type="department"
:multiple="true"
></MemberOrDepartment>
></NavigatorSelector>
<wd-divider color="#bcbfbe"></wd-divider>
<Leave :id="12"></Leave>
<wd-divider color="#bcbfbe"></wd-divider>
@ -103,10 +104,11 @@
import DatetimePicker from '@/pages/approval/components/DatetimePicker.vue'
import Images from '@/pages/approval/components/Images.vue'
import Description from '@/pages/approval/components/Description.vue'
import MemberOrDepartment from '@/pages/approval/components/MemberOrDepartment.vue'
import NavigatorSelector from '@/pages/approval/components/NavigatorSelector.vue'
import Leave from '@/pages/approval/components/Leave.vue'
import DatetimePickerGroup from '@/pages/approval/components/DatetimePickerGroup.vue'
import Overtime from '@/pages/approval/components/Overtime.vue'
import Visitor from '@/pages/approval/components/Visitor.vue'
const columns = ref<Record<number, string>>([
{

View File

@ -1,15 +1,29 @@
<template>
<view class="px-2 text-3.5">
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
</view>
<view class="py-2" @click="openDialog">
<view class="flex flex-items-center flex-justify-between">
<view :class="text ? 'custom-color-black' : 'color-#838589'">
{{ text || placeholder }}
<view v-if="inline">
<view class="flex flex-items-center pos-relative pt-2 pb-1">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
<view @click="openDialog" class="flex-1 flex flex-items-center">
<view :class="[text ? 'custom-color-black' : 'color-#bfbfbf']" class="ml-a mr-2">
{{ text || placeholder }}
</view>
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
</view>
</view>
</view>
<view v-else>
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
</view>
<view class="py-2" @click="openDialog">
<view class="flex flex-items-center flex-justify-between">
<view :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
{{ text || placeholder }}
</view>
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
</view>
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
</view>
</view>
</view>
@ -131,6 +145,10 @@
maxDateText: {
type: String,
default: ''
},
inline: {
type: Boolean,
default: false
}
})

View File

@ -1,19 +1,38 @@
<template>
<view class="px-2 text-3.5">
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
<view v-if="inline">
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
<wd-input
class="flex-1 ml-2"
:type="type"
custom-class="!bg-transparent"
:custom-input-class="inline ? 'text-right' : 'text-left'"
:placeholder="placeholder"
:maxlength="maxlength ?? (type === 'text' ? 30 : 15)"
v-model="text"
:readonly="readonly"
@input="change(id, $event)"
></wd-input>
</view>
</view>
<view class="pt-2">
<wd-input
:type="type"
custom-class="!bg-transparent"
:placeholder="placeholder"
:maxlength="type === 'text' ? 30 : 15"
v-model="text"
:readonly="readonly"
@input="change(id, $event)"
></wd-input>
<view v-else>
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
</view>
<view class="pt-2">
<wd-input
:type="type"
custom-class="!bg-transparent"
:placeholder="placeholder"
:maxlength="maxlength ?? (type === 'text' ? 30 : 15)"
v-model="text"
:readonly="readonly"
@input="change(id, $event)"
></wd-input>
</view>
</view>
</view>
</template>
@ -51,6 +70,14 @@
readonly: {
type: Boolean,
default: false
},
inline: {
type: Boolean,
default: false
},
maxlength: {
type: [Number, null],
default: null
}
})

View File

@ -0,0 +1,94 @@
<template>
<view class="px-2 text-3.5">
<view v-if="inline">
<view class="flex flex-items-center pos-relative py-1.5">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
<view
class="flex-1 ml-a text-right"
@click="toSelect"
:class="[text ? 'custom-color-black' : 'color-#bfbfbf']"
>
{{ text || placeholder }}
</view>
</view>
</view>
<view v-else>
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
</view>
<view class="py-2" @click="toSelect">
<view class="flex flex-items-center flex-justify-between">
<view :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
{{ text || placeholder }}
</view>
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
</view>
</view>
</view>
<wd-keyboard
:mode="type"
title="键盘"
:hide-on-click-outside="true"
v-model:visible="visible"
@input="onInput"
closeText="确认"
@delete="onDelete"
/>
</view>
</template>
<script setup lang="ts">
const text = ref<string>('')
const visible = ref<boolean>(false)
const onInput = value => {
if (props.maxlength && text.value.length >= props.maxlength) return
text.value += value
}
const onDelete = () => {
text.value = text.value.slice(0, -1)
}
const props = defineProps({
id: {
type: Number,
required: true
},
type: {
type: String,
required: true
},
required: {
type: Boolean,
default: false
},
title: {
type: String,
required: true
},
value: {
type: [Number, null],
default: null
},
placeholder: {
type: String,
default: '请输入'
},
maxlength: {
type: [Number, null],
default: null
},
inline: {
type: Boolean,
default: false
}
})
const toSelect = () => {
visible.value = true
}
</script>
<style scoped lang="scss"></style>

View File

@ -1,67 +0,0 @@
<template>
<view class="px-2 text-3.5">
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
</view>
<view class="py-2" @click="toSelect">
<view class="flex flex-items-center flex-justify-between">
<view :class="text ? 'custom-color-black' : 'color-#838589'">
{{ text || placeholder }}
</view>
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
</view>
</view>
</view>
</template>
<script setup lang="ts">
const text = ref<string | null>(null)
const props = defineProps({
id: {
type: Number,
required: true
},
type: {
type: String,
required: true
},
multiple: {
type: Boolean,
default: false
},
required: {
type: Boolean,
default: false
},
title: {
type: String,
required: true
},
value: {
type: [Number, null],
default: null
},
placeholder: {
type: String,
default: '请输入'
}
})
const toSelect = () => {
const params = {
type: props.type,
multiple: props.multiple,
title: props.type === 'member' ? '选择审批用户' : '选择部门'
}
uni.navigateTo({
url: `/pages/select-member-or-department/select-member-or-department?params=${JSON.stringify(params)}`,
events: {
change: res => {
console.log(1111, res)
}
}
})
}
</script>

View File

@ -0,0 +1,89 @@
<template>
<view class="px-2 text-3.5">
<view v-if="inline">
<view class="flex flex-items-center pos-relative pb-1.5">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
<view class="ml-a mr-2" :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
{{ text || placeholder }}
</view>
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
</view>
</view>
<view v-else>
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
</view>
<view class="py-2" @click="toSelect">
<view class="flex flex-items-center flex-justify-between">
<view :class="[text ? 'custom-color-black' : 'color-#bfbfbf']">
{{ text || placeholder }}
</view>
<wd-icon name="arrow-right" color="rgba(0,0,0,0.25)" size="18px"></wd-icon>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
const text = ref<string | null>(null)
const props = defineProps({
id: {
type: Number,
required: true
},
type: {
type: String,
required: true
},
multiple: {
type: Boolean,
default: false
},
required: {
type: Boolean,
default: false
},
title: {
type: String,
required: true
},
value: {
type: [Number, null],
default: null
},
placeholder: {
type: String,
default: '请选择'
},
inline: {
type: Boolean,
default: false
}
})
const toSelect = () => {
if (props.type === 'accessControl') {
uni.navigateTo({
url: `/pages/select/select-access-control`
})
} else {
const params = {
type: props.type,
multiple: props.multiple,
title: props.type === 'member' ? '选择审批用户' : '选择部门'
}
uni.navigateTo({
url: `/pages/select/select-organization?params=${JSON.stringify(params)}`,
events: {
change: res => {
console.log(1111, res)
}
}
})
}
}
</script>

View File

@ -1,20 +1,40 @@
<template>
<view class="px-2 text-3.5">
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
<view v-if="inline">
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
<wd-select-picker
class="flex-1"
align-right
:type="type"
:title="placeholder"
:show-confirm="type === 'checkbox'"
v-model="picker"
:columns="columns"
size="large"
@change="change"
select-size="large"
></wd-select-picker>
</view>
</view>
<view class="pt-2">
<wd-select-picker
:type="type"
:title="placeholder"
:show-confirm="type === 'checkbox'"
v-model="picker"
:columns="columns"
size="large"
@change="change"
select-size="large"
></wd-select-picker>
<view v-else>
<view class="flex flex-items-center pos-relative">
<view v-if="required" class="color-#f62933 pos-absolute left--2 mt-1">*</view>
<view>{{ title }}</view>
</view>
<view class="pt-2">
<wd-select-picker
:type="type"
:title="placeholder"
:show-confirm="type === 'checkbox'"
v-model="picker"
:columns="columns"
size="large"
@change="change"
select-size="large"
></wd-select-picker>
</view>
</view>
</view>
</template>
@ -50,6 +70,10 @@
columns: {
type: Array,
required: true
},
inline: {
type: Boolean,
default: false
}
})

View File

@ -0,0 +1,86 @@
<template>
<view class="bg-white mx-4 p-2 rounded-2 mb-2">
<Input :id="0" title="访客姓名" :required="true" @change="inputChange" inline></Input>
<wd-divider color="#bcbfbe"></wd-divider>
<Input
:id="1"
title="访客手机"
:required="true"
:maxlength="11"
@change="inputChange"
inline
type="number"
></Input>
<wd-divider color="#bcbfbe"></wd-divider>
<SelectPicker required :id="2" title="访客类型" :columns="columns" inline></SelectPicker>
<wd-divider color="#bcbfbe"></wd-divider>
<NavigatorSelector :id="3" title="通行门禁点" type="accessControl" inline></NavigatorSelector>
</view>
<view class="bg-white mx-4 p-2 rounded-2 mb-2">
<Keyboard :id="4" title="车牌号码" type="car" :maxlength="8" inline></Keyboard>
</view>
<view class="bg-white mx-4 p-2 rounded-2 mb-2">
<DatetimePicker
:id="5"
ref="startDatetimePicker"
title="预约到访时间"
@change="changeDate"
type="datetime"
inline
required
></DatetimePicker>
<wd-divider color="#bcbfbe"></wd-divider>
<Input :id="7" title="同行人数" @change="inputChange" inline></Input>
<wd-divider color="#bcbfbe"></wd-divider>
<Input :id="8" title="访问单位" @change="inputChange" inline></Input>
<wd-divider color="#bcbfbe"></wd-divider>
<Input :id="9" title="到访事由说明" @change="inputChange" inline></Input>
<wd-divider color="#bcbfbe"></wd-divider>
<Input :id="10" title="访问地址" @change="inputChange" inline></Input>
<wd-divider color="#bcbfbe"></wd-divider>
<Description :id="11" title="表单通过后,访客将收到断音邀请通知"></Description>
</view>
</template>
<script setup lang="ts">
import Input from '@/pages/approval/components/Input.vue'
import SelectPicker from '@/pages/approval/components/SelectPicker.vue'
import Description from '@/pages/approval/components/Description.vue'
import Keyboard from '@/pages/approval/components/Keyboard.vue'
import DatetimePicker from '@/pages/approval/components/DatetimePicker.vue'
import NavigatorSelector from '@/pages/approval/components/NavigatorSelector.vue'
const columns = ref<Record<number, string>>([
{
value: 0,
label: '外卖快递'
},
{
value: 1,
label: '会议洽谈'
},
{
value: 2,
label: '探亲访友'
},
{
value: 3,
label: '业务沟通'
}
])
const inputChange = e => {
console.log('inputChange', e)
}
const changeDate = e => {
// timestamp.value = e.value
console.log('changeDate', e)
}
</script>
<style lang="scss" scoped>
.wd-divider {
padding: 0 0.5rem;
}
</style>

View File

@ -0,0 +1,7 @@
<template>
<view></view>
</template>
<script setup lang="ts"></script>
<style scoped lang="scss"></style>

View File

@ -61,7 +61,7 @@
@click="toOrganization(index)"
>
<span
:class="[index === organizationList.length - 1 ? 'color-#838589' : 'custom-color-blue']"
:class="[index === organizationList.length - 1 ? 'color-#bfbfbf' : 'custom-color-blue']"
>
{{ department.name }}
</span>
@ -88,12 +88,12 @@
></wd-icon>
<wd-icon v-else name="circle1" color="#838589" size="26px"></wd-icon>
</view>
<MemberOrDepartmentItem
<OrganizationItem
class="flex-1"
:item="item"
:disabled="item.type === 'department' && value.includes(item)"
@click="toClick(item)"
></MemberOrDepartmentItem>
></OrganizationItem>
</view>
</view>
<view class="py-5 px-15">
@ -146,8 +146,8 @@
<script setup lang="ts">
import { useBasicStore } from '@/store'
import MemberOrDepartmentItem from '@/pages/select-member-or-department/components/MemberOrDepartmentItem.vue'
import SearchItem from '@/pages/select-member-or-department/components/SearchItem.vue'
import OrganizationItem from '@/pages/select/components/OrganizationItem.vue'
import SearchItem from '@/pages/select/components/SearchItem.vue'
import GetSystemInfoResult = UniNamespace.GetSystemInfoResult
const instance = getCurrentInstance().proxy

View File

@ -29,7 +29,8 @@ interface NavigateToOptions {
"/pages/login/reset-password" |
"/pages/mine/mine" |
"/pages/notification/notification" |
"/pages/select-member-or-department/select-member-or-department" |
"/pages/select/select-access-control" |
"/pages/select/select-organization" |
"/pages/workbench/workbench" |
"/pages/attendance/attendance-add-group/attendance-add-group" |
"/pages/attendance/attendance-add-group/attendance-device" |