Files
2026-09-24 15:54:47 +08:00

105 lines
3.5 KiB
Vue

<template>
<view class="page edge">
<fy-header title="发起申请" back />
<fy-scroll class="edge-scroll">
<view v-if="!canApply" class="deny">当前账号没有发起申请权限</view>
<view v-else>
<view class="search">
<wd-icon name="search" size="28rpx" color="#9CA3AF" />
<input v-model="q" placeholder="搜索审批流程或申请事项" placeholder-class="ph" confirm-type="search" />
<view v-if="q" class="clear" @click="q = ''">
<wd-icon name="close-bold" size="22rpx" color="#9CA3AF" />
</view>
</view>
<view v-if="!groups.length" class="empty">没有匹配的申请</view>
<view v-for="g in groups" :key="g.category" class="block">
<text class="cat">{{ g.category }}</text>
<view class="card">
<view v-for="k in g.items" :key="k.kind" class="item" @click="open(k)">
<view class="ico" :style="{ background: visual(k).bg }">
<wd-icon :name="visual(k).name" size="36rpx" :color="visual(k).color" />
</view>
<view class="txt">
<text class="t">{{ k.title }}</text>
<text class="d">{{ k.hint }}</text>
</view>
<wd-icon name="arrow-right" size="28rpx" color="#D1D5DB" />
</view>
</view>
</view>
</view>
</fy-scroll>
</view>
</template>
<script>
import FyHeader from '../../components/fy-header.vue'
import FyScroll from '../../components/fy-scroll.vue'
import { store } from '../../utils/store.js'
import { groupedApplyKinds, visibleApplyKinds } from '../../utils/apply.js'
import { tileVisual } from '../../utils/nav.js'
export default {
components: { FyHeader, FyScroll },
data() { return { q: '' } },
computed: {
canApply() { return store.can('personal', 'apply') },
groups() {
const me = store.me || {}
let kinds = visibleApplyKinds({
employeeStatus: me.employeeStatus,
isSuper: me.isSuper,
role: me.title
})
if (this.q.trim()) {
const q = this.q.trim()
kinds = kinds.filter((k) => (k.title + k.hint + k.group).includes(q))
}
return groupedApplyKinds(kinds)
}
},
methods: {
visual(k) {
return tileVisual(k)
},
open(k) {
uni.navigateTo({ url: '/pages/apply/form?kind=' + k.kind })
}
}
}
</script>
<style scoped>
.search {
margin: 16rpx 24rpx 8rpx;
height: 72rpx;
padding: 0 20rpx;
background: #fff;
border-radius: 16rpx;
display: flex;
align-items: center;
gap: 12rpx;
border: 1rpx solid rgba(17, 24, 39, 0.06);
}
.search input { flex: 1; height: 72rpx; font-size: 28rpx; }
.ph { color: #9CA3AF; }
.clear { width: 40rpx; height: 40rpx; display: flex; align-items: center; justify-content: center; }
.block { margin: 20rpx 24rpx 8rpx; }
.cat { display: block; margin: 0 8rpx 12rpx; font-size: 24rpx; color: #6B7280; font-weight: 600; }
.item { display: flex; align-items: center; padding: 22rpx 24rpx; }
.item + .item { border-top: 1rpx solid #F0F2F5; }
.ico {
width: 72rpx;
height: 72rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.txt { flex: 1; min-width: 0; margin: 0 20rpx; }
.t { display: block; font-size: 30rpx; font-weight: 600; color: #111827; }
.d { display: block; margin-top: 6rpx; font-size: 24rpx; color: #6B7280; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.empty, .deny { padding: 120rpx 40rpx; text-align: center; color: #6B7280; font-size: 28rpx; }
</style>