大数据模型练习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>
相关推荐
毕设源码-邱学长19 小时前
【开题答辩全过程】以 基于大数据技术的音乐推荐系统设计与实现为例,包含答辩的问题和答案
大数据
旺仔Sec19 小时前
2026年广东省职业院校技能大赛中职组“大数据应用与服务“赛项任务书(三)
大数据·hadoop
曾阿伦19 小时前
Elasticsearch 自定义分词匹配与同义词处理实战详解
大数据·elasticsearch·搜索引擎
天远云服20 小时前
天远企业司法认证API对接实战:PHP构建B2B供应链合规防火墙
大数据·开发语言·后端·node.js·php
赵谨言20 小时前
基于YOLOv5的植物目标检测研究
大数据·开发语言·经验分享·python
Hello.Reader20 小时前
Flink 应用升级与版本迁移Savepoint、状态兼容、跨版本恢复一次讲透
大数据·chrome·flink
毕设源码-朱学姐20 小时前
【开题答辩全过程】以 基于大数据技术的电商推荐系统的设为例,包含答辩的问题和答案
大数据
远方160921 小时前
115-使用freesql体验Oracle 多版本特性
大数据·数据库·sql·ai·oracle·database
上海蓝色星球21 小时前
造价机器人CER V2.0正式上线!
大数据·人工智能·智慧城市·运维开发
八角Z1 天前
AI价值跃迁的核心:输出责任转移与新兴工种的精准重塑
大数据·人工智能·科技·机器学习·计算机视觉·服务发现