大数据模型练习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>
相关推荐
VALENIAN瓦伦尼安教学设备3 小时前
镭射对心仪在联轴器找正作用
大数据·数据库·人工智能·嵌入式硬件
2601_949543013 小时前
Flutter for OpenHarmony垃圾分类指南App实战:政策法规实现
大数据·flutter
春日见3 小时前
Autoware使用教程
大数据·人工智能·深度学习·elasticsearch·搜索引擎·docker·容器
新缸中之脑3 小时前
在OpenClaw中构建专业AI角色
大数据·人工智能
Gain_chance3 小时前
27-学习笔记尚硅谷数仓搭建-数据仓库DWD层介绍及其事务表(行为)相关概念
大数据·数据仓库·笔记·学习
EveryPossible4 小时前
大数据模型练习1
大数据
EveryPossible4 小时前
大数据模型练习2
大数据
会员源码网4 小时前
Elasticsearch从零启动指南:安装、配置、启停与排坑全解析
大数据·elasticsearch·搜索引擎
才盛智能科技4 小时前
元K:自助KTV行业AI生态领航者
大数据·人工智能·物联网·自助ktv系统·才盛云自助ktv系统