ForcePilot/web/src/components/ShareConfigForm.vue
Wenjie Zhang a5d55d6c37 refactor(storage): 重构对话数据库模型与存储管理
将业务数据模型从SQLite迁移至PostgreSQL,统一使用models_business.py
删除旧的SQLite模型和ConversationManager,新增repository和服务层
优化时间处理工具函数,增加utc_now_naive和format_utc_datetime
重构前端组件代码格式,统一多行导入和长字符串的换行风格
2026-01-24 10:56:31 +08:00

223 lines
5.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="share-config-form">
<div class="share-config-content">
<div class="share-mode">
<a-radio-group v-model:value="config.is_shared" class="share-mode-radio">
<a-radio :value="true">全员共享</a-radio>
<a-radio :value="false">指定部门</a-radio>
</a-radio-group>
</div>
<p class="share-hint">
{{ config.is_shared ? '所有用户都可以访问' : '只有指定部门的用户可以访问' }}
</p>
<!-- 部门选择 -->
<div v-if="!config.is_shared" class="dept-selection">
<a-select
v-model:value="config.accessible_department_ids"
mode="multiple"
placeholder="请选择可访问的部门"
style="width: 100%"
:options="departmentOptions"
/>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue'
import { useUserStore } from '@/stores/user'
import { departmentApi } from '@/apis/department_api'
const userStore = useUserStore()
const departments = ref([])
const props = defineProps({
modelValue: {
type: Object,
required: true,
default: () => ({
is_shared: true,
accessible_department_ids: []
})
},
// 是否自动选中当前用户所在部门
autoSelectUserDept: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['update:modelValue'])
// 本地状态,直接从 props 初始化
const config = reactive({
is_shared: true,
accessible_department_ids: []
})
// 初始化 config
const initConfig = () => {
// 后端返回的是 accessible_departments前端使用 accessible_department_ids
const sourceDepts =
props.modelValue.accessible_department_ids ?? props.modelValue.accessible_departments ?? []
config.is_shared = props.modelValue.is_shared ?? true
config.accessible_department_ids = sourceDepts.map((id) => Number(id))
console.log('[ShareConfigForm] initConfig:', JSON.stringify(config))
}
// 只在组件挂载时初始化一次
onMounted(() => {
initConfig()
})
// 监听本地 config 变化,同步到父组件
watch(
config,
(newVal) => {
console.log('[ShareConfigForm] config 变化emit:', JSON.stringify(newVal))
emit('update:modelValue', {
is_shared: newVal.is_shared,
accessible_department_ids: newVal.accessible_department_ids
})
},
{ deep: true }
)
// 监听共享模式变化
watch(
() => config.is_shared,
(newVal) => {
if (!newVal && props.autoSelectUserDept && config.accessible_department_ids.length === 0) {
// 切换到指定部门模式且未选中任何部门时,默认选中当前用户所在部门
tryAutoSelectUserDept()
}
}
)
// 尝试自动选中用户所在部门
const tryAutoSelectUserDept = () => {
const userDeptId = userStore.departmentId
if (userDeptId) {
const deptExists = departments.value.find((d) => d.id === userDeptId)
if (deptExists) {
// 确保存储为数字类型a-select 返回的是字符串)
config.accessible_department_ids = [Number(userDeptId)]
}
}
}
// 监听用户部门变化处理时序问题departmentId 可能在组件 mounted 后才获取到)
watch(
() => userStore.departmentId,
(newDeptId) => {
if (
props.autoSelectUserDept &&
!config.is_shared &&
config.accessible_department_ids.length === 0 &&
newDeptId
) {
tryAutoSelectUserDept()
}
}
)
// 部门选项
const departmentOptions = computed(() =>
departments.value.map((dept) => ({
label: dept.name,
value: Number(dept.id)
}))
)
// 加载部门列表
const loadDepartments = async () => {
try {
const res = await departmentApi.getDepartments()
departments.value = res.departments || res || []
// 如果需要,自动选中用户所在部门
if (
props.autoSelectUserDept &&
!config.is_shared &&
config.accessible_department_ids.length === 0
) {
tryAutoSelectUserDept()
}
} catch (e) {
console.error('加载部门列表失败:', e)
departments.value = []
}
}
onMounted(() => {
loadDepartments()
})
// 验证当前用户所在部门是否在可访问范围内
// 返回 { valid: boolean, message: string }
const validate = () => {
// 全员共享模式不需要验证
if (config.is_shared) {
return { valid: true, message: '' }
}
// 指定部门模式,需要验证当前用户所在部门是否在列表中
const userDeptId = userStore.departmentId
if (!userDeptId) {
return {
valid: false,
message: '您不属于任何部门,无法使用指定部门共享模式'
}
}
if (!config.accessible_department_ids.includes(userDeptId)) {
return {
valid: false,
message: '您所在的部门必须在可访问部门范围内'
}
}
return { valid: true, message: '' }
}
// 暴露方法给父组件
defineExpose({
config,
validate
})
</script>
<style lang="less" scoped>
.share-config-form {
h3 {
margin-top: 20px;
margin-bottom: 12px;
}
.share-config-content {
background: var(--gray-25);
border-radius: 8px;
padding: 16px;
border: 1px solid var(--gray-150);
.share-mode {
.share-mode-radio {
display: flex;
gap: 24px;
}
}
.share-hint {
font-size: 13px;
color: var(--gray-600);
margin: 8px 0 0 0;
}
.dept-selection {
margin-top: 12px;
}
}
}
</style>