@@ -7,6 +13,10 @@
+
+ 加载中...
+
-
+
-
{{ card.title }}
{{ card.description }}
-
-
{{ card.tag }}
+
+
+ {{ tag.tagName }}
+
-
+
+ 加载中...
+
+
+
+
+
+
+
-
\ No newline at end of file
diff --git a/na-frontend/src/pages/man/HomeManPage.vue b/na-frontend/src/pages/man/HomeManPage.vue
new file mode 100644
index 0000000..eca9d58
--- /dev/null
+++ b/na-frontend/src/pages/man/HomeManPage.vue
@@ -0,0 +1,358 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ info.status }} {{ info.worktime }}
+
+
+
+
+ {{ info.location }}
+
+
+ 距您驾车或者打车8.0公里 需10分钟
+
+
+ 距离1号线微电园站1号口步行400米 需8分钟
+
+
+
+
+
+
+
+
+
新品展示
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/na-frontend/src/pages/man/PortfolioManPage.vue b/na-frontend/src/pages/man/PortfolioManPage.vue
new file mode 100644
index 0000000..3c4e755
--- /dev/null
+++ b/na-frontend/src/pages/man/PortfolioManPage.vue
@@ -0,0 +1,1083 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ card.title }}
+
{{ card.description }}
+
+
+ {{ tag.tagName }}
+
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/na-frontend/src/pages/man/SampleCollectionManPage.vue b/na-frontend/src/pages/man/SampleCollectionManPage.vue
new file mode 100644
index 0000000..cdc6cfa
--- /dev/null
+++ b/na-frontend/src/pages/man/SampleCollectionManPage.vue
@@ -0,0 +1,1084 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ card.title }}
+
{{ card.description }}
+
+
+ {{ tag.tagName }}
+
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/na-frontend/src/pages/man/TagManPage.vue b/na-frontend/src/pages/man/TagManPage.vue
new file mode 100644
index 0000000..552f802
--- /dev/null
+++ b/na-frontend/src/pages/man/TagManPage.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/na-frontend/src/router/index.js b/na-frontend/src/router/index.js
index 3c36009..e6f6b17 100644
--- a/na-frontend/src/router/index.js
+++ b/na-frontend/src/router/index.js
@@ -3,6 +3,10 @@ import VueRouter from "vue-router";
import HomePage from "@/pages/HomePage.vue";
import PortfolioPage from "@/pages/PortfolioPage.vue";
import SampleCollectionPage from "@/pages/SampleCollectionPage.vue";
+import PortfolioMan from "@/pages/man/PortfolioManPage.vue";
+import SampleCollectionMan from "@/pages/man/SampleCollectionManPage.vue";
+import HomeManPage from "@/pages/man/HomeManPage.vue";
+import TagManPage from "@/pages/man/TagManPage.vue";
Vue.use(VueRouter);
const routes = [
@@ -10,20 +14,37 @@ const routes = [
path: "/",
name: "HomePage",
component: HomePage,
- meta: { direction: "back" },
},
{
path: "/portfolio",
name: "PortfolioPage",
component: PortfolioPage,
- meta: { direction: "forward" },
},
{
path: "/sampleCollection",
name: "SampleCollectionPage",
component: SampleCollectionPage,
- meta: { direction: "forward" },
},
+ {
+ path: "/yumi",
+ name: "Yumi",
+ component: HomeManPage,
+ },
+ {
+ path: "/sampleCollectionman",
+ name: "SampleCollectionMan",
+ component: SampleCollectionMan,
+ },
+ {
+ path: "/portfolioMan",
+ name: "PortfolioMan",
+ component: PortfolioMan,
+ },
+ {
+ path: "/tagManPage",
+ name: "tagManPage",
+ component: TagManPage,
+ }
];
const router = new VueRouter({
diff --git a/na-frontend/src/utils/file.js b/na-frontend/src/utils/file.js
new file mode 100644
index 0000000..dbe6c65
--- /dev/null
+++ b/na-frontend/src/utils/file.js
@@ -0,0 +1,227 @@
+import axios from 'axios';
+/**
+ * 文件操作工具类,支持上传、下载和删除文件
+ */
+
+export class FileService {
+ constructor(baseUrl = '') {
+ this.baseUrl = baseUrl;
+ }
+
+ /**
+ * 上传文件到MinIO
+ * @param {Object} options - 上传参数
+ * @param {string} options.bucketName - 存储桶名称
+ * @param {string} options.filePath - 文件路径
+ * @param {File} options.file - 文件对象
+ * @param {Function} [options.onProgress] - 进度回调函数
+ * @returns {Promise
} - 上传成功后的文件路径
+ */
+ uploadFile(options) {
+ const {
+ bucketName,
+ filePath,
+ file,
+ } = options;
+
+ if (!bucketName || !filePath || !file) {
+ return Promise.reject(new Error('缺少必要的上传参数'));
+ }
+
+ const formData = new FormData();
+ formData.append('bucketName', bucketName);
+ formData.append('filePath', filePath);
+ formData.append('file', file);
+
+ return axios({
+ url: `${this.baseUrl}/api/file/upload`,
+ method: 'post',
+ data: formData,
+ headers: { 'Accept': 'application/json' },
+ timeout: 60000
+ })
+ .then(response => {
+ if (response.status === 200) {
+ return response.data;
+ }
+ throw new Error(`上传失败,状态码:${response.status}`);
+ })
+ .catch(this._handleError);
+ }
+
+ /**
+ * 下载文件
+ * @param {Object} options - 下载参数
+ * @param {string} options.bucketName - 存储桶名称
+ * @param {string} options.filePath - 文件路径
+ * @param {string} [options.fileName] - 下载时使用的文件名
+ * @returns {Promise}
+ */
+ downloadFile(options) {
+ const { bucketName, filePath, fileName } = options;
+
+ if (!bucketName || !filePath) {
+ return Promise.reject(new Error('缺少必要的下载参数'));
+ }
+
+ return axios({
+ url: `${this.baseUrl}/api/file/download`,
+ method: 'get',
+ params: { bucketName, filePath },
+ responseType: 'blob',
+ timeout: 60000
+ })
+ .then(response => {
+ if (response.status === 200) {
+ this._saveFile(response.data, fileName || filePath.split('/').pop());
+ return;
+ }
+ throw new Error(`下载失败,状态码:${response.status}`);
+ })
+ .catch(this._handleError);
+ }
+
+ /**
+ * 删除文件
+ * @param {Object} options - 删除参数
+ * @param {string} options.bucketName - 存储桶名称
+ * @param {string} options.filePath - 文件路径
+ * @returns {Promise}
+ */
+ deleteFile(options) {
+ const { bucketName, filePath } = options;
+
+ if (!bucketName || !filePath) {
+ return Promise.reject(new Error('缺少必要的删除参数'));
+ }
+
+ return axios({
+ url: `${this.baseUrl}/api/file/delete`,
+ method: 'delete',
+ params: { bucketName, filePath },
+ timeout: 30000
+ })
+ .then(response => {
+ if (response.status === 204) {
+ return;
+ }
+ throw new Error(`删除失败,状态码:${response.status}`);
+ })
+ .catch(this._handleError);
+ }
+
+ /**
+ * 检查文件是否存在
+ * @param {Object} options - 参数
+ * @param {string} options.bucketName - 存储桶名称
+ * @param {string} options.filePath - 文件路径
+ * @returns {Promise} - 文件是否存在
+ */
+ fileExists(options) {
+ const { bucketName, filePath } = options;
+
+ if (!bucketName || !filePath) {
+ return Promise.reject(new Error('缺少必要的参数'));
+ }
+
+ return axios({
+ url: `${this.baseUrl}/api/file/exists`,
+ method: 'get',
+ params: { bucketName, filePath },
+ timeout: 30000
+ })
+ .then(response => {
+ if (response.status === 200) {
+ return response.data;
+ }
+ throw new Error(`检查失败,状态码:${response.status}`);
+ })
+ .catch(this._handleError);
+ }
+
+ /**
+ * 获取文件URL
+ * @param {Object} options - 参数
+ * @param {string} options.bucketName - 存储桶名称
+ * @param {string} options.filePath - 文件路径
+ * @param {number} [options.expirySeconds=3600] - URL有效期(秒)
+ * @returns {Promise} - 文件URL
+ */
+ getFileUrl(options) {
+ const { bucketName, filePath, expirySeconds = 3600 } = options;
+
+ if (!bucketName || !filePath) {
+ return Promise.reject(new Error('缺少必要的参数'));
+ }
+
+ return axios({
+ url: `${this.baseUrl}/api/file/url`,
+ method: 'get',
+ params: { bucketName, filePath, expirySeconds },
+ timeout: 30000
+ })
+ .then(response => {
+ if (response.status === 200) {
+ return response.data;
+ }
+ throw new Error(`获取URL失败,状态码:${response.status}`);
+ })
+ .catch(this._handleError);
+ }
+
+ /**
+ * 保存文件到本地
+ * @param {Blob} blob - 文件内容
+ * @param {string} fileName - 文件名
+ */
+ _saveFile(blob, fileName) {
+ // 处理中文文件名
+ const encodedFileName = encodeURIComponent(fileName);
+
+ if (navigator.msSaveBlob) {
+ // 兼容IE
+ navigator.msSaveBlob(blob, fileName);
+ } else {
+ // 现代浏览器
+ const link = document.createElement('a');
+ link.href = URL.createObjectURL(blob);
+ link.setAttribute('download', encodedFileName);
+ link.style.display = 'none';
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ URL.revokeObjectURL(link.href);
+ }
+ }
+
+ /**
+ * 统一处理错误
+ * @param {Error} error - 错误对象
+ */
+ _handleError(error) {
+ let errorMsg = '操作失败';
+ if (error.response) {
+ errorMsg += `,服务器错误:${error.response.status} ${error.response.statusText}`;
+ } else if (error.request) {
+ errorMsg += ',未收到服务器响应';
+ } else {
+ errorMsg += `,${error.message}`;
+ }
+ console.error(errorMsg, error);
+ throw new Error(errorMsg);
+ }
+ }
+
+ // 创建Vue插件
+export const FileServicePlugin = {
+ install(Vue, options = {}) {
+ // 创建全局实例
+ const fileService = new FileService(options.baseUrl);
+
+ // 方式1:添加到Vue原型,全局可用
+ Vue.prototype.$fileService = fileService;
+
+ // 方式2:注册为全局组件
+ Vue.fileService = fileService;
+ }
+ };
\ No newline at end of file
diff --git a/na-frontend/src/utils/request.js b/na-frontend/src/utils/request.js
index d364fc4..f51d09d 100644
--- a/na-frontend/src/utils/request.js
+++ b/na-frontend/src/utils/request.js
@@ -2,7 +2,7 @@ import axios from 'axios'
// 创建 axios 实例
const service = axios.create({
- baseURL: "http://127.0.0.1:8090/api",
+ baseURL: "http://wcy111.top:35001/api",
timeout: 10000
})
@@ -19,31 +19,11 @@ const getRequestKey = (config) => {
const dataStr = data ? JSON.stringify(data) : '';
return `${method}:${url}:${paramsStr}:${dataStr}`;
};
-// 请求拦截器:添加防抖逻辑
+
+// 请求拦截器:仅保留防抖逻辑
service.interceptors.request.use(
config => {
- // 1. 检查POST请求体和参数是否都为空
- if (config.method === 'post') {
- // 检查请求体是否为空
- const bodyEmpty =
- config.data === undefined ||
- config.data === null ||
- (typeof config.data === 'object' && Object.keys(config.data).length === 0) ||
- (typeof config.data === 'string' && config.data.trim().length === 0);
-
- // 检查URL参数是否为空
- const paramsEmpty =
- config.params === undefined ||
- config.params === null ||
- (typeof config.params === 'object' && Object.keys(config.params).length === 0);
-
- // 如果请求体和参数都为空,则打印提示
- if (bodyEmpty && paramsEmpty) {
- console.log('提示:POST请求的请求体和参数均为空');
- }
- }
-
- // 2. 防抖逻辑
+ // 防抖逻辑
return new Promise((resolve) => {
const requestKey = getRequestKey(config);
// 清除之前的定时器
@@ -63,4 +43,29 @@ service.interceptors.request.use(
return Promise.reject(error);
}
);
+
+// 响应拦截器保持不变
+service.interceptors.response.use(
+ response => {
+ return response.data;
+ },
+ error => {
+ let errorMessage = '请求失败';
+
+ if (error.response) {
+ errorMessage = `请求失败,状态码: ${error.response.status}`;
+ if (error.response.data && error.response.data.message) {
+ errorMessage += `,原因: ${error.response.data.message}`;
+ }
+ } else if (error.request) {
+ errorMessage = '请求已发送,但没有收到响应';
+ } else {
+ errorMessage = `请求错误: ${error.message}`;
+ }
+
+ console.error(errorMessage);
+ return Promise.reject(errorMessage);
+ }
+);
+
export default service;
\ No newline at end of file