zhangwei
8 天以前 03c275439949875a857538df89a41696642c42b3
'首页公告与详情'
14个文件已修改
4个文件已添加
802 ■■■■ 已修改文件
.env 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/item/shouye.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/modules/home.ts 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/modules/item.ts 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/modules/remaining.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/utils.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/component/myHeader.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/detail.vue 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/index.vue 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/home/utils/hook.tsx 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mine/index.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/newregister/index.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/newregister/utils/hook.tsx 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/aboutItem/form.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/aboutItem/utils/hook.tsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/component/pdfPreview2.vue 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/dept/form.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env
@@ -2,4 +2,4 @@
VITE_PORT = 8848
# 是否隐藏首页 隐藏 true 不隐藏 false (勿删除,VITE_HIDE_HOME只需在.env文件配置)
VITE_HIDE_HOME = false
VITE_HIDE_HOME = true
src/api/item/shouye.ts
New file
@@ -0,0 +1,110 @@
/**首页接口 */
import { http } from "@/utils/http";
import { baseUrlApi } from "../util";
import type { Result } from "../types";
// 获取内容发布详情
export const neirongfabuDetail = params => {
  return http.request<Result>(
    "get",
    baseUrlApi("/api/shouyeGonggao/neirongfabuDetail"),
    {
      params
    }
  );
};
// 获取非政府订单处理详情
export const feizhengfuDetail = params => {
  return http.request<Result>("get", baseUrlApi("/api/shouyeGonggao/detail"), {
    params
  });
};
// 首页查询非政府订单处理
export const shouyeOrder = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/shouyeGonggao/shouyeOrder"),
    {
      data
    }
  );
};
// 首页变更公告
export const shouyeChangeOrder = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/shouyeGonggao/shouyeChangeOrder"),
    {
      data
    }
  );
};
// 首页中标公告
export const shouyeZhongbiaoOrder = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/shouyeGonggao/shouyeZhongbiaoOrder"),
    {
      data
    }
  );
};
// 首页公告信息-招采公告
export const pageGonggao = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/shouyeGonggao/pageGonggao"),
    {
      data
    }
  );
};
// 首页公告信息-更正公告
export const pageGengzgeng = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/shouyeGonggao/pageGengzgeng"),
    {
      data
    }
  );
};
// 首页公告信息-中标公告
export const pageZhongbiaoGonggao = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/shouyeGonggao/pageZhongbiaoGonggao"),
    {
      data
    }
  );
};
// 首页内容发布
export const shouyeNeirongfabu = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/shouyeGonggao/shouyeNeirongfabu"),
    {
      data
    }
  );
};
// 首页咨询中心-内容发布
export const pageNeirongfabu = (data?: object) => {
  return http.request<Result>(
    "post",
    baseUrlApi("/api/shouyeGonggao/pageNeirongfabu"),
    {
      data
    }
  );
};
src/router/index.ts
@@ -107,7 +107,13 @@
/** 路由白名单 */
const whiteList = ["/login"];
const noLoginList = ["/index", "/register", "/registernav", "/registersucess"];
const noLoginList = [
  "/index",
  "/register",
  "/registernav",
  "/registersucess",
  "/gonggaoDetail"
];
// const whiteList = [];
const { VITE_HIDE_HOME } = import.meta.env;
src/router/modules/home.ts
@@ -9,7 +9,8 @@
  meta: {
    icon: "ep/home-filled",
    title: "首页",
    rank: 0
    rank: 0,
    showLink: false
  },
  children: [
    {
src/router/modules/item.ts
@@ -39,26 +39,26 @@
        }
      }
    ]
  },
  {
    path: "/aboutItem",
    meta: {
      title: "关注项目",
      icon: "pajamas:work-item-new"
    },
    children: [
      {
        // path随便写,但前面必须有个 `/`
        path: "/aboutItem",
        // component对应的值前不需要加 / 值对应的是实际业务 `.vue` 或 `.tsx` 代码路径
        component: () => import("@/views/system/aboutItem/index.vue"),
        name: "aboutItem",
        meta: {
          title: "关注项目",
          roles: ["GYS"]
          // showLink:false
        }
      }
    ]
  }
  // {
  //   path: "/aboutItem",
  //   meta: {
  //     title: "关注项目",
  //     icon: "pajamas:work-item-new"
  //   },
  //   children: [
  //     {
  //       // path随便写,但前面必须有个 `/`
  //       path: "/aboutItem",
  //       // component对应的值前不需要加 / 值对应的是实际业务 `.vue` 或 `.tsx` 代码路径
  //       component: () => import("@/views/system/aboutItem/index.vue"),
  //       name: "aboutItem",
  //       meta: {
  //         title: "关注项目",
  //         roles: ["GYS"]
  //         // showLink:false
  //       }
  //     }
  //   ]
  // }
] satisfies Array<RouteConfigsTable>;
src/router/modules/remaining.ts
@@ -22,6 +22,16 @@
    }
  },
  {
    path: "/gonggaoDetail",
    name: "gonggaoDetail",
    component: () => import("@/views/home/detail.vue"),
    meta: {
      title: "公告详情",
      showLink: false,
      rank: 101
    }
  },
  {
    path: "/login",
    name: "Login",
    component: () => import("@/views/login/index.vue"),
src/router/utils.ts
@@ -29,7 +29,7 @@
const quanxianList = ["/item"];
const managerList = ["/user"];
const userInfo = storageLocal().getItem<DataInfo<number>>(userKey);
// const userInfo = storageLocal().getItem<DataInfo<number>>(userKey);
// 动态路由
import { getAsyncRoutes } from "@/api/routes";
src/views/home/component/myHeader.vue
@@ -24,6 +24,9 @@
      </div>
    </div>
  </div>
  <div class="banner">
    <!-- <img width="100%" height="306px" src="@/assets/home/banner.png" alt="" /> -->
  </div>
</template>
<style lang="scss" scoped>
@@ -60,4 +63,13 @@
    }
  }
}
.banner {
  //   left: -3.76px;
  //   top: 80px;
  //   position: absolute;
  background: url("@/assets/home/banner.png") no-repeat left center;
  background-size: cover;
  width: 100%;
  height: 306px;
}
</style>
src/views/home/detail.vue
New file
@@ -0,0 +1,193 @@
<script setup lang="ts">
import { onMounted, reactive, ref, h } from "vue";
import MyHeader from "./component/myHeader.vue";
import MyFooter from "./component/myFooter.vue";
import { useIndex } from "../home/utils/hook";
import { message } from "@/utils/message";
import pdfPreview from "@/views/system/component/pdfPreview.vue";
import { deviceDetection } from "@pureadmin/utils";
import { addDialog } from "@/components/ReDialog";
const { getNeirongfabuDetail, route, router, getFeizhengfuDetail, stateHook } =
  useIndex();
import { ArrowRight } from "@element-plus/icons-vue";
import MaterialIconThemePdf from "~icons/material-icon-theme/pdf";
import MaterialIconThemeImage from "~icons/material-icon-theme/image";
import MaterialIconThemeWord from "~icons/material-icon-theme/word";
import MaterialIconThemeTable from "~icons/material-icon-theme/table";
import MaterialIconThemeZip from "~icons/material-icon-theme/zip";
const previewPdf = pdfUrl => {
  switch (pdfUrl.fileType) {
    case "png":
      showImg(pdfUrl.filePath);
      break;
    case "jepg":
      showImg(pdfUrl.filePath);
      break;
    case "pdf":
      addDialog({
        title: `预览pdf`,
        props: {},
        width: "60%",
        draggable: true,
        fullscreen: deviceDetection(),
        fullscreenIcon: true,
        sureBtnLoading: true,
        closeOnClickModal: false,
        contentRenderer: () => h(pdfPreview, { fileInfo: pdfUrl })
        // jsx 语法 (注意在.vue文件启用jsx语法,需要在script开启lang="tsx")
      });
      break;
    default:
      window.location.href = pdfUrl.filePath;
      message("正在下载!");
      break;
  }
};
const showPreview = ref(false);
const state = reactive({
  srcList: []
});
const showImg = (name: string | number) => {
  showPreview.value = true;
  state.srcList = [name];
};
onMounted(() => {
  console.log(route);
  const value = route.query;
  getFeizhengfuDetail(value);
});
defineOptions({
  name: "gonggaoDetail"
});
</script>
<template>
  <div class="bg-[#f5f5f5] min-h-[100%]">
    <my-header />
    <div class="w-[80%] m-auto p-5">
      <div class="h=[52px] w-[100%] bg-white p-2 pl-4 flex items-center">
        <span class="text-sm">您的当前位置:</span>
        <el-breadcrumb :separator-icon="ArrowRight">
          <el-breadcrumb-item :to="{ path: '/index' }" replace>
            首页
          </el-breadcrumb-item>
          <el-breadcrumb-item>{{ route.meta.title }}</el-breadcrumb-item>
        </el-breadcrumb>
      </div>
      <div class="bg-white w-[100%] p-4 mt-7">
        <h3 class="text-center p-4 text-2xl">
          {{ stateHook.gonggaoDetail.projectName }}
        </h3>
        <div class="w-[95%] m-auto pt-1 pb-1">
          <div class="bg-[#edf1f4] w-[100%] m-auto text-center pt-1 pb-1">
            【信息发布主体:
            {{ stateHook.gonggaoDetail.caigourenmingcheng }}
            】 【发布时间:<span class="text-red-500">{{
              stateHook.gonggaoDetail.createTime
            }}</span
            >】
          </div>
          <div class="mt-3">
            <span class="text-xl">一、项目基本情况</span>
            <div>
              <p>项目编号:{{ stateHook.gonggaoDetail.projectCode }}</p>
              <p>采购方式:{{ stateHook.gonggaoDetail.caigoufangshiName }}</p>
              <p>预算金额:{{ stateHook.gonggaoDetail.caigouyusuan }}元</p>
              <p>联合体投标:{{ stateHook.gonggaoDetail.lianhetitoubiao }}</p>
              <p>
                投标报名开始时间:{{ stateHook.gonggaoDetail.toubiaoStartDate }}
              </p>
              <p>
                投标报名截止时间:{{ stateHook.gonggaoDetail.toubiaoEndDate }}
              </p>
              <p>开标时间:{{ stateHook.gonggaoDetail.kaibiaoDate }}</p>
              <p
                class="flex items-center cursor-pointer"
                @click="
                  previewPdf({
                    name: stateHook.gonggaoDetail.zhaobiaowenjianName,
                    filePath: stateHook.gonggaoDetail.zhaobiaowenjian,
                    fileType: 'pdf'
                  })
                "
              >
                招标文件:<MaterialIconThemePdf style="font-size: 1.5em" />{{
                  stateHook.gonggaoDetail.zhaobiaowenjianName
                }}
              </p>
              <div v-if="stateHook.gonggaoDetail.fujian" class="flex">
                附件:
                <div>
                  <p
                    v-for="item in stateHook.gonggaoDetail.fujianList"
                    :key="item.src"
                    class="flex items-center cursor-pointer"
                    @click="previewPdf(item)"
                  >
                    <MaterialIconThemeImage
                      v-if="item.fileType == 'png' || item.fileType == 'jepg'"
                      style="font-size: 1.5em"
                    />
                    <MaterialIconThemePdf
                      v-else-if="item.fileType == 'pdf'"
                      style="font-size: 1.5em"
                    />
                    <MaterialIconThemeTable
                      v-else-if="item.fileType == 'xlsx'"
                      style="font-size: 1.5em"
                    />
                    <MaterialIconThemeWord
                      v-else-if="
                        item.fileType == 'doc' || item.fileType == 'docx'
                      "
                      style="font-size: 1.5em"
                    />
                    <MaterialIconThemeZip v-else style="font-size: 1.5em" />
                    {{ item.name }}
                  </p>
                </div>
              </div>
            </div>
          </div>
          <div v-if="stateHook.gonggaoDetail?.changeOrder" class="mt-3">
            <span class="text-xl">二、变更公告</span>
            <div>
              <p>
                变更名称:{{ stateHook.gonggaoDetail.changeOrder?.projectName }}
              </p>
              <p
                v-if="stateHook.gonggaoDetail?.changeOrder"
                class="flex items-center cursor-pointer"
                @click="
                  previewPdf({
                    name: stateHook.gonggaoDetail.changeOrder
                      .biangengwenjianName,
                    filePath:
                      stateHook.gonggaoDetail.changeOrder.biangengwenjian,
                    fileType: 'pdf'
                  })
                "
              >
                变更公告:
                <MaterialIconThemePdf style="font-size: 1.5em" />
                {{ stateHook.gonggaoDetail.changeOrder.biangengwenjianName }}
              </p>
            </div>
          </div>
        </div>
      </div>
    </div>
    <my-footer />
  </div>
  <el-image-viewer
    v-if="showPreview"
    :url-list="state.srcList"
    show-progress
    @close="showPreview = false"
  />
</template>
<style lang="scss" scoped></style>
src/views/home/index.vue
@@ -1,88 +1,43 @@
el
<template>
  <my-header />
  <div class="banner">
    <!-- <img width="100%" height="306px" src="@/assets/home/banner.png" alt="" /> -->
  </div>
  <div class="notice">
    <div class="left">
      <div class="item item1">
        <img src="@/assets/home/notice1.png" alt="" />
        <div>招采公告</div>
      </div>
      <div class="item">
        <img src="@/assets/home/notice.png" alt="" />
        <div>更正公告</div>
      </div>
      <div class="item">
        <img src="@/assets/home/notice.png" alt="" />
        <div>结果公告</div>
      </div>
      <div class="item">
        <img src="@/assets/home/notice.png" alt="" />
        <div>其他公告</div>
      <div
        v-for="(item, index) in state.gonggaoList"
        :key="index"
        :class="['item', stateHook.active == index ? 'item1' : '']"
        @click="getShouyeOrder(index)"
      >
        <img
          v-if="stateHook.active == index"
          src="@/assets/home/notice1.png"
          alt=""
        />
        <img v-else src="@/assets/home/notice.png" alt="" />
        <div>{{ item.name }}</div>
      </div>
    </div>
    <div class="right">
      <!-- <el-tabs v-model="activeName" class="demo-tabs">
        <el-tab-pane label="意向公开" name="first">
          意向公开 -->
      <div class="item">
        <span
          ><span style="color: #145ccd; font-weight: 600">·</span
          >【四川省成都市】2024年石盘街道付家祠村粮油产业园区及配套基础设施建设项目磋商公告</span
        >
        <span>2024-04-15 18:10</span>
      <div
        v-for="item in stateHook.shouyeOrderList"
        :key="item.id"
        class="item"
        @click="goDetail(item.tenderId ?? item.id)"
      >
        <span>
          <span style="color: #145ccd; font-weight: 600">·</span>
          {{
            item.xingzhengquyuName &&
            `【${item.xingzhengquyuName.match(/^.*?市/)}】`
          }}
          {{ item.projectName }}
        </span>
        <span>{{ item.createTime }}</span>
      </div>
      <div class="item">
        <span
          ><span style="color: #145ccd; font-weight: 600">·</span
          >【四川省成都市】熊猫谷游客中心局部改造项目磋商公告</span
        >
        <span>2024-04-15 18:10</span>
      </div>
      <div class="item">
        <span
          ><span style="color: #145ccd; font-weight: 600">·</span
          >【四川省成都市】丹景街道民湖社区红白喜事服务场所磋商公告</span
        >
        <span>2024-04-15 18:10</span>
      </div>
      <div class="item">
        <span
          ><span style="color: #145ccd; font-weight: 600">·</span
          >【四川省成都市】成都东部新区三岔湖高级中学体艺中心前临时停车区和正校门两侧门卫室间区域黑化及排水提升解除内涝项目磋商公告</span
        >
        <span>2024-04-15 18:10</span>
      </div>
      <div class="item">
        <span
          ><span style="color: #145ccd; font-weight: 600">·</span
          >【四川省成都市】四川省成都戒毒康复所病残戒毒人员康复活动中心维修改造项目第二次磋商公告</span
        >
        <span>2024-04-15 18:10</span>
      </div>
      <div class="item">
        <span
          ><span style="color: #145ccd; font-weight: 600">·</span
          >【四川省成都市】老干部活动中心装修改造项目磋商公告</span
        >
        <span>2024-04-15 18:10</span>
      </div>
      <div class="item">
        <span
          ><span style="color: #145ccd; font-weight: 600">·</span
          >【四川省成都市】金牛区抢险救灾工程项目工程队伍储备库(房建、市政类)招标公告</span
        >
        <span>2024-04-15 18:10</span>
      </div>
      <div class="item">
        <span
          ><span style="color: #145ccd; font-weight: 600">·</span
          >【四川省成都市】金牛区抢险救灾工程项目工程队伍储备库(房建、市政类)招标公告</span
        >
        <span>2024-04-15 18:10</span>
      </div>
      <!-- </el-tab-pane>
        <el-tab-pane label="工程招标" name="second">工程招标</el-tab-pane>
        <el-tab-pane label="货物招标" name="third">货物招标</el-tab-pane>
@@ -386,6 +341,7 @@
import { exRole } from "@/api/register/index";
import { storageLocal, isString, isIncludeAllChildren } from "@pureadmin/utils";
import { initRouter, getTopMenu } from "@/router/utils";
import { useIndex } from "../home/utils/hook";
import { getToken } from "@/utils/auth";
import { useRoute, useRouter } from "vue-router";
@@ -398,6 +354,7 @@
import type { RoleItem } from "@/api/types";
const userStore = useUserStore();
const { stateHook, getShouyeOrder, goDetail } = useIndex();
// 访问 state 属性
// console.log(userStore.roles,'-'); // 直接获取值
@@ -416,12 +373,19 @@
  roleList: [],
  rolesCode: [],
  userInfo: {} as userType,
  accessToken: ""
  accessToken: "",
  gonggaoList: [
    { name: "招采公告" },
    { name: "更正公告" },
    { name: "结果公告" }
    // { name: "其他公告" }
  ]
});
onMounted(() => {
  // exRole().then(res => {
  //   state.roleList = res.result;
  // });
  getShouyeOrder(0);
  state.roleList = useUserStoreHook().rolesList;
  getUseRoles();
  state.accessToken = getToken()?.accessToken;
@@ -441,7 +405,7 @@
  addDialog({
    width: "20%",
    title: "确认信息",
    contentRenderer: () => <p>是否申请为{item.name}!</p>, // jsx 语法 (注意在.vue文件启用jsx语法,需要在script开启lang="tsx")
    contentRenderer: () => <p>是否申请为{item.name}!</p>, // jsx 语法 (注意在.vue文件启用jsx语法,需要在script开启lang="tsx")
    closeCallBack: ({ options, args }) => {
      if (args?.command === "cancel") {
        // 您点击了取消按钮
@@ -463,14 +427,17 @@
const toWelcome = async item => {
  // if (useUserStoreHook().nowRole.code !== item.code) {
  // 获取后端路由
  initRouter().then(() => {
    console.log("hhhh");
    useUserStoreHook().changeLogoInExRule({
  useUserStoreHook()
    .changeLogoInExRule({
      ruleCode: item.code
    })
    .then(res => {
      initRouter().then(() => {
        let path = getTopMenu(true);
        router.push({ name: path.name });
      });
    });
    router.push({ name: "Welcome" });
  });
  // }
};
// 去登录
@@ -480,32 +447,26 @@
</script>
<style lang="scss" scoped>
.banner {
  //   left: -3.76px;
  //   top: 80px;
  //   position: absolute;
  background: url("@/assets/home/banner.png") no-repeat left center;
  background-size: cover;
  width: 100%;
  height: 306px;
}
.notice {
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  width: 72%;
  height: 518px;
  height: 400px;
  padding: 15px;
  margin: 20px auto;
  background: rgb(254, 254, 254);
  border-radius: 8px;
  box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
  box-shadow:
    rgba(149, 157, 165, 0.15) 0px -6px 18px,
    rgba(149, 157, 165, 0.2) 0px 8px 24px;
  .left {
    width: 10%;
    height: 483px;
    height: 100%;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    justify-content: space-around;
    align-content: space-between;
    .item {
      width: 137px;
      height: 111px;
@@ -548,12 +509,12 @@
      padding: 0 10px;
    }
    /* 偶数行背景色 */
    .item:nth-child(even) {
    .item:nth-child(odd) {
      background: rgb(244, 244, 244);
      border-radius: 4px;
    }
    /* 奇数行背景色 */
    .item:nth-child(odd) {
    .item:nth-child(even) {
      padding: 8px;
      background-color: #fff;
    }
src/views/home/utils/hook.tsx
New file
@@ -0,0 +1,115 @@
import { onMounted, reactive } from "vue";
import { useRoute, useRouter } from "vue-router";
import {
  pageGonggao,
  pageGengzgeng,
  shouyeZhongbiaoOrder,
  neirongfabuDetail,
  shouyeOrder,
  shouyeChangeOrder,
  feizhengfuDetail
} from "@/api/item/shouye";
const convertFujianToObjects = (fujianStr, fujianNameStr) => {
  // 分割字符串为数组并过滤空值
  const srcArray = fujianStr.split(",").filter(Boolean);
  const nameArray = fujianNameStr.split(",").filter(Boolean);
  // 提取文件后缀作为valu
  const getFileExtension = fileName => {
    const lastDotIndex = fileName.lastIndexOf(".");
    // 如果没有后缀或文件名以点结尾,返回空字符串
    if (lastDotIndex === -1 || lastDotIndex === fileName.length - 1) {
      return "";
    }
    return fileName.slice(lastDotIndex + 1).toLowerCase();
  };
  // 映射为目标对象数组
  return srcArray.map((src, index) => {
    // 确保名称数组有对应索引的元素
    const name = nameArray[index]?.trim() || `未知文件${index + 1}`;
    return {
      name: name,
      filePath: src.trim(),
      fileType: getFileExtension(name)
    };
  });
};
export function useIndex() {
  const route = useRoute();
  const router = useRouter();
  const stateHook = reactive({
    pageGonggaoList: [],
    shouyeZhongbiaoOrderList: [],
    shouyeOrderList: [],
    active: 0,
    gonggaoDetail: {}
  });
  async function getPageGonggao() {
    const res = await pageGonggao();
    stateHook.pageGonggaoList = res.result;
  }
  async function getPageGengzgeng() {
    const res = await pageGengzgeng();
    stateHook.pageGonggaoList = res.result;
  }
  async function getShouyeZhongbiaoOrder() {
    const res = await shouyeZhongbiaoOrder();
    stateHook.shouyeZhongbiaoOrderList = res.result;
  }
  async function getNeirongfabuDetail(data) {
    const res = await neirongfabuDetail(data);
    stateHook.pageGonggaoList = res.result;
  }
  async function getFeizhengfuDetail(params) {
    const res = await feizhengfuDetail(params);
    stateHook.gonggaoDetail = res.result;
    stateHook.gonggaoDetail.fujianList = convertFujianToObjects(
      stateHook.gonggaoDetail.fujian,
      stateHook.gonggaoDetail.fujianName
    );
  }
  async function getShouyeOrder(active) {
    let res;
    stateHook.active = active;
    switch (active) {
      case 0:
        res = await shouyeOrder();
        stateHook.shouyeOrderList = res.result;
        break;
      case 1:
        res = await getShouyeChangeOrder();
        stateHook.shouyeOrderList = res.result;
        break;
      case 2:
        res = await shouyeZhongbiaoOrder();
        stateHook.shouyeOrderList = res.result;
        break;
    }
  }
  async function getShouyeChangeOrder() {
    const res = await shouyeChangeOrder();
    stateHook.shouyeOrderList = res.result;
  }
  function goDetail(id) {
    router.push({ name: "gonggaoDetail", query: { id } });
  }
  onMounted(() => {
    console.log("---");
    // getNeirongfabuDetail();
    // getPageGonggao();
    // getPageGengzgeng();
    // getShouyeZhongbiaoOrder();
  });
  return {
    stateHook,
    getPageGonggao,
    getShouyeOrder,
    getNeirongfabuDetail,
    goDetail,
    route,
    router,
    getFeizhengfuDetail
  };
}
src/views/mine/index.vue
@@ -180,13 +180,13 @@
        message: "请输入正确的手机号码",
        trigger: "blur"
      }
    ],
    bankName: [
      { required: true, message: "请输入企业开户行", trigger: "blur" }
    ],
    bankAccount: [
      { required: true, message: "请输入企业银行账号", trigger: "blur" }
    ]
    // bankName: [
    //   { required: true, message: "请输入企业开户行", trigger: "blur" }
    // ],
    // bankAccount: [
    //   { required: true, message: "请输入企业银行账号", trigger: "blur" }
    // ]
  },
  loading: {
    signIn: false
src/views/newregister/index.vue
@@ -412,7 +412,9 @@
            </el-form-item>
            <el-form-item label=" ">
              <span>已有账号?</span>
              <el-link type="primary" :underline="false">立即登录</el-link>
              <el-link type="primary" :underline="false" @click="toLogin"
                >立即登录</el-link
              >
            </el-form-item>
          </el-form>
        </div>
@@ -441,7 +443,8 @@
  handlebankAccountIMG,
  isLoading,
  uploadSFZ,
  openAgreement
  openAgreement,
  toLogin
} = useRegister();
defineOptions({
src/views/newregister/utils/hook.tsx
@@ -533,6 +533,10 @@
      }
    });
  }
  // 去登录
  function toLogin() {
    router.push({ name: "Login" });
  }
  return {
    state,
    resetForm,
@@ -549,6 +553,7 @@
    handleAvatarSuccess,
    loadNode,
    handlebankAccountIMG,
    openAgreement
    openAgreement,
    toLogin
  };
}
src/views/system/aboutItem/form.vue
@@ -9,6 +9,7 @@
import { getCaigoufangshiList } from "@/api/item/index";
const { state } = useDept();
let cascaderRef = ref();
const props = withDefaults(defineProps<FormProps>(), {
  formInline: () => ({
    id: "",
@@ -54,7 +55,11 @@
  return ruleFormRef.value;
}
const handleChange = value => {
  console.log(value);
  console.log(
    value,
    cascaderRef.value.getCheckedNodes()[0].pathLabels.join(" / "),
    123
  );
};
defineExpose({ getRef });
onMounted(async () => {});
@@ -229,6 +234,7 @@
      <re-col :value="6" :xs="24" :sm="24">
        <el-form-item label="行政区域" prop="xingzhengquyu">
          <el-cascader
            :ref="cascaderRef"
            v-model="newFormInline.xingzhengquyu"
            class="w-full"
            :options="state.regionList"
src/views/system/aboutItem/utils/hook.tsx
@@ -11,7 +11,7 @@
const selectedNum = ref(0);
export function useDept(tableRef: Ref) {
export function useDept(tableRef?: Ref) {
  const form = reactive({
    // 新增日期范围,可为 null,类型为数组
    createDateRange: null,
src/views/system/component/pdfPreview2.vue
New file
@@ -0,0 +1,89 @@
<template>
  <div v-loading="loading" class="wrap">
    <vue-office-docx
      v-if="fileInfo.fileType === 'docx' || fileInfo.fileType === 'doc'"
      :src="fileInfo.filePath"
      style="height: 100%"
      @rendered="rendered"
      @error="HandlError"
    />
    <vue-office-pdf
      v-if="fileInfo.fileType === 'pdf'"
      :src="fileInfo.filePath"
      style="height: 100%"
      @rendered="rendered"
      @error="HandlError"
    />
    <vue-office-excel
      v-if="fileInfo.fileType === 'xlsx'"
      :src="fileInfo.filePath"
      style="height: 78vh"
      @rendered="rendered"
      @error="HandlError"
    />
    <el-image
      v-if="fileInfo.fileType === 'image'"
      :src="fileInfo.filePath"
      alt="Preview"
      @load="rendered"
      @error="HandlError"
    />
    <video
      v-if="fileInfo.fileType === 'video' && fileInfo.filePath"
      width="100%"
      controls
      controlslist="nodownload"
    >
      <!-- /** controlslist="nodownload" 隐藏下载按钮 */ -->
      <source :src="fileInfo.filePath" />
      Download the
      <a :href="fileInfo.filePath">MP4</a>
    </video>
    <audio
      v-if="fileInfo.fileType === 'audio' && fileInfo.filePath"
      controls
      controlsList="nodownload"
      style="width: 100%"
    >
      <source :src="fileInfo.filePath" type="audio/mp3" />
      您的浏览器不支持audio标签。
    </audio>
  </div>
</template>
<script setup>
import { onMounted, ref } from "vue";
//引入VueOfficeDocx组件 相关样式
// import VueOfficeDocx from "@vue-office/docx/lib/v3/vue-office-docx.mjs";
// import VueOfficeExcel from "@vue-office/excel/lib/v3/vue-office-excel.mjs";
// import VueOfficePdf from "@vue-office/pdf/lib/v3/vue-office-pdf.mjs";
//引入相关样式
// import "@vue-office/docx/lib/v3/index.css";
// import "@vue-office/excel/lib/v3/index.css";
const props = defineProps({
  fileInfo: {
    type: Object,
    required: true
  }
});
const loading = ref(true);
/** rendered:渲染完成后调用 */
const rendered = () => {
  loading.value = false;
};
/** HandlError :渲染失败后调用 */
const HandlError = errorInfo => {
  // 假设你已经配置了全局的 toast
  alert("该文件暂不支持在线预览");
  loading.value = false;
};
onMounted(() => {
  console.log(props.fileInfo);
});
</script>
src/views/system/dept/form.vue
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { onMounted, ref, reactive } from "vue";
import { onMounted, ref, reactive, computed } from "vue";
import ReCol from "@/components/ReCol";
import { formRules } from "./utils/rule";
import { FormProps } from "./utils/types";
@@ -9,6 +9,27 @@
import { getCaigoufangshiList } from "@/api/item/index";
const { state, nowRole } = useDept(ref({}));
// 递归查找label的函数
const findLabelsByValues = (values, options, currentLabels = []) => {
  if (!values.length || !options) return currentLabels;
  const [firstValue, ...restValues] = values;
  const matched = options.find(item => item.code === firstValue);
  if (matched) {
    currentLabels.push(matched.name);
    // 继续查找下一级
    return findLabelsByValues(restValues, matched.regions, currentLabels);
  }
  return currentLabels;
};
// 计算属性:根据selectedValue动态获取label
const selectedLabels = computed(() => {
  return findLabelsByValues(
    newFormInline.value.xingzhengquyu,
    state.regionList
  ).join("");
});
const props = withDefaults(defineProps<FormProps>(), {
  formInline: () => ({
    id: "",
@@ -55,7 +76,7 @@
  return ruleFormRef.value;
}
const handleChange = value => {
  console.log(value);
  newFormInline.value.xingzhengquyuName = selectedLabels.value;
};
const selectChange = value => {
  let obj = state.caigoufangshiList.find(item => {