大数据模型练习4

html 复制代码
<template>
  <el-dialog v-model="visible" title="模板管理" width="900px">
    <el-table :data="searchStore.templates" style="width: 100%" stripe>
      <el-table-column prop="id" label="编号" width="60" />

      <el-table-column label="模板类型" width="100">
        <template #default="scope">
          <el-tag :type="scope.row.type === 'public' ? 'warning' : 'info'">
            {{ scope.row.type === 'public' ? '公用' : '个人' }}
          </el-tag>
        </template>
      </el-table-column>

      <el-table-column label="模板名称" min-width="150">
        <template #default="scope">
          <el-button link type="primary" @click="handleApply(scope.row)">
            {{ scope.row.name }}
          </el-button>
        </template>
      </el-table-column>

      <el-table-column prop="creator" label="创建人" width="120" />
      <el-table-column prop="createTime" label="创建时间" width="180" />

      <el-table-column label="设为默认" width="100" align="center">
        <template #default="scope">
          <el-switch
            :model-value="scope.row.isDefault"
            :loading="switchLoadingMap[scope.row.id]"
            :disabled="scope.row.isDefault"
            @change="() => handleSetDefault(scope.row)"
          />
        </template>
      </el-table-column>

      <el-table-column label="操作" width="120" fixed="right">
        <template #default="scope">
          <div class="action-buttons">
            <el-tooltip content="分享模板" placement="top" v-if="scope.row.permission?.canShare">
              <el-button link type="primary" :icon="Share" @click="handleShareOpen(scope.row)" />
            </el-tooltip>

            <el-tooltip content="删除模板" placement="top" v-if="scope.row.permission?.canDelete">
              <el-button link type="danger" :icon="Delete" @click="handleDelete(scope.row)" />
            </el-tooltip>
          </div>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>

  <el-dialog v-model="shareVisible" title="共享模板" width="450px" append-to-body>
    <el-form label-position="top">
      <el-form-item label="模板名称">
        <el-input v-model="currentShareRow.name" disabled />
      </el-form-item>
      <el-form-item label="共享给 (个人/群组)">
        <el-input v-model="shareTarget" placeholder="请输入工号或群组名" />
      </el-form-item>
      <el-form-item label="描述">
        <el-input type="textarea" placeholder="请输入描述信息" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="shareVisible = false" :disabled="shareSubmitting">取消</el-button>
      <el-button type="primary" @click="handleShareSubmit" :loading="shareSubmitting">
        确定分享
      </el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { computed, ref, reactive } from 'vue'
import { useSearchStore } from '../../stores/searchStore'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Share, Delete } from '@element-plus/icons-vue'

const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
const searchStore = useSearchStore()

const visible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val),
})

// === 1. 设为默认的相关逻辑 ===
const switchLoadingMap = reactive({}) // 存储每一行的 loading 状态 { id: boolean }

// 定义超时时长 (毫秒)
const API_TIMEOUT = 3000

const handleSetDefault = async (row) => {
  // 如果已经是默认的,不做操作(UI上其实已经disable了)
  if (row.isDefault) return

  // 1. 开启 Loading
  switchLoadingMap[row.id] = true

  try {
    // 2. 构造超时 Promise
    const timeoutPromise = new Promise((_, reject) => {
      setTimeout(() => {
        reject(new Error('请求超时,请稍后重试'))
      }, API_TIMEOUT)
    })

    // 3. Race: 真实请求 vs 超时
    await Promise.race([
      searchStore.apiSetDefault(row.id), // 调用 Store 的异步 Action
      timeoutPromise,
    ])

    // 成功后,Loading 会在 finally 移除,State 由 Store 更新
    ElMessage.success('设置默认模板成功')
  } catch (error) {
    // 4. 失败或超时处理
    console.error(error)
    ElMessage.error(error.message || '设置失败')

    // 注意:因为我们绑定的是 model-value 而不是 v-model,
    // 且数据更新依赖 store,所以失败时只要不改 store,Switch 就会自动保持原样。
  } finally {
    // 5. 关闭 Loading
    switchLoadingMap[row.id] = false
  }
}

// === 2. 删除相关逻辑 ===
const handleDelete = (row) => {
  ElMessageBox.confirm(`确定删除模板 "${row.name}" 吗?`, '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
    beforeClose: async (action, instance, done) => {
      if (action === 'confirm') {
        instance.confirmButtonLoading = true // 让 MessageBox 的按钮转圈
        instance.confirmButtonText = '删除中...'

        try {
          await searchStore.apiDeleteTemplate(row.id)
          ElMessage.success('删除成功')
          done()
        } catch (e) {
          ElMessage.error('删除失败')
        } finally {
          instance.confirmButtonLoading = false
        }
      } else {
        done()
      }
    },
  })
    .then(() => {
      // confirm 回调
    })
    .catch(() => {
      // cancel 回调
    })
}

// === 3. 分享相关逻辑 ===
const shareVisible = ref(false)
const shareSubmitting = ref(false)
const currentShareRow = ref({})
const shareTarget = ref('')

const handleShareOpen = (row) => {
  currentShareRow.value = { ...row }
  shareTarget.value = '' // 重置输入
  shareVisible.value = true
}

const handleShareSubmit = async () => {
  if (!shareTarget.value) {
    ElMessage.warning('请输入分享对象')
    return
  }

  shareSubmitting.value = true
  try {
    await searchStore.apiShareTemplate(currentShareRow.value.id, shareTarget.value)
    ElMessage.success('分享成功')
    shareVisible.value = false
  } catch (error) {
    ElMessage.error('分享失败,请重试')
  } finally {
    shareSubmitting.value = false
  }
}

// 点击名称应用模板
const handleApply = (row) => {
  searchStore.applyTemplate(row)
  visible.value = false
}
</script>

<style scoped>
.action-buttons {
  display: flex;
  gap: 8px;
  justify-content: center;
}
</style>
相关推荐
Elastic 中国社区官方博客24 分钟前
Elasticsearch:通过最小分数确保语义精度
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
狮子座明仔39 分钟前
DeepImageSearch:当图像检索需要“侦探式推理“,现有AI还差多远?
大数据·人工智能·语言模型
追风少年ii1 小时前
CosMx文献分享--空间同型聚类对癌细胞可塑性的抑制
大数据·数据挖掘·数据分析·空间·单细胞
2501_926978331 小时前
近10年中国社会发展路径总体视角图--双层架构的出现
大数据·人工智能
nita张2 小时前
2026年2月战略定位公司案例分享
大数据·人工智能·python
L***一2 小时前
高职大数据专业就业竞争力构建:从技能筑基到价值转化的实践路径
大数据
Hello.Reader2 小时前
Flink 任务失败恢复机制Restart Strategy 和 Failover Strategy 怎么配才“又稳又不炸”
大数据·flink·策略模式
keke.shengfengpolang11 小时前
2026大专大数据与财务管理:不止是会计
大数据
龙山云仓11 小时前
No160:AI中国故事-对话耿恭——孤城坚守与AI韧性:极端环境与信念之光
大数据·人工智能·机器学习