3f3d35d6d6445f9cc90a8cf7bb496bee7f465542..25975d7ec42b1691512ff6f29041bd3bd1a4a1e3
昨天 spring
fix: 消息通知接口联调,页面跳转
25975d 对比 | 目录
昨天 spring
fix: 完成消息通知
3960a1 对比 | 目录
已修改7个文件
237 ■■■■ 文件已修改
src/api/system/message.js 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/Navbar.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/components/NotificationCenter/index.vue 69 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/customerFile/index.vue 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/supplierManage/components/BlacklistTab.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/supplierManage/components/HomeTab.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/approvalProcess/index.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/message.js
@@ -3,42 +3,43 @@
// 查询消息通知列表
export function listMessage(query) {
  return request({
    url: "/system/message/list",
    url: "/system/notice/list",
    method: "get",
    params: query,
  });
}
// 查询未读消息数量
export function getUnreadCount() {
export function getUnreadCount(consigneeId) {
  return request({
    url: "/system/message/unreadCount",
    url: "/system/notice/getCount",
    method: "get",
    params: { consigneeId },
  });
}
// 标记消息为已读
export function markAsRead(messageId) {
export function markAsRead(noticeId, status) {
  return request({
    url: "/system/message/markAsRead",
    method: "post",
    data: { messageId },
    url: "/system/notice",
    method: "put",
    data: { noticeId, status },
  });
}
// 一键标记所有消息为已读
export function markAllAsRead() {
  return request({
    url: "/system/message/markAllAsRead",
    url: "/system/notice/markAllAsRead",
    method: "post",
  });
}
// 确认消息
export function confirmMessage(messageId) {
export function confirmMessage(noticeId, status) {
  return request({
    url: "/system/message/confirm",
    method: "post",
    data: { messageId },
    url: "/system/notice",
    method: "put",
    data: { noticeId, status },
  });
}
src/layout/components/Navbar.vue
@@ -344,6 +344,7 @@
    }
  }
}
</style>
<style lang="scss">
@@ -358,4 +359,7 @@
    padding: 0 !important;
  }
}
.el-badge__content.is-fixed{
  top: 12px;
}
</style>
src/layout/components/NotificationCenter/index.vue
@@ -25,12 +25,12 @@
                </el-icon>
              </div>
              <div class="notification-content-wrapper">
                <div class="notification-title">{{ item.title }}</div>
                <div class="notification-detail">{{ item.content }}</div>
                <div class="notification-title">{{ item.noticeTitle }}</div>
                <div class="notification-detail">{{ item.noticeContent }}</div>
                <div class="notification-time">{{ item.createTime }}</div>
              </div>
              <div class="notification-action">
                <el-button type="primary" size="small" @click="handleConfirm(item.id)">
                <el-button type="primary" size="small" @click="handleConfirm(item)">
                  确认
                </el-button>
              </div>
@@ -53,8 +53,8 @@
                </el-icon>
              </div>
              <div class="notification-content-wrapper">
                <div class="notification-title">{{ item.title }}</div>
                <div class="notification-detail">{{ item.content }}</div>
                <div class="notification-title">{{ item.noticeTitle }}</div>
                <div class="notification-detail">{{ item.noticeContent }}</div>
                <div class="notification-time">{{ item.createTime }}</div>
              </div>
            </div>
@@ -82,7 +82,11 @@
import { Bell } from '@element-plus/icons-vue'
import { listMessage, markAsRead, markAllAsRead, confirmMessage, getUnreadCount } from '@/api/system/message'
import { ElMessage } from 'element-plus'
import useUserStore from '@/store/modules/user'
import { useRouter } from 'vue-router'
const userStore = useUserStore()
const router = useRouter()
const emit = defineEmits(['unreadCountChange'])
const activeTab = ref('unread')
@@ -96,19 +100,25 @@
// 加载消息列表
const loadMessages = async () => {
  try {
    const consigneeId = userStore.id
    if (!consigneeId) {
      console.warn('未获取到当前登录用户ID')
      return
    }
    const params = {
      consigneeId: consigneeId,
      pageNum: pageNum.value,
      pageSize: pageSize.value,
      isRead: activeTab.value === 'read' ? 1 : 0
      status: activeTab.value === 'read' ? 1 : 0
    }
    const res = await listMessage(params)
    if (res.code === 200) {
      if (activeTab.value === 'unread') {
        unreadList.value = res.rows || []
        unreadList.value = res.data.records || []
      } else {
        readList.value = res.rows || []
        readList.value = res.data.records || []
      }
      total.value = res.total || 0
      total.value = res.data.total || 0
    }
  } catch (error) {
    console.error('加载消息列表失败:', error)
@@ -118,7 +128,12 @@
// 加载未读数量
const loadUnreadCount = async () => {
  try {
    const res = await getUnreadCount()
    const consigneeId = userStore.id
    if (!consigneeId) {
      console.warn('未获取到当前登录用户ID')
      return
    }
    const res = await getUnreadCount(consigneeId)
    if (res.code === 200) {
      unreadCount.value = res.data || 0
      emit('unreadCountChange', unreadCount.value)
@@ -135,16 +150,42 @@
}
// 确认消息
const handleConfirm = async (messageId) => {
const handleConfirm = async (item) => {
  try {
    const res = await confirmMessage(messageId)
    console.log('item', item)
    const res = await confirmMessage(item.noticeId, 1)
    if (res.code === 200) {
      ElMessage.success('确认成功')
      // 标记为已读
      await markAsRead(messageId)
      // 重新加载数据
      loadMessages()
      loadUnreadCount()
      // 根据 jumpPath 进行页面跳转
      if (item.jumpPath) {
        try {
          // 解析 jumpPath,分离路径和查询参数
          const [path, queryString] = item.jumpPath.split('?')
          let query = {}
          if (queryString) {
            // 解析查询参数
            queryString.split('&').forEach(param => {
              const [key, value] = param.split('=')
              if (key && value) {
                query[key] = decodeURIComponent(value)
              }
            })
          }
          // 跳转到指定页面
          router.push({
            path: path,
            query: query
          })
        } catch (error) {
          console.error('页面跳转失败:', error)
        }
      }
    }
  } catch (error) {
    console.error('确认消息失败:', error)
src/views/basicData/customerFile/index.vue
@@ -47,14 +47,11 @@
        @pagination="pagination"
      ></PIMTable>
    </div>
    <FormDialog
    <el-dialog
      v-model="dialogFormVisible"
      :title="(type) => type === 'add' ? '新增客户信息' : '编辑客户信息'"
      :operation-type="operationType"
      :title="operationType === 'add' ? '新增客户信息' : '编辑客户信息'"
      width="70%"
      @close="closeDia"
      @confirm="submitForm"
      @cancel="closeDia"
    >
      <el-form
        :model="form"
@@ -196,31 +193,63 @@
          </el-col>
        </el-row>
      </el-form>
    </FormDialog>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 用户导入对话框 -->
    <ImportDialog
      ref="importDialogRef"
      v-model="upload.open"
    <el-dialog
      :title="upload.title"
      v-model="upload.open"
      width="400px"
      :action="upload.url"
      :headers="upload.headers"
      :disabled="upload.isUploading"
      :before-upload="upload.beforeUpload"
      :on-progress="upload.onProgress"
      :on-success="upload.onSuccess"
      :on-error="upload.onError"
      :on-change="upload.onChange"
      @confirm="submitFileForm"
      @cancel="handleImportCancel"
      @download-template="importTemplate"
    />
      append-to-body
    >
      <el-upload
        ref="uploadRef"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="upload.headers"
        :action="upload.url + '?updateSupport=' + upload.updateSupport"
        :disabled="upload.isUploading"
        :before-upload="upload.beforeUpload"
        :on-progress="upload.onProgress"
        :on-success="upload.onSuccess"
        :on-error="upload.onError"
        :on-change="upload.onChange"
        :auto-upload="false"
        drag
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <template #tip>
          <div class="el-upload__tip text-center">
            <span>仅允许导入xls、xlsx格式文件。</span>
            <el-link
              type="primary"
              :underline="false"
              style="font-size: 12px; vertical-align: baseline"
              @click="importTemplate"
              >下载模板</el-link
            >
          </div>
        </template>
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitFileForm">确 定</el-button>
          <el-button @click="upload.open = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import { Search, Close } from "@element-plus/icons-vue";
import { Search } from "@element-plus/icons-vue";
import {
  addCustomer,
  delCustomer,
@@ -232,9 +261,6 @@
import { userListNoPage } from "@/api/system/user.js";
import useUserStore from "@/store/modules/user";
import { getToken } from "@/utils/auth.js";
import { getCurrentDate } from "@/utils/index.js";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import ImportDialog from "@/components/Dialog/ImportDialog.vue";
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
@@ -312,7 +338,6 @@
const selectedRows = ref([]);
const userList = ref([]);
const tableLoading = ref(false);
const importDialogRef = ref(null);
const page = reactive({
  current: 1,
  size: 100,
@@ -401,9 +426,7 @@
    if(response.code === 200){
      proxy.$modal.msgSuccess("文件上传成功");
      upload.open = false;
      if (importDialogRef.value) {
        importDialogRef.value.clearFiles();
      }
      proxy.$refs["uploadRef"].clearFiles();
      getList();
    }else if(response.code === 500){
      proxy.$modal.msgError(response.msg);
@@ -461,13 +484,7 @@
/** 提交上传文件 */
function submitFileForm() {
  upload.isUploading = true;
  if (importDialogRef.value) {
    importDialogRef.value.submit();
  }
}
/** 取消导入 */
function handleImportCancel() {
  upload.open = false;
  proxy.$refs["uploadRef"].submit();
}
/** 导入按钮操作 */
function handleImport() {
@@ -597,6 +614,15 @@
    });
};
// 获取当前日期并格式化为 YYYY-MM-DD
function getCurrentDate() {
  const today = new Date();
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, "0"); // 月份从0开始
  const day = String(today.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
}
onMounted(() => {
    getList();
});
src/views/basicData/supplierManage/components/BlacklistTab.vue
@@ -240,7 +240,6 @@
import useUserStore from "@/store/modules/user";
import { getToken } from "@/utils/auth.js";
import FilesDia from "../filesDia.vue";
import { getCurrentDate } from "@/utils/index.js";
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
@@ -542,6 +541,14 @@
      });
};
// 获取当前日期并格式化为 YYYY-MM-DD
function getCurrentDate() {
  const today = new Date();
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, "0"); // 月份从0开始
  const day = String(today.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
}
// 打开附件弹框
const openFilesFormDia = (row) => {
  nextTick(() => {
src/views/basicData/supplierManage/components/HomeTab.vue
@@ -246,7 +246,6 @@
import useUserStore from "@/store/modules/user";
import { getToken } from "@/utils/auth.js";
import FilesDia from "../filesDia.vue";
import { getCurrentDate } from "@/utils/index.js";
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
@@ -548,6 +547,14 @@
      });
};
// 获取当前日期并格式化为 YYYY-MM-DD
function getCurrentDate() {
  const today = new Date();
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, "0"); // 月份从0开始
  const day = String(today.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
}
// 打开附件弹框
const openFilesFormDia = (row) => {
  nextTick(() => {
src/views/collaborativeApproval/approvalProcess/index.vue
@@ -7,6 +7,8 @@
      <el-tab-pane label="出差管理" name="3"></el-tab-pane>
      <el-tab-pane label="报销管理" name="4"></el-tab-pane>
      <el-tab-pane label="采购审批" name="5"></el-tab-pane>
      <el-tab-pane label="报价审批" name="6"></el-tab-pane>
      <el-tab-pane label="出库审批" name="7"></el-tab-pane>
    </el-tabs>
    
    <div class="search_form">
@@ -62,12 +64,14 @@
import { Search } from "@element-plus/icons-vue";
import {onMounted, ref, computed, reactive, toRefs, nextTick, getCurrentInstance} from "vue";
import {ElMessageBox} from "element-plus";
import { useRoute } from 'vue-router';
import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
import {approveProcessDelete, approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess.js";
import useUserStore from "@/store/modules/user";
const userStore = useUserStore();
const route = useRoute();
// 当前选中的标签页,默认为公出管理
const activeTab = ref('1');
@@ -277,6 +281,8 @@
    3: "/approveProcess/exportThree",
    4: "/approveProcess/exportFour",
    5: "/approveProcess/exportFive",
    6: "/approveProcess/exportSix",
    7: "/approveProcess/exportSeven",
  }
  const url = urlMap[type] || urlMap[0]
  const nameMap = {
@@ -286,6 +292,8 @@
    3: "出差管理审批表",
    4: "报销管理审批表",
    5: "采购申请审批表",
    6: "报价审批表",
    7: "出库审批表",
  }
  const fileName = nameMap[type] || nameMap[0]
  proxy.download(url, {}, `${fileName}.xlsx`)
@@ -333,6 +341,21 @@
      });
};
onMounted(() => {
  // 根据URL参数设置标签页和查询条件
  const approveType = route.query.approveType;
  const approveId = route.query.approveId;
  if (approveType) {
    // 设置标签页(approveType 对应 activeTab 的 name)
    activeTab.value = String(approveType);
  }
  if (approveId) {
    // 设置流程编号查询条件
    searchForm.value.approveId = String(approveId);
  }
  // 查询列表
  getList();
});
</script>