hookehuyr

feat: 添加微信支付和配置相关API及环境变量配置

refactor: 重构axios和api模块结构,移除无用代码

chore: 更新vite配置和项目基础设置

docs: 添加接口文档注释

style: 格式化代码并统一代码风格
1 -# 开发环境配置 1 +###
2 +# 资源公共路径
3 +VITE_BASE = /
2 4
3 -# API 基础地址 5 +# 测试open-id
4 -VITE_API_BASE_URL=http://localhost:3000/api 6 +VITE_OPENID = api-test-openid
7 +# VITE_OPENID = o8BRf1gLDWieH3Y3JvbrI_4IjaME
8 +# VITE_OPENID = oJLZq5t9PIKLW9tm1oSUNAuPwssA
9 +# VITE_OPENID = oJLZq5uT_6GwIh2tQWh1F9IoHZ3U
10 +# VITE_OPENID =
5 11
6 -# 是否开启 Mock 12 +# B端账号
7 -VITE_USE_MOCK=true 13 +VITE_ID = 13761653761
8 14
9 -# 开发服务器端口 15 +# 验证码
10 -VITE_PORT=5173 16 +VITE_PIN =
11 17
12 -# 是否自动打开浏览器
13 -VITE_OPEN=true
...\ No newline at end of file ...\ No newline at end of file
18 +# 反向代理服务器地址
19 +VITE_PROXY_TARGET = https://oa-dev.onwall.cn
20 +# VITE_PROXY_TARGET = http://oa.onwall.cn
21 +
22 +# PC端地址
23 +VITE_MOBILE_URL = http://localhost:5173/
......
1 -# 生产环境配置 1 +###
2 +# 资源公共路径
3 +VITE_BASE = /f/stdj/
2 4
3 -# API 基础地址 5 +# 测试open-id
4 -VITE_API_BASE_URL=https://api.yourdomain.com 6 +VITE_APP_OPENID =
5 7
6 -# 是否开启 Mock 8 +# B端账号
7 -VITE_USE_MOCK=false 9 +VITE_APP_ID =
8 10
9 -# 构建输出目录 11 +# 验证码
10 -VITE_OUTPUT_DIR=dist 12 +VITE_APP_PIN =
11 13
12 -# 静态资源目录
13 -VITE_ASSETS_DIR=assets
...\ No newline at end of file ...\ No newline at end of file
14 +# 反向代理服务器地址
15 +VITE_PROXY_TARGET = https://oa.onwall.cn
16 +
17 +# PC端地址
18 +# VITE_MOBILE_URL = http://oa.onwall.cn/f/guanzong/web/
19 +# VITE_MOBILE_URL = http://guanzong.onwall.cn/f/guanzong/web/
......
1 +/*
2 + * @Date: 2022-06-17 14:54:29
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2023-06-25 09:33:28
5 + * @FilePath: /huizhu/src/api/common.js
6 + * @Description: 通用接口
7 + */
8 +import { fn, fetch, uploadFn } from '@/api/fn';
9 +
10 +const Api = {
11 + SMS: '/srv/?a=sms',
12 + TOKEN: '/srv/?a=upload',
13 + SAVE_FILE: '/srv/?a=upload&t=save_file',
14 +}
15 +
16 +/**
17 + * @description: 发送验证码
18 + * @param {*} phone 手机号码
19 + * @returns
20 + */
21 +export const smsAPI = (params) => fn(fetch.post(Api.SMS, params));
22 +
23 +/**
24 + * @description: 获取七牛token
25 + * @param {*} filename 文件名
26 + * @param {*} file 图片base64
27 + * @returns
28 + */
29 +export const qiniuTokenAPI = (params) => fn(fetch.stringifyPost(Api.TOKEN, params));
30 +
31 +/**
32 + * @description: 上传七牛
33 + * @param {*}
34 + * @returns
35 + */
36 +export const qiniuUploadAPI = (url, data, config) => uploadFn(fetch.basePost(url, data, config));
37 +
38 +/**
39 + * @description: 保存图片
40 + * @param {*} format
41 + * @param {*} hash
42 + * @param {*} height
43 + * @param {*} width
44 + * @param {*} filekey
45 + * @returns
46 + */
47 +export const saveFileAPI = (params) => fn(fetch.stringifyPost(Api.SAVE_FILE, params));
1 +/*
2 + * @Date: 2022-05-18 22:56:08
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2023-08-24 10:56:44
5 + * @FilePath: /front/src/api/fn.js
6 + * @Description: 文件描述
7 + */
8 +import axios from '@/utils/axios';
9 +import { showSuccessToast, showFailToast } from 'vant';
10 +import qs from 'Qs'
11 +
12 +/**
13 + * 网络请求功能函数
14 + * @param {*} api 请求axios接口
15 + * @returns 请求成功后,获取数据
16 + */
17 +export const fn = (api) => {
18 + return api
19 + .then(res => {
20 + if (res.data.code === 1) {
21 + return res.data || true;
22 + } else {
23 + // tslint:disable-next-line: no-console
24 + console.warn(res);
25 + if (!res.data.show) return false;
26 + showFailToast(res.data.msg);
27 + return false;
28 + }
29 + })
30 + .catch(err => {
31 + // tslint:disable-next-line: no-console
32 + console.error(err);
33 + return false;
34 + })
35 + .finally(() => { // 最终执行
36 + })
37 +}
38 +
39 +/**
40 + * 七牛返回格式
41 + * @param {*} api
42 + * @returns
43 + */
44 +export const uploadFn = (api) => {
45 + return api
46 + .then(res => {
47 + if (res.statusText === 'OK') {
48 + return res.data || true;
49 + } else {
50 + // tslint:disable-next-line: no-console
51 + console.warn(res);
52 + if (!res.data.show) return false;
53 + showFailToast(res.data.msg);
54 + return false;
55 + }
56 + })
57 + .catch(err => {
58 + // tslint:disable-next-line: no-console
59 + console.error(err);
60 + return false;
61 + })
62 +}
63 +
64 +/**
65 + * 统一 GET/POST 不同传参形式
66 + */
67 +export const fetch = {
68 + get: function (api, params) {
69 + return axios.get(api, { params })
70 + },
71 + post: function (api, params) {
72 + return axios.post(api, params)
73 + },
74 + stringifyPost: function (api, params) {
75 + return axios.post(api, qs.stringify(params))
76 + },
77 + basePost: function (url, data, config) {
78 + return axios.post(url, data, config)
79 + }
80 +}
1 -import request from '@/utils/request' 1 +/*
2 + * @Date: 2023-08-24 09:42:27
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2025-10-31 11:04:23
5 + * @FilePath: /stdj_h5/src/api/index.js
6 + * @Description: 文件描述
7 + */
8 +import { fn, fetch } from '@/api/fn';
2 9
3 -// 用户相关 API 10 +const Api = {
4 -export const userApi = { 11 + GET_HOME: '/srv/?a=home',
5 - // 获取用户信息 12 + GET_ARTICLE: '/srv/?a=get_article',
6 - getUserInfo: () => request.get('/user/info'), 13 +};
7 14
8 - // 更新用户信息 15 +/**
9 - updateUserInfo: (data) => request.put('/user/info', data), 16 + * @description: 首页数据
17 + * @returns {Object} list
18 + * @property [Object] list.STDJSSQZ 三师七证
19 + * @property integer list.STDJSSQZ.id 分类id
20 + * @property string list.STDJSSQZ.category_name 分类名称
21 + * @property string list.STDJSSQZ.cover 封面图
22 + * @property string list.STDJSSQZ.parent_sn 父分类id
23 + * @property [Object] list.STDJFHLC 法会流程
24 + * @property integer list.STDJFHLC.id 分类id
25 + * @property string list.STDJFHLC.category_name 分类名称
26 + * @property string list.STDJFHLC.cover 封面图
27 + * @property string list.STDJFHLC.parent_sn 父分类id
28 + * @property [Object] list.STDJXGXW 新闻
29 + * @property integer list.STDJXGXW.id 分类id
30 + * @property string list.STDJXGXW.post_title 新闻标题
31 + * @property string list.STDJXGXW.post_date 发布日期
32 + * @property string list.STDJXGXW.photo 封面图
33 + */
34 +export const homePageAPI = (params) => fn(fetch.get(Api.GET_HOME, params));
10 35
11 - // 用户登录 36 +/**
12 - login: (data) => request.post('/user/login', data), 37 + * @description: 三師七證数据
38 + * @param {String} pid 分类id
39 + * @returns {Object} list
40 + * @property integer list.id 分类id
41 + * @property string list.category_name 分类名称
42 + * @property string list.category_seq 分类顺序
43 + * @property [Object] list.list 子分类列表
44 + * @property integer list.list.id 子分类id
45 + * @property string list.list.post_title 标题/名称
46 + * @property string list.list.post_date 发布日期
47 + * @property string list.list.post_excerpt 简介
48 + * @property string list.list.post_content 内容/描述
49 + * @property string list.list.photo 封面图
50 + * @property string list.list.category_id 分类id
51 + */
52 +export const getSSQZAPI = (params) => fn(fetch.get(Api.GET_ARTICLE, params));
13 53
14 - // 用户注册 54 +/**
15 - register: (data) => request.post('/user/register', data), 55 + * @description: 图片流媒体数据
56 + * @param {String} cid 分类id
57 + * @param {String} page 页码,默认0
58 + * @param {String} limit 每页数量,默认10
59 + * @returns {Object} list
60 + * @property integer list.id 分类id
61 + * @property string list.post_title 标题/名称
62 + * @property string list.post_date 发布日期
63 + * @property string list.post_excerpt 简介
64 + * @property string list.photo 封面图
65 + */
66 +export const getImgStreamAPI = (params) => fn(fetch.get(Api.GET_ARTICLE, params));
16 67
17 - // 用户登出
18 - logout: () => request.post('/user/logout')
19 -}
20 -
21 -// 通用 API
22 -export const commonApi = {
23 - // 上传文件
24 - upload: (file) => {
25 - const formData = new FormData()
26 - formData.append('file', file)
27 - return request.post('/upload', formData, {
28 - headers: {
29 - 'Content-Type': 'multipart/form-data'
30 - }
31 - })
32 - },
33 -
34 - // 获取配置信息
35 - getConfig: () => request.get('/config'),
36 -
37 - // 发送验证码
38 - sendSms: (phone) => request.post('/sms/send', { phone })
39 -}
40 -
41 -// 示例 API
42 -export const demoApi = {
43 - // 获取列表数据
44 - getList: (params) => request.get('/demo/list', { params }),
45 -
46 - // 获取详情
47 - getDetail: (id) => request.get(`/demo/${id}`),
48 -
49 - // 创建数据
50 - create: (data) => request.post('/demo', data),
51 -
52 - // 更新数据
53 - update: (id, data) => request.put(`/demo/${id}`, data),
54 -
55 - // 删除数据
56 - delete: (id) => request.delete(`/demo/${id}`)
57 -}
58 -
59 -// 导出所有 API
60 -export default {
61 - userApi,
62 - commonApi,
63 - demoApi
64 -}
...\ No newline at end of file ...\ No newline at end of file
68 +/**
69 + * @description: 文章详情数据
70 + * @param {String} i 文章id
71 + * @returns {Object} data
72 + * @property integer data.post_author 作者
73 + * @property string data.post_title 标题/名称
74 + * @property string data.post_date 发布日期
75 + * @property string data.post_excerpt 简介
76 + * @property string data.post_content 内容/描述
77 + * @property string data.post_modified 修改日期
78 + * @property string data.post_status 状态
79 + * @property string data.post_type 类型
80 + * @property object data.file_list 文件列表
81 + * @property object data.file_list.photo 照片
82 + * @property string data.file_list.photo.value 照片地址
83 + */
84 +export const getArticleDetailAPI = (params) => fn(fetch.get(Api.GET_ARTICLE, params));
......
1 +/*
2 + * @Author: hookehuyr hookehuyr@gmail.com
3 + * @Date: 2022-06-09 13:32:44
4 + * @LastEditors: hookehuyr hookehuyr@gmail.com
5 + * @LastEditTime: 2022-06-14 14:47:01
6 + * @FilePath: /tswj/src/api/wx/config.js
7 + * @Description:
8 + */
9 +import { fn, fetch } from '@/api/fn';
10 +
11 +const Api = {
12 + WX_JSAPI: '/srv/?a=wx_share',
13 +}
14 +
15 +/**
16 + * @description 获取微信CONFIG配置文件
17 + * @param {*} url
18 + * @returns {*} cfg
19 + */
20 +export const wxJsAPI = (params) => fn(fetch.get(Api.WX_JSAPI, params));
1 +/*
2 + * @Date: 2022-06-13 14:18:57
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-06-13 14:27:21
5 + * @FilePath: /tswj/src/api/wx/jsApiList.js
6 + * @Description: 文件描述
7 + */
8 +export const apiList = [
9 + "updateAppMessageShareData",
10 + "updateTimelineShareData",
11 + "onMenuShareTimeline",
12 + "onMenuShareAppMessage",
13 + "onMenuShareQQ",
14 + "onMenuShareWeibo",
15 + "onMenuShareQZone",
16 + "startRecord",
17 + "stopRecord",
18 + "onVoiceRecordEnd",
19 + "playVoice",
20 + "pauseVoice",
21 + "stopVoice",
22 + "onVoicePlayEnd",
23 + "uploadVoice",
24 + "downloadVoice",
25 + "chooseImage",
26 + "previewImage",
27 + "uploadImage",
28 + "downloadImage",
29 + "translateVoice",
30 + "getNetworkType",
31 + "openLocation",
32 + "getLocation",
33 + "hideOptionMenu",
34 + "showOptionMenu",
35 + "hideMenuItems",
36 + "showMenuItems",
37 + "hideAllNonBaseMenuItem",
38 + "showAllNonBaseMenuItem",
39 + "closeWindow",
40 + "scanQRCode",
41 + "chooseWXPay",
42 + "openProductSpecificView",
43 + "addCard",
44 + "chooseCard",
45 + "openCard"
46 +]
1 +/*
2 + * @Author: hookehuyr hookehuyr@gmail.com
3 + * @Date: 2022-06-09 13:32:44
4 + * @LastEditors: hookehuyr hookehuyr@gmail.com
5 + * @LastEditTime: 2022-06-09 13:42:06
6 + * @FilePath: /tswj/src/api/wx/config.js
7 + * @Description:
8 + */
9 +import { fn, fetch } from '@/api/fn';
10 +
11 +const Api = {
12 + WX_PAY: 'c/bill_paymentForBill.do',
13 +}
14 +
15 +/**
16 + * @description 微信支付接口
17 + * @param {*}
18 + * @returns {*}
19 + */
20 +export const wxPayAPI = (params) => fn(fetch.get(Api.WX_PAY, params));
...@@ -2,38 +2,18 @@ ...@@ -2,38 +2,18 @@
2 * @Author: hookehuyr hookehuyr@gmail.com 2 * @Author: hookehuyr hookehuyr@gmail.com
3 * @Date: 2022-05-28 10:17:40 3 * @Date: 2022-05-28 10:17:40
4 * @LastEditors: hookehuyr hookehuyr@gmail.com 4 * @LastEditors: hookehuyr hookehuyr@gmail.com
5 - * @LastEditTime: 2025-07-01 16:23:59 5 + * @LastEditTime: 2025-10-31 09:52:30
6 - * @FilePath: /mlaj/src/utils/axios.js 6 + * @FilePath: /stdj_h5/src/utils/axios.js
7 * @Description: 7 * @Description:
8 */ 8 */
9 import axios from 'axios'; 9 import axios from 'axios';
10 -import router from '@/router'; 10 +// import router from '@/router';
11 // import qs from 'Qs' 11 // import qs from 'Qs'
12 // import { strExist } from '@/utils/tools' 12 // import { strExist } from '@/utils/tools'
13 +// import { parseQueryString } from '@/utils/tools'
13 14
14 -// axios.defaults.baseURL = 'http://localhost:3000/api';
15 axios.defaults.params = { 15 axios.defaults.params = {
16 - f: 'behalo', 16 + f: 'stdj',
17 -};
18 -
19 -/**
20 - * 设置用户认证信息到请求头
21 - * @param {string} userId - 用户ID
22 - * @param {string} userToken - 用户Token
23 - */
24 -export const setAuthHeaders = (userId, userToken) => {
25 - if (userId && userToken) {
26 - axios.defaults.headers['User-Id'] = userId;
27 - axios.defaults.headers['User-Token'] = userToken;
28 - }
29 -};
30 -
31 -/**
32 - * 清除用户认证信息
33 - */
34 -export const clearAuthHeaders = () => {
35 - delete axios.defaults.headers['User-Id'];
36 - delete axios.defaults.headers['User-Token'];
37 }; 17 };
38 18
39 /** 19 /**
...@@ -41,16 +21,6 @@ export const clearAuthHeaders = () => { ...@@ -41,16 +21,6 @@ export const clearAuthHeaders = () => {
41 */ 21 */
42 axios.interceptors.request.use( 22 axios.interceptors.request.use(
43 config => { 23 config => {
44 - /**
45 - * 司总授权信息
46 - * 动态获取 user_info 并设置到请求头
47 - * 确保每个请求都带上最新的 user_info
48 - */
49 - const user_info = localStorage.getItem('user_info') ? JSON.parse(localStorage.getItem('user_info')) : {};
50 - if (user_info) {
51 - config.headers['User-Id'] = user_info.user_id;
52 - config.headers['User-Token'] = user_info.HTTP_USER_TOKEN;
53 - }
54 // const url_params = parseQueryString(location.href); 24 // const url_params = parseQueryString(location.href);
55 // GET请求默认打上时间戳,避免从缓存中拿数据。 25 // GET请求默认打上时间戳,避免从缓存中拿数据。
56 const timestamp = config.method === 'get' ? (new Date()).valueOf() : ''; 26 const timestamp = config.method === 'get' ? (new Date()).valueOf() : '';
...@@ -73,20 +43,9 @@ axios.interceptors.request.use( ...@@ -73,20 +43,9 @@ axios.interceptors.request.use(
73 */ 43 */
74 axios.interceptors.response.use( 44 axios.interceptors.response.use(
75 response => { 45 response => {
76 - if (response.data && response.data.code === 401) {
77 - // 清除用户登录信息
78 - localStorage.removeItem('currentUser');
79 - // 清除认证请求头
80 - clearAuthHeaders();
81 - // 跳转到登录页面,并携带当前路由信息
82 - const currentPath = router.currentRoute.value.fullPath;
83 - router.push(`/login?redirect=${encodeURIComponent(currentPath)}`);
84 - // router.push(`/login`);
85 - }
86 return response; 46 return response;
87 }, 47 },
88 error => { 48 error => {
89 - // 响应错误处理
90 return Promise.reject(error); 49 return Promise.reject(error);
91 }); 50 });
92 51
......
1 /* 1 /*
2 * @Date: 2025-10-30 10:27:43 2 * @Date: 2025-10-30 10:27:43
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-10-30 15:24:36 4 + * @LastEditTime: 2025-10-30 21:48:53
5 * @FilePath: /stdj_h5/vite.config.js 5 * @FilePath: /stdj_h5/vite.config.js
6 * @Description: 文件描述 6 * @Description: 文件描述
7 */ 7 */
8 -import { defineConfig } from 'vite' 8 +import { defineConfig, loadEnv } from 'vite'
9 import vue from '@vitejs/plugin-vue' 9 import vue from '@vitejs/plugin-vue'
10 import AutoImport from 'unplugin-auto-import/vite' 10 import AutoImport from 'unplugin-auto-import/vite'
11 import Components from 'unplugin-vue-components/vite' 11 import Components from 'unplugin-vue-components/vite'
...@@ -14,9 +14,16 @@ import path from 'path' ...@@ -14,9 +14,16 @@ import path from 'path'
14 import tailwindcss from 'tailwindcss' 14 import tailwindcss from 'tailwindcss'
15 import autoprefixer from 'autoprefixer' 15 import autoprefixer from 'autoprefixer'
16 import postcsspxtoviewport from 'postcss-px-to-viewport' 16 import postcsspxtoviewport from 'postcss-px-to-viewport'
17 +import { createProxy } from './build/proxy'
17 18
18 -// https://vitejs.dev/config/ 19 +export default ({ command, mode }) => {
19 -export default defineConfig({ 20 + const root = process.cwd();
21 +
22 + const viteEnv = loadEnv(mode, root);
23 + // let isProd = (command === 'serve'); // 情景配置是否为开发模式 serve 或 build
24 +
25 + return defineConfig({
26 + base: viteEnv.VITE_BASE, // 开发或生产环境服务的公共基础路径。
20 plugins: [ 27 plugins: [
21 vue(), 28 vue(),
22 AutoImport({ 29 AutoImport({
...@@ -66,25 +73,40 @@ export default defineConfig({ ...@@ -66,25 +73,40 @@ export default defineConfig({
66 }, 73 },
67 server: { 74 server: {
68 host: '0.0.0.0', 75 host: '0.0.0.0',
69 - port: 5573, 76 + port: viteEnv.VITE_PORT, // 本地服务端口
70 - open: true, 77 + // strictPort: true, // 设为true时若端口已被占用则会直接退出, 而不是尝试下一个可用端口
71 - proxy: { 78 + // https: '',
72 - '/api': { 79 + // open: false, // 在服务器启动时自动在浏览器中打开应用程序. 当此值为字符串时, 会被当作URL的路径名.
73 - target: 'http://localhost:8080', 80 + // proxy: { // 代理
74 - changeOrigin: true, 81 + // '/srv/': {
75 - rewrite: (path) => path.replace(/^\/api/, '') 82 + // // target: 'http://voice.onwall.cn',
76 - } 83 + // target: viteEnv.VITE_PROXY_TARGET,
77 - } 84 + // changeOrigin: true,
85 + // // rewrite: (path) => path.replace(/^\/api/, '')
86 + // },
87 + // },
88 + proxy: createProxy(viteEnv.VITE_PROXY_PREFIX, viteEnv.VITE_PROXY_TARGET),
89 + // cors: '', // 为开发服务器配置 CORS。默认启用并允许任何源,传递一个 选项对象 来调整行为或设为 false 表示禁用。
90 + // force: '', // 设置为 true 强制使依赖预构建。
91 + // hmr: '', // 禁用或配置 HMR 连接(用于 HMR websocket 必须使用不同的 http 服务器地址的情况)。 设置 server.hmr.overlay 为 false 可以禁用服务器错误遮罩层。
92 + // watch: '', // 传递给 chokidar 的文件系统监视器选项。
78 }, 93 },
79 build: { 94 build: {
80 - outDir: 'dist', 95 + // outDir: 'voice', // 指定输出路径(相对于项目根目录).
96 + outDir: viteEnv.VITE_OUTDIR, // 指定输出路径(相对于项目根目录).
81 assetsDir: 'static', 97 assetsDir: 'static',
82 rollupOptions: { 98 rollupOptions: {
83 output: { 99 output: {
84 chunkFileNames: 'static/js/[name]-[hash].js', 100 chunkFileNames: 'static/js/[name]-[hash].js',
85 entryFileNames: 'static/js/[name]-[hash].js', 101 entryFileNames: 'static/js/[name]-[hash].js',
86 - assetFileNames: 'static/[ext]/[name]-[hash].[ext]' 102 + assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
87 - } 103 + },
88 - } 104 + input: { // 多页面应用模式, 打包时配置,运行配置要处理root
105 + main: path.resolve(__dirname, 'index.html'),
106 + // mono1: path.resolve(__dirname, 'src/packages/mono1/index.html'),
107 + // mono2: path.resolve(__dirname, 'src/packages/mono2/index.html'),
89 } 108 }
90 -}) 109 + },
110 + },
111 + });
112 +};
......