wanglizhong
2025-05-01 f3e793d0cb0810401545820c41b18df16db7f6fa
fix:ui 层面增加匿名访问
2个文件已添加
4个文件已修改
253 ■■■■■ 已修改文件
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysClientAppController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/anonymous/index.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/permission.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/router/index.js 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/utils/request.js 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/anonymous/test.vue 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysClientAppController.java
@@ -125,6 +125,7 @@
        String sign = SecurityUtils.md5(signStr);
        
        AjaxResult ajax = AjaxResult.success();
        ajax.put("use","md5(appId+timestamp+securityKey)");
        ajax.put("appId", appId);
        ajax.put("timestamp", String.valueOf(timestamp));
        ajax.put("sign", sign);
ruoyi-ui/src/api/anonymous/index.js
New file
@@ -0,0 +1,18 @@
import request from '@/utils/request'
// 生成签名
export function generateSign(appId) {
  return request({
    url: '/system/clientApp/generateSign/' + appId,
    method: 'get'
  })
}
// 匿名访问示例
export function anonymousTest(data) {
  return request({
    url: '/system/clientApp/testSign',
    method: 'get',
    params: data
  })
}
ruoyi-ui/src/permission.js
@@ -9,7 +9,7 @@
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register']
const whiteList = ['/login', '/register','/anonymous/*']
const isWhiteList = (path) => {
  return whiteList.some(pattern => isPathMatch(pattern, path))
@@ -47,9 +47,11 @@
      }
    }
  } else {
    debugger;
    // 没有token
    if (isWhiteList(to.path)) {
    if (isWhiteList(to.path) || to.meta.anonymous) {
      // 在免登录白名单,直接进入
      next()
    } else {
      next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
ruoyi-ui/src/router/index.js
@@ -95,11 +95,17 @@
    ]
  },
  {
    path: 'order/detail/:id',
    path: '/order/detail/:id',
    component: () => import('@/views/system/order/detail'),
    name: 'OrderDetail',
    meta: { title: '订单详情' },
    hidden: true
    hidden: true,
    meta: { title: '订单详情页', anonymous: true }
  },
  {
    path: '/anonymous/test',
    component: () => import('@/views/anonymous/test'),
    hidden: true,
    meta: { title: '匿名访问测试', anonymous: true }
  }
]
ruoyi-ui/src/utils/request.js
@@ -26,7 +26,10 @@
  const isToken = (config.headers || {}).isToken === false
  // 是否需要防止数据重复提交
  const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  if (getToken() && !isToken) {
  if (!isToken &&  getToken()) {
    config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  }
  // get请求映射params参数
ruoyi-ui/src/views/anonymous/test.vue
New file
@@ -0,0 +1,211 @@
<template>
  <div class="anonymous-container">
    <div class="test-card">
      <h2 class="card-title">匿名访问测试</h2>
      <div class="form-content">
        <div class="form-item">
          <label>应用ID:</label>
          <input v-model="form.appId" placeholder="请输入应用ID" class="input-field" />
        </div>
        <div class="form-actions">
          <button class="btn btn-primary" @click="handleTest">测试访问</button>
          <button class="btn btn-success" @click="handleGenerateSign">生成签名</button>
        </div>
      </div>
      <!-- 显示签名信息 -->
      <div v-if="signInfo" class="info-card">
        <h3>签名信息</h3>
        <div class="info-item">
          <span class="label">时间戳:</span>
          <span class="value">{{ signInfo.timestamp }}</span>
        </div>
        <div class="info-item">
          <span class="label">签名:</span>
          <span class="value">{{ signInfo.sign }}</span>
        </div>
        <div class="info-item">
          <span class="label">签名字符串:</span>
          <span class="value">{{ signInfo.signStr }}</span>
        </div>
      </div>
      <!-- 显示测试结果 -->
      <div v-if="testResult" class="info-card">
        <h3>测试结果</h3>
        <pre class="result-content">{{ JSON.stringify(testResult, null, 2) }}</pre>
      </div>
    </div>
  </div>
</template>
<script>
import { generateSign, anonymousTest } from '@/api/anonymous'
import { Message } from 'element-ui'
export default {
  name: 'AnonymousTest',
  data() {
    return {
      form: {
        appId: ''
      },
      signInfo: null,
      testResult: null
    }
  },
  methods: {
    // 生成签名
    handleGenerateSign() {
      if (!this.form.appId) {
        Message.warning('请输入应用ID')
        return
      }
      generateSign(this.form.appId).then(response => {
        this.signInfo = response.data
        Message.success('签名生成成功')
      })
    },
    // 测试匿名访问
    handleTest() {
      if (!this.signInfo) {
        Message.warning('请先生成签名')
        return
      }
      const params = {
        appId: this.form.appId,
        sign: this.signInfo.sign,
        timestamp: this.signInfo.timestamp
      }
      anonymousTest(params).then(response => {
        this.testResult = response
        Message.success('测试成功')
      })
    }
  }
}
</script>
<style scoped>
.anonymous-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  background-color: #f0f2f5;
  padding: 20px;
}
.test-card {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
  padding: 30px;
  width: 100%;
  max-width: 600px;
}
.card-title {
  margin: 0 0 20px;
  color: #333;
  text-align: center;
}
.form-content {
  margin-bottom: 20px;
}
.form-item {
  margin-bottom: 15px;
}
.form-item label {
  display: block;
  margin-bottom: 5px;
  color: #606266;
}
.input-field {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  font-size: 14px;
  transition: border-color 0.2s;
}
.input-field:focus {
  outline: none;
  border-color: #409eff;
}
.form-actions {
  display: flex;
  gap: 10px;
  margin-top: 20px;
}
.btn {
  padding: 8px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: opacity 0.2s;
}
.btn:hover {
  opacity: 0.8;
}
.btn-primary {
  background-color: #409eff;
  color: white;
}
.btn-success {
  background-color: #67c23a;
  color: white;
}
.info-card {
  margin-top: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 4px;
}
.info-card h3 {
  margin: 0 0 15px;
  color: #333;
  font-size: 16px;
}
.info-item {
  margin: 10px 0;
  line-height: 1.5;
}
.label {
  font-weight: bold;
  color: #606266;
  margin-right: 10px;
}
.value {
  font-family: monospace;
  color: #666;
  word-break: break-all;
}
.result-content {
  background-color: #f5f7fa;
  padding: 15px;
  border-radius: 4px;
  margin: 10px 0 0;
  overflow-x: auto;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.5;
}
</style>