123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- <template>
- <HeadPanl class="project-detail-header">
- <div class="meta">
- <div class="header">
- <h3>{{ project?.projectName }}</h3>
- <div
- v-if="project?.projectStatus === ProjectStatus.undone"
- class="actions"
- >
- <a-button @click="updateProject">修改项目</a-button>
- <a-button @click="deleteProject">删除项目</a-button>
- <a-button type="primary" @click="finishProject"> 完成项目 </a-button>
- </div>
- </div>
- <div class="body">
- <div class="info">
- <div class="meta">
- <p><span>创建人</span>{{ project?.projectCreater }}</p>
- <p><span>创建时间</span>{{ project?.createTime }}</p>
- <p><span>更新时间</span>{{ project?.updateTime }}</p>
- </div>
- <p class="desc">{{ project?.projectMsg }}</p>
- </div>
- <!-- <Simples :data="simples" /> -->
- </div>
- <a-tabs :active-key="activeTabName" @change="changeTab">
- <a-tab-pane
- v-for="option in tabOptions"
- :key="option.key"
- :tab="option.label"
- />
- </a-tabs>
- </div>
- </HeadPanl>
- <BodyPanl>
- <RouterView v-slot="{ Component }">
- <KeepAlive>
- <component :is="Component" />
- </KeepAlive>
- </RouterView>
- </BodyPanl>
- </template>
- <script setup lang="ts">
- import Simples from '@/components/simples/index.vue'
- import EditProject from './edit.vue'
- import { Modal } from 'ant-design-vue'
- import { HeadPanl, BodyPanl } from '@/layout/panl'
- import { router, RoutesName, routesMetas } from '@/router'
- import { computed, onActivated, onDeactivated, toRef } from 'vue'
- import { useProject, ProjectStatus } from '@/store'
- import { useRealtime } from '@/hook'
- import { renderModal } from '@/helper'
- import { uploadFile } from '@/api'
- const simples = computed(() => [
- { label: '信息', value: 2 },
- { label: '待处理', value: 2 },
- { label: '已解决', value: 2 },
- { label: '未解决', value: 2 },
- { label: '进行中', value: 2 }
- ])
- const tabOptions = [
- // RoutesName.projectMaterial,
- RoutesName.projectScenes,
- RoutesName.projectMembers
- ].map(name => ({
- key: name,
- label: routesMetas[name].title
- }))
- const activeTabName = computed(
- () => router.currentRoute.value.name as RoutesName
- )
- const changeTab = (name: any) => {
- router.replace({ name, params: router.currentRoute.value.params })
- }
- const projectStore = useProject()
- const project = toRef(projectStore.$state, 'current')
- useRealtime(() => {
- const id = Number(router.currentRoute.value.params.id)
- const back = () => router.back()
- if (!id || id < 0) {
- back()
- throw '错误页面'
- }
- return projectStore.setCurrent(id).catch(back)
- })
- let interval: number
- onActivated(() => {
- interval = setInterval(() => {
- const id = Number(router.currentRoute.value.params.id)
- id && projectStore.setCurrent(id)
- }, 1000)
- })
- onDeactivated(() => {
- clearInterval(interval)
- })
- const deleteProject = () => {
- Modal.confirm({
- content: '删除后无法恢复,是否确认?',
- title: '删除项目',
- width: '400px',
- okText: '删除',
- icon: null,
- cancelText: '取消',
- onOk: async () => {
- await projectStore.delete()
- router.replace({ name: RoutesName.projects })
- }
- })
- }
- const finishProject = async () => {
- await projectStore.finish()
- router.replace({ name: RoutesName.projects })
- }
- const updateProject = async () => {
- renderModal(EditProject, {
- project: projectStore.current!,
- async onSave({ projectImg, bimFile, ...data }) {
- const img =
- projectImg && typeof projectImg !== 'string'
- ? await uploadFile(projectImg as File)
- : projectImg
- await projectStore.update({ ...data, projectImg: img })
- }
- })
- }
- </script>
- <style lang="scss" scoped>
- .project-detail-header {
- padding-bottom: 0;
- }
- .header {
- display: flex;
- justify-content: space-between;
- margin-bottom: 24px;
- align-items: center;
- h3 {
- font-size: 20px;
- color: #323233;
- margin: 0;
- }
- .actions button {
- margin-left: 16px;
- }
- }
- .body {
- display: flex;
- justify-content: space-between;
- .meta {
- display: flex;
- margin-bottom: 16px;
- p {
- color: #888888;
- margin-right: 20px;
- margin-bottom: 0;
- span {
- color: #323233;
- margin-right: 3px;
- &::after {
- content: ':';
- }
- }
- }
- }
- .desc {
- flex: 1;
- max-width: 800px;
- padding: 14px 10px;
- background: #fafafa;
- color: #646566;
- line-height: 20px;
- font-size: 14px;
- }
- .tabs {
- margin-top: 16px;
- }
- }
- </style>
- <style lang="scss">
- .project-detail-header .ant-tabs-top > .ant-tabs-nav {
- margin: 0;
- }
- </style>
|