feat:部门选择
This commit is contained in:
196
components/company-dept-dialog/company-dept-dialog.vue
Normal file
196
components/company-dept-dialog/company-dept-dialog.vue
Normal file
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<view v-if="dialogStore.show" class="company-dept-dialog">
|
||||
<view class="company-dept-dialog__mask" @tap="handleCancel" />
|
||||
<view class="company-dept-dialog__panel">
|
||||
<view class="company-dept-dialog__header">
|
||||
<text class="company-dept-dialog__title">{{ dialogStore.title }}</text>
|
||||
</view>
|
||||
<view class="company-dept-dialog__body">
|
||||
<!-- 公司选择 -->
|
||||
<view class="company-dept-dialog__field">
|
||||
<text class="company-dept-dialog__label">公司</text>
|
||||
<uni-data-select
|
||||
v-model="selectedCompanyModel"
|
||||
:localdata="companyOptionsForSelect"
|
||||
collection=""
|
||||
field="companyName"
|
||||
orderby=""
|
||||
:clear-icon="false"
|
||||
@change="onCompanyChangeUni"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 部门选择 -->
|
||||
<view class="company-dept-dialog__field">
|
||||
<text class="company-dept-dialog__label">部门</text>
|
||||
<uni-data-select
|
||||
v-model="selectedDeptModel"
|
||||
:localdata="deptOptionsForSelect"
|
||||
collection=""
|
||||
field="deptName"
|
||||
orderby=""
|
||||
:clear-icon="false"
|
||||
@change="onDeptChangeUni"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="company-dept-dialog__footer">
|
||||
<u-button @tap="handleCancel">取消</u-button>
|
||||
<u-button type="primary" :disabled="!isConfirmEnabled" @tap="handleConfirm"> 确定 </u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import nx from '@/nx'
|
||||
|
||||
const dialogStore = nx.$store('company-dept')
|
||||
const { companyList, selectedCompanyId, selectedDeptId } = storeToRefs(dialogStore)
|
||||
|
||||
const deptOptions = computed(() => dialogStore.getDeptsByCompanyId(selectedCompanyModel.value))
|
||||
|
||||
// 用于 uni-data-select 的格式:必须包含 value 和 text 字段
|
||||
const companyOptionsForSelect = computed(() =>
|
||||
companyList.value.map(item => ({
|
||||
value: item.companyId,
|
||||
text: item.companyName
|
||||
}))
|
||||
)
|
||||
|
||||
const deptOptionsForSelect = computed(() =>
|
||||
deptOptions.value.map(item => ({
|
||||
value: item.deptId,
|
||||
text: item.deptName
|
||||
}))
|
||||
)
|
||||
|
||||
// 双向绑定模型(uni-data-select 使用 value 绑定)
|
||||
const selectedCompanyModel = ref(selectedCompanyId.value)
|
||||
const selectedDeptModel = ref(selectedDeptId.value)
|
||||
|
||||
// 监听 store 变化,同步到 model(应对外部触发更新)
|
||||
watch(
|
||||
() => selectedCompanyId.value,
|
||||
newVal => {
|
||||
if (newVal !== selectedCompanyModel.value) {
|
||||
selectedCompanyModel.value = newVal
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => selectedDeptId.value,
|
||||
newVal => {
|
||||
if (newVal !== selectedDeptModel.value) {
|
||||
selectedDeptModel.value = newVal
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// uni-data-select 的 change 回调
|
||||
const onCompanyChangeUni = e => {
|
||||
const companyId = e
|
||||
if (companyId !== undefined && companyId !== null) {
|
||||
dialogStore.setSelectedCompany(companyId)
|
||||
// 重置部门选择
|
||||
dialogStore.setSelectedDept('')
|
||||
selectedDeptModel.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
const onDeptChangeUni = e => {
|
||||
const deptId = e
|
||||
if (deptId !== undefined && deptId !== null) {
|
||||
dialogStore.setSelectedDept(deptId)
|
||||
}
|
||||
}
|
||||
|
||||
// 按钮状态
|
||||
const isConfirmEnabled = computed(() => !!dialogStore.selectedCompanyId && !!dialogStore.selectedDeptId)
|
||||
|
||||
// 操作
|
||||
const handleCancel = () => {
|
||||
dialogStore.cancel()
|
||||
}
|
||||
|
||||
const handleConfirm = () => {
|
||||
if (!isConfirmEnabled.value) return
|
||||
dialogStore.confirm()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.company-dept-dialog {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 15000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&__mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
&__panel {
|
||||
position: relative;
|
||||
width: 45vw;
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
padding: 24px 20px 16px;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
&__panel {
|
||||
width: 70vw;
|
||||
}
|
||||
}
|
||||
&__header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1f1f1f;
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
&__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
&__field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
&__label {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user