<script src="../../../config/global.ts"></script>
<template>
  <div class="list-card">
    <!-- 搜索区域 -->
    <div class="list-card-operation">
      <t-button @click="formVisible = true">新建项目</t-button>
      <t-input v-model="searchValue" class="search-input" placeholder="请输入你需要搜索的项目标题" clearable>
        <template #suffix-icon>
          <search-icon v-if="searchValue === ''" size="20px" />
        </template>
      </t-input>
    </div>
    <!-- 卡片列表 -->
    <template v-if="pagination.total > 0 && !dataLoading">
      <div class="list-card-items">
        <t-row :gutter="[16, 16]">
          <t-col
            :lg="4"
            :xs="6"
            :xl="3"
            v-for="(project, index) in sortedProjectList.slice (
              pagination.pageSize * (pagination.current - 1),
              pagination.pageSize * pagination.current,
            )"
            :key="index"
          >
            <project-card :project="project" @delete-item="handleDeleteItem" @manage-project="handleManageproject" />
          </t-col>
        </t-row>
      </div>
      <div class="list-card-pagination">
        <t-pagination
          v-model="pagination.current"
          :total="pagination.total"
          :pageSizeOptions="[12, 24, 36]"
          :page-size.sync="pagination.pageSize"
          @page-size-change="onPageSizeChange"
          @current-change="onCurrentChange"
        />
      </div>
    </template>
    <div v-else-if="dataLoading" class="list-card-loading">
      <t-loading text="加载中..."></t-loading>
    </div>
    <!-- 项目管理弹窗 -->
    <t-dialog header="新建项目" :visible.sync="formVisible" :width="680" :footer="false">
      <div slot="body">
        <!-- 表单内容 -->
        <t-form :data="formData" ref="form" :rules="rules" @submit="onSubmit" :labelWidth="100">
          <t-form-item label="项目名称" name="project_name">
            <t-input :style="{ width: '480px' }" v-model="formData.project_name" placeholder="请输入项目名称"></t-input>
          </t-form-item>
          <t-form-item label="项目介绍" name="project_description">
            <t-input :style="{ width: '480px' }" v-model="formData.project_description" placeholder="请输入项目介绍"></t-input>
          </t-form-item>
<pre><code>      &lt;t-form-item style=&quot;float: right&quot;&gt;
        &lt;t-button variant=&quot;outline&quot; @click=&quot;onClickCloseBtn&quot;&gt;取消&lt;/t-button&gt;
        &lt;t-button theme=&quot;primary&quot; type=&quot;submit&quot;&gt;提交&lt;/t-button&gt;
      &lt;/t-form-item&gt;
    &lt;/t-form&gt;
  &lt;/div&gt;
&lt;/t-dialog&gt;
&lt;!-- 删除操作弹窗 --&gt;
&lt;t-dialog
  header=&quot;确认删除所选项目?&quot;
  :body=&quot;confirmBody&quot;
  :visible.sync=&quot;confirmVisible&quot;
  @confirm=&quot;onConfirmDelete&quot;
  :onCancel=&quot;onCancel&quot;
&gt;
&lt;/t-dialog&gt;
</code></pre>
  </div>
</template>
<script lang="ts">
import { prefix } from '@/config/global.ts';
import { SearchIcon } from 'tdesign-icons-vue';
import ProjectCard from '@/components/project-card/index.vue';
<p>const INITIAL_DATA = {
name: '',
description: '',
};</p>
<p>export default {
name: 'Projects',
components: {
SearchIcon,
ProjectCard,
},
data() {
return {
pagination: { current: 1, pageSize: 12, total: 0 },
prefix,
projectList: [],
value: 'first',
rowKey: 'index',
tableLayout: 'auto',
verticalAlign: 'top',
bordered: true,
hover: true,
rowClassName: (rowKey) =&gt; <code>${rowKey}-class</code>,
formData: {
project_name: '',
project_description: '',
},
options: [
{ label: '网关', value: '1' },
{ label: '人工智能', value: '2' },
{ label: 'CVM', value: '3' },
],
formVisible: false,
textareaValue: '',
rules: {
project_name: [{ required: true, message: '请输入项目名称', type: 'error' }],
},
searchValue: '',
confirmVisible: false, // 控制确认弹窗
deleteproject: undefined,
dataLoading: false,
};
},
computed: {
sortedProjectList() {
return [...this.projectList].sort((a, b) =&gt; b.ID - a.ID);
},
confirmBody(): string {
const { deleteproject } = this;
return deleteproject ? <code>删除后,${deleteproject.project_name}的所有项目信息将被清空, 且无法恢复</code> : '';
},
},
watch: {
// eslint-disable-next-line func-names
'$route': function(to, from) {
console.log(&quot;route to&quot;, to)
if (to.path.endsWith('/projects')) {
console.log(&quot;to projects&quot;)
this.loadPageData();
}
}
},</p>
<p>mounted() {
console.log(&quot;this is project page&quot;)
this.loadPageData()
},
methods: {
loadPageData() :void {
this.dataLoading = true;
this.$request
.get('/web/projects', {
headers: {
},
withCredentials: true
})
.then((res) =&gt; {
console.log(res)
if (res.status === 200) {
const list = res.data;
console.log(list)
this.projectList = list;
this.pagination = {
...this.pagination,
total: list.length,
};
}
})
.catch((e: Error) =&gt; {
console.log(e);
})
.finally(() =&gt; {
this.dataLoading = false;
});
},
onPageSizeChange(size: number): void {
this.pagination.pageSize = size;
this.pagination.current = 1;
},
onCurrentChange(current: number): void {
this.pagination.current = current;
},
onSubmit({ result, firstError }) {
if (!firstError) {
// this.$message.success('提交成功');
this.formVisible = false;
console.log({
project_name: this.formData.project_name,
description: this.formData.project_description,
});
// 将项目名称和描述发送给服务器进行保存
this.$request
.post('/web/projects', {
project_name: this.formData.project_name,
description: this.formData.project_description,
},{headers: {'Content-Type': 'application/json'}},
{withCredentials: true}
)
.then((res) =&gt; {
if (res.status === 200) {
// 如果服务器返回状态码为 200(成功),则从响应数据中获取保存后的项目信息
const newProject = res.data;
newProject.project_name = this.formData.project_name;
newProject.project_description = this.formData.project_description;
// 添加新项目到项目列表
this.projectList.unshift(newProject);
// 更新当前页的总数量
this.pagination.total++;
}
})
.catch((err) =&gt; {
console.error(err);
this.$message.error('保存失败');
});
} else {
console.log('Errors: ', result);
this.$message.warning(firstError);
}
},
onClickCloseBtn(): void {
this.formVisible = false;
this.formData = {};
},
handleDeleteItem(project): void {
if (!project.ID) {
this.$message.error('项目没有 ID,无法删除');
return;
}
this.confirmVisible = true;
this.deleteproject = project;
},
onConfirmDelete(): void {
// const { index } = this.deleteproject;
// this.projectList.splice(index - 1, 1);
this.confirmVisible = false;
// 向服务器发送删除请求
this.$request
.delete(<code>web/projects/${this.deleteproject.ID}</code>, {
withCredentials: true,
})
.then((res) =&gt; {
if (res.status === 200) {
this.$message.success(this.deleteproject.project_name + '删除成功');
console.log('删除成功');
this.pagination.total--
// 更新项目列表
this.$request
.get('web/projects')
.then((res) =&gt; {
this.projectList = res.data;
})
.catch((err) =&gt; {
console.error(err);
this.$message.error('获取项目列表失败', err);
});
}
})
.catch((err) =&gt; {
console.error(err);
this.$message.error('删除失败', err);
});
},
onCancel(): void {
this.deleteproject = undefined;
this.formData = {};
},
handleManageproject(project) {
this.formVisible = true;
this.formData = { ...project, status: project?.isSetup ? '1' : '0' };
this.projectList.unshift(project);
this.confirmVisible = false;
},
},
};
</script></p>
<style scoped lang="less">
  .list-card-operation {
    display: flex;
    justify-content: space-between;

    .search-input {
      width: 360px;
    }
  }

  .list-card-items {
    margin: 14px 0 24px 0;
    display: flex;
    flex-wrap: wrap;
  }

  .project-card {
    width: 200px;
    height: 200px;
    margin: 8px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .project-card-title {
    font-weight: bold;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .project-card-description {
    margin-top: 8px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
</style>
项目管理平台 - 项目列表

原文地址: https://www.cveoy.top/t/topic/quH8 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录