69 Commits
1b21a6bb48
...
d0e4cb2f8f
-
290.eslintrc-auto-import.json
-
2.vercel/project.json
-
44CORS_README.md
-
43build/utils.js
-
44build/vite/build.js
-
26build/vite/plugin/autoImport.js
-
21build/vite/plugin/autocomponents.js
-
37build/vite/plugin/compress.js
-
37build/vite/plugin/index.js
-
19build/vite/plugin/mock.js
-
43build/vite/proxy.js
-
2index.html
-
1263package-lock.json
-
8package.json
-
25src/api/zhongchouApi.js
-
BINsrc/assets/bg@2x.png
-
BINsrc/assets/daijiemi.png
-
BINsrc/assets/img/bg.png
-
BINsrc/assets/img/zhongchou/bg.png
-
BINsrc/assets/img/zhongchou/blueBg.png
-
BINsrc/assets/img/zhongchou/redBg.png
-
BINsrc/assets/img/zhongchou/rocket.gif
-
BINsrc/assets/img/zhongchou/助力成功.png
-
BINsrc/assets/img/zhongchou/助力港股.png
-
BINsrc/assets/img/zhongchou/助力美股.png
-
BINsrc/assets/img/zhongchou/助力美股享实时数据.png
-
BINsrc/assets/img/zhongchou/周年庆装饰.png
-
BINsrc/assets/img/zhongchou/大标题.png
-
BINsrc/assets/img/zhongchou/底座.png
-
BINsrc/assets/img/zhongchou/手机bg.png
-
BINsrc/assets/img/zhongchou/手机助力美股享实时数据.png
-
BINsrc/assets/img/zhongchou/手机周年庆装饰.png
-
BINsrc/assets/img/zhongchou/手机矩形.png
-
BINsrc/assets/img/zhongchou/手机组2.png
-
BINsrc/assets/img/zhongchou/时间边框.png
-
BINsrc/assets/img/zhongchou/框.png
-
BINsrc/assets/img/zhongchou/活动需知.png
-
BINsrc/assets/img/zhongchou/浮窗.png
-
BINsrc/assets/img/zhongchou/港股.png
-
BINsrc/assets/img/zhongchou/港股已助力.png
-
BINsrc/assets/img/zhongchou/火箭.png
-
BINsrc/assets/img/zhongchou/知道了.png
-
BINsrc/assets/img/zhongchou/美股.png
-
BINsrc/assets/img/zhongchou/美股已助力.png
-
BINsrc/assets/img/待揭秘.png
-
1src/assets/vue.svg
-
BINsrc/assets/登录背景.png
-
285src/auto-import.d.ts
-
14src/components.d.ts
-
2src/style.css
-
2src/utils/prizeList.js
-
27src/utils/request.js
-
102src/views/choujiang/Login.vue
-
34src/views/choujiang/hxl-cj/cj.vue
-
1365src/views/zhongchou/index.vue
-
96vite.config.js
-
98修改完成总结.md
-
92抽奖逻辑修改说明.md
-
113测试用例.md
@ -0,0 +1,290 @@ |
|||
{ |
|||
"globals": { |
|||
"Component": true, |
|||
"ComponentPublicInstance": true, |
|||
"ComputedRef": true, |
|||
"DirectiveBinding": true, |
|||
"EffectScope": true, |
|||
"ExtractDefaultPropTypes": true, |
|||
"ExtractPropTypes": true, |
|||
"ExtractPublicPropTypes": true, |
|||
"InjectionKey": true, |
|||
"MaybeRef": true, |
|||
"MaybeRefOrGetter": true, |
|||
"PropType": true, |
|||
"Ref": true, |
|||
"Slot": true, |
|||
"Slots": true, |
|||
"VNode": true, |
|||
"WritableComputedRef": true, |
|||
"asyncComputed": true, |
|||
"autoResetRef": true, |
|||
"computed": true, |
|||
"computedAsync": true, |
|||
"computedEager": true, |
|||
"computedInject": true, |
|||
"computedWithControl": true, |
|||
"controlledComputed": true, |
|||
"controlledRef": true, |
|||
"createApp": true, |
|||
"createEventHook": true, |
|||
"createGlobalState": true, |
|||
"createInjectionState": true, |
|||
"createReactiveFn": true, |
|||
"createSharedComposable": true, |
|||
"createUnrefFn": true, |
|||
"customRef": true, |
|||
"debouncedRef": true, |
|||
"debouncedWatch": true, |
|||
"defineAsyncComponent": true, |
|||
"defineComponent": true, |
|||
"eagerComputed": true, |
|||
"effectScope": true, |
|||
"extendRef": true, |
|||
"getCurrentInstance": true, |
|||
"getCurrentScope": true, |
|||
"h": true, |
|||
"ignorableWatch": true, |
|||
"inject": true, |
|||
"isDefined": true, |
|||
"isProxy": true, |
|||
"isReactive": true, |
|||
"isReadonly": true, |
|||
"isRef": true, |
|||
"makeDestructurable": true, |
|||
"markRaw": true, |
|||
"nextTick": true, |
|||
"onActivated": true, |
|||
"onBeforeMount": true, |
|||
"onBeforeRouteLeave": true, |
|||
"onBeforeRouteUpdate": true, |
|||
"onBeforeUnmount": true, |
|||
"onBeforeUpdate": true, |
|||
"onClickOutside": true, |
|||
"onDeactivated": true, |
|||
"onErrorCaptured": true, |
|||
"onKeyStroke": true, |
|||
"onLongPress": true, |
|||
"onMounted": true, |
|||
"onRenderTracked": true, |
|||
"onRenderTriggered": true, |
|||
"onScopeDispose": true, |
|||
"onServerPrefetch": true, |
|||
"onStartTyping": true, |
|||
"onUnmounted": true, |
|||
"onUpdated": true, |
|||
"onWatcherCleanup": true, |
|||
"pausableWatch": true, |
|||
"provide": true, |
|||
"reactify": true, |
|||
"reactifyObject": true, |
|||
"reactive": true, |
|||
"reactiveComputed": true, |
|||
"reactiveOmit": true, |
|||
"reactivePick": true, |
|||
"readonly": true, |
|||
"ref": true, |
|||
"refAutoReset": true, |
|||
"refDebounced": true, |
|||
"refDefault": true, |
|||
"refThrottled": true, |
|||
"refWithControl": true, |
|||
"resolveComponent": true, |
|||
"resolveRef": true, |
|||
"resolveUnref": true, |
|||
"shallowReactive": true, |
|||
"shallowReadonly": true, |
|||
"shallowRef": true, |
|||
"syncRef": true, |
|||
"syncRefs": true, |
|||
"templateRef": true, |
|||
"throttledRef": true, |
|||
"throttledWatch": true, |
|||
"toRaw": true, |
|||
"toReactive": true, |
|||
"toRef": true, |
|||
"toRefs": true, |
|||
"toValue": true, |
|||
"triggerRef": true, |
|||
"tryOnBeforeMount": true, |
|||
"tryOnBeforeUnmount": true, |
|||
"tryOnMounted": true, |
|||
"tryOnScopeDispose": true, |
|||
"tryOnUnmounted": true, |
|||
"unref": true, |
|||
"unrefElement": true, |
|||
"until": true, |
|||
"useActiveElement": true, |
|||
"useArrayEvery": true, |
|||
"useArrayFilter": true, |
|||
"useArrayFind": true, |
|||
"useArrayFindIndex": true, |
|||
"useArrayFindLast": true, |
|||
"useArrayJoin": true, |
|||
"useArrayMap": true, |
|||
"useArrayReduce": true, |
|||
"useArraySome": true, |
|||
"useArrayUnique": true, |
|||
"useAsyncQueue": true, |
|||
"useAsyncState": true, |
|||
"useAttrs": true, |
|||
"useBase64": true, |
|||
"useBattery": true, |
|||
"useBluetooth": true, |
|||
"useBreakpoints": true, |
|||
"useBroadcastChannel": true, |
|||
"useBrowserLocation": true, |
|||
"useCached": true, |
|||
"useClipboard": true, |
|||
"useCloned": true, |
|||
"useColorMode": true, |
|||
"useConfirmDialog": true, |
|||
"useCounter": true, |
|||
"useCssModule": true, |
|||
"useCssVar": true, |
|||
"useCssVars": true, |
|||
"useCurrentElement": true, |
|||
"useCycleList": true, |
|||
"useDark": true, |
|||
"useDateFormat": true, |
|||
"useDebounce": true, |
|||
"useDebounceFn": true, |
|||
"useDebouncedRefHistory": true, |
|||
"useDeviceMotion": true, |
|||
"useDeviceOrientation": true, |
|||
"useDevicePixelRatio": true, |
|||
"useDevicesList": true, |
|||
"useDisplayMedia": true, |
|||
"useDocumentVisibility": true, |
|||
"useDraggable": true, |
|||
"useDropZone": true, |
|||
"useElementBounding": true, |
|||
"useElementByPoint": true, |
|||
"useElementHover": true, |
|||
"useElementSize": true, |
|||
"useElementVisibility": true, |
|||
"useEventBus": true, |
|||
"useEventListener": true, |
|||
"useEventSource": true, |
|||
"useEyeDropper": true, |
|||
"useFavicon": true, |
|||
"useFetch": true, |
|||
"useFileDialog": true, |
|||
"useFileSystemAccess": true, |
|||
"useFocus": true, |
|||
"useFocusWithin": true, |
|||
"useFps": true, |
|||
"useFullscreen": true, |
|||
"useGamepad": true, |
|||
"useGeolocation": true, |
|||
"useId": true, |
|||
"useIdle": true, |
|||
"useImage": true, |
|||
"useInfiniteScroll": true, |
|||
"useIntersectionObserver": true, |
|||
"useInterval": true, |
|||
"useIntervalFn": true, |
|||
"useKeyModifier": true, |
|||
"useLastChanged": true, |
|||
"useLink": true, |
|||
"useLocalStorage": true, |
|||
"useMagicKeys": true, |
|||
"useManualRefHistory": true, |
|||
"useMediaControls": true, |
|||
"useMediaQuery": true, |
|||
"useMemoize": true, |
|||
"useMemory": true, |
|||
"useModel": true, |
|||
"useMounted": true, |
|||
"useMouse": true, |
|||
"useMouseInElement": true, |
|||
"useMousePressed": true, |
|||
"useMutationObserver": true, |
|||
"useNavigatorLanguage": true, |
|||
"useNetwork": true, |
|||
"useNow": true, |
|||
"useObjectUrl": true, |
|||
"useOffsetPagination": true, |
|||
"useOnline": true, |
|||
"usePageLeave": true, |
|||
"useParallax": true, |
|||
"usePermission": true, |
|||
"usePointer": true, |
|||
"usePointerLock": true, |
|||
"usePointerSwipe": true, |
|||
"usePreferredColorScheme": true, |
|||
"usePreferredContrast": true, |
|||
"usePreferredDark": true, |
|||
"usePreferredLanguages": true, |
|||
"usePreferredReducedMotion": true, |
|||
"usePrevious": true, |
|||
"useRafFn": true, |
|||
"useRefHistory": true, |
|||
"useResizeObserver": true, |
|||
"useRoute": true, |
|||
"useRouter": true, |
|||
"useScreenOrientation": true, |
|||
"useScreenSafeArea": true, |
|||
"useScriptTag": true, |
|||
"useScroll": true, |
|||
"useScrollLock": true, |
|||
"useSessionStorage": true, |
|||
"useShare": true, |
|||
"useSlots": true, |
|||
"useSorted": true, |
|||
"useSpeechRecognition": true, |
|||
"useSpeechSynthesis": true, |
|||
"useStepper": true, |
|||
"useStorage": true, |
|||
"useStorageAsync": true, |
|||
"useStyleTag": true, |
|||
"useSupported": true, |
|||
"useSwipe": true, |
|||
"useTemplateRef": true, |
|||
"useTemplateRefsList": true, |
|||
"useTextDirection": true, |
|||
"useTextSelection": true, |
|||
"useTextareaAutosize": true, |
|||
"useThrottle": true, |
|||
"useThrottleFn": true, |
|||
"useThrottledRefHistory": true, |
|||
"useTimeAgo": true, |
|||
"useTimeout": true, |
|||
"useTimeoutFn": true, |
|||
"useTimeoutPoll": true, |
|||
"useTimestamp": true, |
|||
"useTitle": true, |
|||
"useToNumber": true, |
|||
"useToString": true, |
|||
"useToggle": true, |
|||
"useTransition": true, |
|||
"useUrlSearchParams": true, |
|||
"useUserMedia": true, |
|||
"useVModel": true, |
|||
"useVModels": true, |
|||
"useVibrate": true, |
|||
"useVirtualList": true, |
|||
"useWakeLock": true, |
|||
"useWebNotification": true, |
|||
"useWebSocket": true, |
|||
"useWebWorker": true, |
|||
"useWebWorkerFn": true, |
|||
"useWindowFocus": true, |
|||
"useWindowScroll": true, |
|||
"useWindowSize": true, |
|||
"watch": true, |
|||
"watchArray": true, |
|||
"watchAtMost": true, |
|||
"watchDebounced": true, |
|||
"watchEffect": true, |
|||
"watchIgnorable": true, |
|||
"watchOnce": true, |
|||
"watchPausable": true, |
|||
"watchPostEffect": true, |
|||
"watchSyncEffect": true, |
|||
"watchThrottled": true, |
|||
"watchTriggerable": true, |
|||
"watchWithFilter": true, |
|||
"whenever": true |
|||
} |
|||
} |
@ -1 +1 @@ |
|||
{"projectName":"trae_8qnxf0if"} |
|||
{"projectName":"trae_zf0uu3bt"} |
@ -1,44 +0,0 @@ |
|||
# 跨域问题解决方案 |
|||
|
|||
## 配置说明 |
|||
|
|||
本项目已配置Vite代理来解决跨域问题。 |
|||
|
|||
### 1. Vite配置 (vite.config.js) |
|||
|
|||
```javascript |
|||
server: { |
|||
host: '0.0.0.0', |
|||
port: 3000, |
|||
proxy: { |
|||
'/api': { |
|||
target: 'https://dbqb.nfdxy.net', |
|||
changeOrigin: true, |
|||
secure: false, |
|||
rewrite: (path) => path.replace(/^\/api/, '/devLotApi/api') |
|||
} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### 2. 请求配置 (src/utils/request.js) |
|||
|
|||
- `baseURL: '/api'` - 设置基础URL为代理路径 |
|||
|
|||
### 3. API调用 (src/api/API.js) |
|||
|
|||
- 使用相对路径 `/prize/list` 而不是完整的URL |
|||
- 实际请求会被代理到 `https://dbqb.nfdxy.net/devLotApi/api/prize/list` |
|||
|
|||
## 工作原理 |
|||
|
|||
1. 前端发起请求到 `/api/prize/list` |
|||
2. Vite开发服务器拦截请求 |
|||
3. 代理将请求转发到 `https://dbqb.nfdxy.net/devLotApi/api/prize/list` |
|||
4. 服务器响应通过代理返回给前端 |
|||
|
|||
## 注意事项 |
|||
|
|||
- 此配置仅在开发环境有效 |
|||
- 生产环境需要在服务器端配置CORS或使用nginx代理 |
|||
- 确保目标服务器允许跨域请求 |
@ -0,0 +1,43 @@ |
|||
import fs from 'fs' |
|||
import path from 'path' |
|||
|
|||
// 移除未使用的导入
|
|||
/** |
|||
* 是否是 dev 环境 |
|||
* @export |
|||
* @param {string} mode |
|||
* @return {boolean} |
|||
*/ |
|||
export function isDevFn(mode) { |
|||
return mode === 'development'; |
|||
} |
|||
|
|||
/** |
|||
* 是否是 prod 环境 |
|||
* @export |
|||
* @param {string} mode |
|||
* @return {boolean} |
|||
*/ |
|||
export function isProdFn(mode) { |
|||
return mode === 'production'; |
|||
} |
|||
|
|||
/** |
|||
* Read all environment variable configuration files to process.env |
|||
*/ |
|||
export function wrapperEnv(envConf) { |
|||
const ret = {}; |
|||
|
|||
for (const envName of Object.keys(envConf)) { |
|||
let realName = envConf[envName].replace(/\\n/g, '\n'); |
|||
realName = realName === 'true' ? true : realName === 'false' ? false : realName; |
|||
|
|||
ret[envName] = realName; |
|||
if (typeof realName === 'string') { |
|||
process.env[envName] = realName; |
|||
} else if (typeof realName === 'object') { |
|||
process.env[envName] = JSON.stringify(realName); |
|||
} |
|||
} |
|||
return ret; |
|||
} |
@ -0,0 +1,44 @@ |
|||
export function createBuild(viteEnv) { |
|||
const { VITE_OUTPUT_DIR } = viteEnv; |
|||
return { |
|||
sourcemap: false, // 是否启用
|
|||
outDir: VITE_OUTPUT_DIR, |
|||
cssCodeSplit: true, // 禁用 CSS 代码拆分,将整个项目中的所有 CSS 将被提取到一个 CSS 文件中
|
|||
brotliSize: false, // 关闭打包计算
|
|||
target: 'esnext', |
|||
minify: 'terser', // 混淆器, terser 构建后文件体积更小, esbuild
|
|||
// 小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项
|
|||
assetsInlineLimit: 4096, |
|||
chunkSizeWarningLimit: 2000, // chunk 大小警告的限制(以 kbs 为单位)
|
|||
assetsDir: 'static', // 静态资源目录
|
|||
// rollup 打包配置
|
|||
rollupOptions: { |
|||
output: { |
|||
chunkFileNames: 'static/js/[name]-[hash].js', |
|||
entryFileNames: 'static/js/[name]-[hash].js', |
|||
assetFileNames: (chunkInfo) => { |
|||
if (chunkInfo.name) { |
|||
const info = chunkInfo.name.split('.'); |
|||
let extType = info[info.length - 1]; |
|||
if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/i.test(chunkInfo.name)) { |
|||
extType = 'media'; |
|||
} else if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(chunkInfo.name)) { |
|||
extType = 'images'; |
|||
} else if (/\.(woff2?|eot|ttf|otf)(\?.*)?$/i.test(chunkInfo.name)) { |
|||
extType = 'fonts'; |
|||
} |
|||
return `static/${extType}/[name]-[hash][extname]`; |
|||
} |
|||
return 'static/[ext]/[name]-[hash].[ext]'; |
|||
} |
|||
} |
|||
}, |
|||
// 压缩配置
|
|||
terserOptions: { |
|||
compress: { |
|||
drop_console: true, // 生产环境移除console
|
|||
drop_debugger: true // 生产环境移除debugger
|
|||
} |
|||
} |
|||
}; |
|||
} |
@ -0,0 +1,26 @@ |
|||
/** |
|||
* Introduces component library styles on demand. |
|||
* https://github.com/antfu/unplugin-auto-import
|
|||
*/ |
|||
import AutoImport from 'unplugin-auto-import/vite' |
|||
|
|||
export function configAutoImportPlugin() { |
|||
return AutoImport({ |
|||
include: [ |
|||
/\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
|
|||
/\.vue$/, |
|||
/\.vue\?vue/, // .vue
|
|||
/\.md$/ // .md
|
|||
], |
|||
imports: ['vue', 'vue-router', '@vueuse/core'], |
|||
// 可以选择auto-import.d.ts生成的位置,使用ts建议设置为'src/auto-import.d.ts'
|
|||
dts: 'src/auto-import.d.ts', |
|||
// eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals
|
|||
// 生成全局声明文件,给eslint用
|
|||
eslintrc: { |
|||
enabled: true, // Default `false`
|
|||
filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
|
|||
globalsPropValue: true // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
|
|||
} |
|||
}) |
|||
} |
@ -0,0 +1,21 @@ |
|||
/** |
|||
* Introduces component library styles on demand. |
|||
* https://github.com/antfu/unplugin-vue-components
|
|||
*/ |
|||
import Components from 'unplugin-vue-components/vite' |
|||
import { VantResolver } from 'unplugin-vue-components/resolvers' |
|||
|
|||
export function configAutoComponentsPlugin() { |
|||
return Components({ |
|||
// 指定组件位置,默认是src/components
|
|||
dirs: ['src/components'], |
|||
extensions: ['vue', 'tsx'], |
|||
// 配置文件生成位置
|
|||
dts: 'src/components.d.ts', |
|||
// 搜索子目录
|
|||
deep: true, |
|||
// 允许子目录作为组件的命名空间前缀。
|
|||
directoryAsNamespace: false |
|||
// include:[]
|
|||
}) |
|||
} |
@ -0,0 +1,37 @@ |
|||
/** |
|||
* Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated |
|||
* https://github.com/anncwb/vite-plugin-compression
|
|||
*/ |
|||
import compressPlugin from 'vite-plugin-compression' |
|||
|
|||
export function configCompressPlugin( |
|||
compress, |
|||
deleteOriginFile = false |
|||
) { |
|||
if (!compress || compress === 'none') { |
|||
return [] |
|||
} |
|||
const compressList = compress.split(',') |
|||
|
|||
const plugins = [] |
|||
|
|||
if (compressList.includes('gzip')) { |
|||
plugins.push( |
|||
compressPlugin({ |
|||
ext: '.gz', |
|||
deleteOriginFile |
|||
}) |
|||
) |
|||
} |
|||
|
|||
if (compressList.includes('brotli')) { |
|||
plugins.push( |
|||
compressPlugin({ |
|||
ext: '.br', |
|||
algorithm: 'brotliCompress', |
|||
deleteOriginFile |
|||
}) |
|||
) |
|||
} |
|||
return plugins |
|||
} |
@ -0,0 +1,37 @@ |
|||
import vue from '@vitejs/plugin-vue' |
|||
import vueJsx from '@vitejs/plugin-vue-jsx' |
|||
// import { configMockPlugin } from './mock'
|
|||
import { configAutoImportPlugin } from './autoImport' |
|||
import { configAutoComponentsPlugin } from './autocomponents' |
|||
import { configCompressPlugin } from './compress' |
|||
|
|||
export function createVitePlugins(viteEnv, isBuild) { |
|||
const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv |
|||
|
|||
const vitePlugins = [ |
|||
// have to
|
|||
vue(), |
|||
// have to
|
|||
vueJsx({ |
|||
// include: /\.(jsx|tsx)/
|
|||
}) |
|||
] |
|||
|
|||
// unplugin-vue-components
|
|||
vitePlugins.push(configAutoComponentsPlugin()) |
|||
|
|||
// unplugin-auto-import
|
|||
vitePlugins.push(configAutoImportPlugin()) |
|||
|
|||
// // vite-plugin-mock
|
|||
// VITE_USE_MOCK && vitePlugins.push(configMockPlugin(isBuild))
|
|||
|
|||
// The following plugins only work in the production environment
|
|||
if (isBuild) { |
|||
// rollup-plugin-gzip
|
|||
vitePlugins.push( |
|||
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE) |
|||
) |
|||
} |
|||
return vitePlugins |
|||
} |
@ -0,0 +1,19 @@ |
|||
/** |
|||
* Mock plugin for development and production. |
|||
* https://github.com/anncwb/vite-plugin-mock
|
|||
*/ |
|||
// import { viteMockServe } from 'vite-plugin-mock'
|
|||
|
|||
// export function configMockPlugin(isBuild: boolean) {
|
|||
// return viteMockServe({
|
|||
// ignore: /^_/,
|
|||
// mockPath: 'mock',
|
|||
// localEnabled: !isBuild,
|
|||
// prodEnabled: isBuild,
|
|||
// injectCode: `
|
|||
// import { setupProdMockServer } from '../mock/_createProductionServer';
|
|||
// setupProdMockServer();
|
|||
// `
|
|||
// })
|
|||
// }
|
|||
export {} |
@ -0,0 +1,43 @@ |
|||
/** |
|||
* Generate proxy |
|||
* @param list |
|||
*/ |
|||
|
|||
export function createProxy() { |
|||
return { |
|||
// 字符串简写写法
|
|||
// '/foo': 'http://localhost:4567',
|
|||
// 选项写法
|
|||
// '/api': {
|
|||
// target: process .env.VITE_APP_API_BASE_URL || 'http://192.168.8.93:3001',
|
|||
// changeOrigin: true,
|
|||
// rewrite: (path) => path.replace(/^\/api/, '')
|
|||
// },
|
|||
// // 全球指数
|
|||
// '/hcm': {
|
|||
// target: process.env.VITE_APP_API_BASE_URL_HCM || 'http://192.168.8.93:3001',
|
|||
// changeOrigin: true,
|
|||
// rewrite: (path) => path.replace(/^\/hcm/, '')
|
|||
// },
|
|||
// // 时空预测
|
|||
// '/pre': {
|
|||
// target: process.env.VITE_APP_API_BASE_URL_AI || 'http://192.168.8.93:3001',
|
|||
// changeOrigin: true,
|
|||
// rewrite: (path) => path.replace(/^\/pre/, '')
|
|||
// }
|
|||
// 正则表达式写法
|
|||
// '^/fallback/.*': {
|
|||
// target: 'http://jsonplaceholder.typicode.com',
|
|||
// changeOrigin: true,
|
|||
// rewrite: (path) => path.replace(/^\/fallback/, '')
|
|||
// }
|
|||
// 使用 proxy 实例
|
|||
// "/api": {
|
|||
// target: "http://jsonplaceholder.typicode.com",
|
|||
// changeOrigin: true,
|
|||
// configure: (proxy, options) => {
|
|||
// // proxy 是 'http-proxy' 的实例
|
|||
// },
|
|||
// },
|
|||
} |
|||
} |
1263
package-lock.json
File diff suppressed because it is too large
View File
@ -0,0 +1,25 @@ |
|||
import request from "../utils/request"; |
|||
const APIurl = import.meta.env.VITE_APP_API_BASE_URL; |
|||
// 开发环境使用代理,生产环境使用环境变量
|
|||
// const APIurl = import.meta.env.DEV ? '/Api' : import.meta.env.VITE_APP_API_BASE_URL;
|
|||
|
|||
export function addRecordAPI(data) { |
|||
return request({ |
|||
url: `${APIurl}/api/funding/addRecord`, |
|||
method: 'post', |
|||
data: data, |
|||
headers: { |
|||
ApiToken: localStorage.getItem('localToken') |
|||
}, |
|||
}) |
|||
} |
|||
// 新增:获取活动信息接口
|
|||
export function getActivity1API() { |
|||
return request({ |
|||
url: `${APIurl}/api/funding/getActivity`, |
|||
method: 'post', |
|||
headers: { |
|||
ApiToken: localStorage.getItem('localToken') |
|||
}, |
|||
}) |
|||
} |
Before Width: 3840 | Height: 2160 | Size: 5.6 MiB After Width: 1920 | Height: 1080 | Size: 492 KiB |
Before Width: 766 | Height: 220 | Size: 144 KiB After Width: 766 | Height: 220 | Size: 43 KiB |
Before Width: 1920 | Height: 1080 | Size: 1.8 MiB |
After Width: 1920 | Height: 1080 | Size: 174 KiB |
After Width: 1292 | Height: 741 | Size: 21 KiB |
After Width: 1320 | Height: 769 | Size: 23 KiB |
After Width: 500 | Height: 500 | Size: 932 KiB |
After Width: 624 | Height: 754 | Size: 92 KiB |
After Width: 402 | Height: 88 | Size: 8.8 KiB |
After Width: 402 | Height: 88 | Size: 11 KiB |
After Width: 852 | Height: 98 | Size: 40 KiB |
After Width: 708 | Height: 267 | Size: 155 KiB |
After Width: 982 | Height: 98 | Size: 16 KiB |
After Width: 390 | Height: 220 | Size: 9.5 KiB |
After Width: 750 | Height: 1624 | Size: 177 KiB |
After Width: 492 | Height: 229 | Size: 14 KiB |
After Width: 571 | Height: 225 | Size: 109 KiB |
After Width: 688 | Height: 1051 | Size: 20 KiB |
After Width: 622 | Height: 938 | Size: 134 KiB |
After Width: 578 | Height: 58 | Size: 831 B |
After Width: 790 | Height: 586 | Size: 25 KiB |
After Width: 100 | Height: 70 | Size: 4.2 KiB |
After Width: 190 | Height: 190 | Size: 17 KiB |
After Width: 1369 | Height: 812 | Size: 185 KiB |
After Width: 402 | Height: 88 | Size: 8.5 KiB |
After Width: 219 | Height: 586 | Size: 29 KiB |
After Width: 228 | Height: 194 | Size: 8.2 KiB |
After Width: 1319 | Height: 773 | Size: 243 KiB |
After Width: 402 | Height: 88 | Size: 9.9 KiB |
Before Width: 383 | Height: 110 | Size: 47 KiB After Width: 383 | Height: 110 | Size: 15 KiB |
@ -1 +0,0 @@ |
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg> |
Before Width: 5760 | Height: 3240 | Size: 867 KiB After Width: 5760 | Height: 3240 | Size: 251 KiB |
@ -0,0 +1,285 @@ |
|||
/* eslint-disable */ |
|||
/* prettier-ignore */ |
|||
// @ts-nocheck
|
|||
// noinspection JSUnusedGlobalSymbols
|
|||
// Generated by unplugin-auto-import
|
|||
// biome-ignore lint: disable
|
|||
export {} |
|||
declare global { |
|||
const EffectScope: typeof import('vue')['EffectScope'] |
|||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] |
|||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] |
|||
const computed: typeof import('vue')['computed'] |
|||
const computedAsync: typeof import('@vueuse/core')['computedAsync'] |
|||
const computedEager: typeof import('@vueuse/core')['computedEager'] |
|||
const computedInject: typeof import('@vueuse/core')['computedInject'] |
|||
const computedWithControl: typeof import('@vueuse/core')['computedWithControl'] |
|||
const controlledComputed: typeof import('@vueuse/core')['controlledComputed'] |
|||
const controlledRef: typeof import('@vueuse/core')['controlledRef'] |
|||
const createApp: typeof import('vue')['createApp'] |
|||
const createEventHook: typeof import('@vueuse/core')['createEventHook'] |
|||
const createGlobalState: typeof import('@vueuse/core')['createGlobalState'] |
|||
const createInjectionState: typeof import('@vueuse/core')['createInjectionState'] |
|||
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn'] |
|||
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] |
|||
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn'] |
|||
const customRef: typeof import('vue')['customRef'] |
|||
const debouncedRef: typeof import('@vueuse/core')['debouncedRef'] |
|||
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch'] |
|||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] |
|||
const defineComponent: typeof import('vue')['defineComponent'] |
|||
const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] |
|||
const effectScope: typeof import('vue')['effectScope'] |
|||
const extendRef: typeof import('@vueuse/core')['extendRef'] |
|||
const getCurrentInstance: typeof import('vue')['getCurrentInstance'] |
|||
const getCurrentScope: typeof import('vue')['getCurrentScope'] |
|||
const h: typeof import('vue')['h'] |
|||
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] |
|||
const inject: typeof import('vue')['inject'] |
|||
const isDefined: typeof import('@vueuse/core')['isDefined'] |
|||
const isProxy: typeof import('vue')['isProxy'] |
|||
const isReactive: typeof import('vue')['isReactive'] |
|||
const isReadonly: typeof import('vue')['isReadonly'] |
|||
const isRef: typeof import('vue')['isRef'] |
|||
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] |
|||
const markRaw: typeof import('vue')['markRaw'] |
|||
const nextTick: typeof import('vue')['nextTick'] |
|||
const onActivated: typeof import('vue')['onActivated'] |
|||
const onBeforeMount: typeof import('vue')['onBeforeMount'] |
|||
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] |
|||
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] |
|||
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] |
|||
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] |
|||
const onClickOutside: typeof import('@vueuse/core')['onClickOutside'] |
|||
const onDeactivated: typeof import('vue')['onDeactivated'] |
|||
const onErrorCaptured: typeof import('vue')['onErrorCaptured'] |
|||
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke'] |
|||
const onLongPress: typeof import('@vueuse/core')['onLongPress'] |
|||
const onMounted: typeof import('vue')['onMounted'] |
|||
const onRenderTracked: typeof import('vue')['onRenderTracked'] |
|||
const onRenderTriggered: typeof import('vue')['onRenderTriggered'] |
|||
const onScopeDispose: typeof import('vue')['onScopeDispose'] |
|||
const onServerPrefetch: typeof import('vue')['onServerPrefetch'] |
|||
const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] |
|||
const onUnmounted: typeof import('vue')['onUnmounted'] |
|||
const onUpdated: typeof import('vue')['onUpdated'] |
|||
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup'] |
|||
const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] |
|||
const provide: typeof import('vue')['provide'] |
|||
const reactify: typeof import('@vueuse/core')['reactify'] |
|||
const reactifyObject: typeof import('@vueuse/core')['reactifyObject'] |
|||
const reactive: typeof import('vue')['reactive'] |
|||
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed'] |
|||
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit'] |
|||
const reactivePick: typeof import('@vueuse/core')['reactivePick'] |
|||
const readonly: typeof import('vue')['readonly'] |
|||
const ref: typeof import('vue')['ref'] |
|||
const refAutoReset: typeof import('@vueuse/core')['refAutoReset'] |
|||
const refDebounced: typeof import('@vueuse/core')['refDebounced'] |
|||
const refDefault: typeof import('@vueuse/core')['refDefault'] |
|||
const refThrottled: typeof import('@vueuse/core')['refThrottled'] |
|||
const refWithControl: typeof import('@vueuse/core')['refWithControl'] |
|||
const resolveComponent: typeof import('vue')['resolveComponent'] |
|||
const resolveRef: typeof import('@vueuse/core')['resolveRef'] |
|||
const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] |
|||
const shallowReactive: typeof import('vue')['shallowReactive'] |
|||
const shallowReadonly: typeof import('vue')['shallowReadonly'] |
|||
const shallowRef: typeof import('vue')['shallowRef'] |
|||
const syncRef: typeof import('@vueuse/core')['syncRef'] |
|||
const syncRefs: typeof import('@vueuse/core')['syncRefs'] |
|||
const templateRef: typeof import('@vueuse/core')['templateRef'] |
|||
const throttledRef: typeof import('@vueuse/core')['throttledRef'] |
|||
const throttledWatch: typeof import('@vueuse/core')['throttledWatch'] |
|||
const toRaw: typeof import('vue')['toRaw'] |
|||
const toReactive: typeof import('@vueuse/core')['toReactive'] |
|||
const toRef: typeof import('vue')['toRef'] |
|||
const toRefs: typeof import('vue')['toRefs'] |
|||
const toValue: typeof import('vue')['toValue'] |
|||
const triggerRef: typeof import('vue')['triggerRef'] |
|||
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] |
|||
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] |
|||
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted'] |
|||
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose'] |
|||
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted'] |
|||
const unref: typeof import('vue')['unref'] |
|||
const unrefElement: typeof import('@vueuse/core')['unrefElement'] |
|||
const until: typeof import('@vueuse/core')['until'] |
|||
const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] |
|||
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery'] |
|||
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter'] |
|||
const useArrayFind: typeof import('@vueuse/core')['useArrayFind'] |
|||
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex'] |
|||
const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast'] |
|||
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin'] |
|||
const useArrayMap: typeof import('@vueuse/core')['useArrayMap'] |
|||
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce'] |
|||
const useArraySome: typeof import('@vueuse/core')['useArraySome'] |
|||
const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique'] |
|||
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue'] |
|||
const useAsyncState: typeof import('@vueuse/core')['useAsyncState'] |
|||
const useAttrs: typeof import('vue')['useAttrs'] |
|||
const useBase64: typeof import('@vueuse/core')['useBase64'] |
|||
const useBattery: typeof import('@vueuse/core')['useBattery'] |
|||
const useBluetooth: typeof import('@vueuse/core')['useBluetooth'] |
|||
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints'] |
|||
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel'] |
|||
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] |
|||
const useCached: typeof import('@vueuse/core')['useCached'] |
|||
const useClipboard: typeof import('@vueuse/core')['useClipboard'] |
|||
const useCloned: typeof import('@vueuse/core')['useCloned'] |
|||
const useColorMode: typeof import('@vueuse/core')['useColorMode'] |
|||
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog'] |
|||
const useCounter: typeof import('@vueuse/core')['useCounter'] |
|||
const useCssModule: typeof import('vue')['useCssModule'] |
|||
const useCssVar: typeof import('@vueuse/core')['useCssVar'] |
|||
const useCssVars: typeof import('vue')['useCssVars'] |
|||
const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement'] |
|||
const useCycleList: typeof import('@vueuse/core')['useCycleList'] |
|||
const useDark: typeof import('@vueuse/core')['useDark'] |
|||
const useDateFormat: typeof import('@vueuse/core')['useDateFormat'] |
|||
const useDebounce: typeof import('@vueuse/core')['useDebounce'] |
|||
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn'] |
|||
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory'] |
|||
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion'] |
|||
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation'] |
|||
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio'] |
|||
const useDevicesList: typeof import('@vueuse/core')['useDevicesList'] |
|||
const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia'] |
|||
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility'] |
|||
const useDraggable: typeof import('@vueuse/core')['useDraggable'] |
|||
const useDropZone: typeof import('@vueuse/core')['useDropZone'] |
|||
const useElementBounding: typeof import('@vueuse/core')['useElementBounding'] |
|||
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint'] |
|||
const useElementHover: typeof import('@vueuse/core')['useElementHover'] |
|||
const useElementSize: typeof import('@vueuse/core')['useElementSize'] |
|||
const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility'] |
|||
const useEventBus: typeof import('@vueuse/core')['useEventBus'] |
|||
const useEventListener: typeof import('@vueuse/core')['useEventListener'] |
|||
const useEventSource: typeof import('@vueuse/core')['useEventSource'] |
|||
const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper'] |
|||
const useFavicon: typeof import('@vueuse/core')['useFavicon'] |
|||
const useFetch: typeof import('@vueuse/core')['useFetch'] |
|||
const useFileDialog: typeof import('@vueuse/core')['useFileDialog'] |
|||
const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess'] |
|||
const useFocus: typeof import('@vueuse/core')['useFocus'] |
|||
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin'] |
|||
const useFps: typeof import('@vueuse/core')['useFps'] |
|||
const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] |
|||
const useGamepad: typeof import('@vueuse/core')['useGamepad'] |
|||
const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] |
|||
const useId: typeof import('vue')['useId'] |
|||
const useIdle: typeof import('@vueuse/core')['useIdle'] |
|||
const useImage: typeof import('@vueuse/core')['useImage'] |
|||
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] |
|||
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver'] |
|||
const useInterval: typeof import('@vueuse/core')['useInterval'] |
|||
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn'] |
|||
const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier'] |
|||
const useLastChanged: typeof import('@vueuse/core')['useLastChanged'] |
|||
const useLink: typeof import('vue-router')['useLink'] |
|||
const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage'] |
|||
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys'] |
|||
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory'] |
|||
const useMediaControls: typeof import('@vueuse/core')['useMediaControls'] |
|||
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] |
|||
const useMemoize: typeof import('@vueuse/core')['useMemoize'] |
|||
const useMemory: typeof import('@vueuse/core')['useMemory'] |
|||
const useModel: typeof import('vue')['useModel'] |
|||
const useMounted: typeof import('@vueuse/core')['useMounted'] |
|||
const useMouse: typeof import('@vueuse/core')['useMouse'] |
|||
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] |
|||
const useMousePressed: typeof import('@vueuse/core')['useMousePressed'] |
|||
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] |
|||
const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] |
|||
const useNetwork: typeof import('@vueuse/core')['useNetwork'] |
|||
const useNow: typeof import('@vueuse/core')['useNow'] |
|||
const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl'] |
|||
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] |
|||
const useOnline: typeof import('@vueuse/core')['useOnline'] |
|||
const usePageLeave: typeof import('@vueuse/core')['usePageLeave'] |
|||
const useParallax: typeof import('@vueuse/core')['useParallax'] |
|||
const usePermission: typeof import('@vueuse/core')['usePermission'] |
|||
const usePointer: typeof import('@vueuse/core')['usePointer'] |
|||
const usePointerLock: typeof import('@vueuse/core')['usePointerLock'] |
|||
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe'] |
|||
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme'] |
|||
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast'] |
|||
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark'] |
|||
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages'] |
|||
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion'] |
|||
const usePrevious: typeof import('@vueuse/core')['usePrevious'] |
|||
const useRafFn: typeof import('@vueuse/core')['useRafFn'] |
|||
const useRefHistory: typeof import('@vueuse/core')['useRefHistory'] |
|||
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver'] |
|||
const useRoute: typeof import('vue-router')['useRoute'] |
|||
const useRouter: typeof import('vue-router')['useRouter'] |
|||
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation'] |
|||
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea'] |
|||
const useScriptTag: typeof import('@vueuse/core')['useScriptTag'] |
|||
const useScroll: typeof import('@vueuse/core')['useScroll'] |
|||
const useScrollLock: typeof import('@vueuse/core')['useScrollLock'] |
|||
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage'] |
|||
const useShare: typeof import('@vueuse/core')['useShare'] |
|||
const useSlots: typeof import('vue')['useSlots'] |
|||
const useSorted: typeof import('@vueuse/core')['useSorted'] |
|||
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition'] |
|||
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis'] |
|||
const useStepper: typeof import('@vueuse/core')['useStepper'] |
|||
const useStorage: typeof import('@vueuse/core')['useStorage'] |
|||
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync'] |
|||
const useStyleTag: typeof import('@vueuse/core')['useStyleTag'] |
|||
const useSupported: typeof import('@vueuse/core')['useSupported'] |
|||
const useSwipe: typeof import('@vueuse/core')['useSwipe'] |
|||
const useTemplateRef: typeof import('vue')['useTemplateRef'] |
|||
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] |
|||
const useTextDirection: typeof import('@vueuse/core')['useTextDirection'] |
|||
const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] |
|||
const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize'] |
|||
const useThrottle: typeof import('@vueuse/core')['useThrottle'] |
|||
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn'] |
|||
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory'] |
|||
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo'] |
|||
const useTimeout: typeof import('@vueuse/core')['useTimeout'] |
|||
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn'] |
|||
const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll'] |
|||
const useTimestamp: typeof import('@vueuse/core')['useTimestamp'] |
|||
const useTitle: typeof import('@vueuse/core')['useTitle'] |
|||
const useToNumber: typeof import('@vueuse/core')['useToNumber'] |
|||
const useToString: typeof import('@vueuse/core')['useToString'] |
|||
const useToggle: typeof import('@vueuse/core')['useToggle'] |
|||
const useTransition: typeof import('@vueuse/core')['useTransition'] |
|||
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams'] |
|||
const useUserMedia: typeof import('@vueuse/core')['useUserMedia'] |
|||
const useVModel: typeof import('@vueuse/core')['useVModel'] |
|||
const useVModels: typeof import('@vueuse/core')['useVModels'] |
|||
const useVibrate: typeof import('@vueuse/core')['useVibrate'] |
|||
const useVirtualList: typeof import('@vueuse/core')['useVirtualList'] |
|||
const useWakeLock: typeof import('@vueuse/core')['useWakeLock'] |
|||
const useWebNotification: typeof import('@vueuse/core')['useWebNotification'] |
|||
const useWebSocket: typeof import('@vueuse/core')['useWebSocket'] |
|||
const useWebWorker: typeof import('@vueuse/core')['useWebWorker'] |
|||
const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn'] |
|||
const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus'] |
|||
const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll'] |
|||
const useWindowSize: typeof import('@vueuse/core')['useWindowSize'] |
|||
const watch: typeof import('vue')['watch'] |
|||
const watchArray: typeof import('@vueuse/core')['watchArray'] |
|||
const watchAtMost: typeof import('@vueuse/core')['watchAtMost'] |
|||
const watchDebounced: typeof import('@vueuse/core')['watchDebounced'] |
|||
const watchEffect: typeof import('vue')['watchEffect'] |
|||
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] |
|||
const watchOnce: typeof import('@vueuse/core')['watchOnce'] |
|||
const watchPausable: typeof import('@vueuse/core')['watchPausable'] |
|||
const watchPostEffect: typeof import('vue')['watchPostEffect'] |
|||
const watchSyncEffect: typeof import('vue')['watchSyncEffect'] |
|||
const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] |
|||
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable'] |
|||
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] |
|||
const whenever: typeof import('@vueuse/core')['whenever'] |
|||
} |
|||
// for type re-export
|
|||
declare global { |
|||
// @ts-ignore
|
|||
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' |
|||
import('vue') |
|||
} |
@ -0,0 +1,14 @@ |
|||
/* eslint-disable */ |
|||
// @ts-nocheck
|
|||
// Generated by unplugin-vue-components
|
|||
// Read more: https://github.com/vuejs/core/pull/3399
|
|||
// biome-ignore lint: disable
|
|||
export {} |
|||
|
|||
/* prettier-ignore */ |
|||
declare module 'vue' { |
|||
export interface GlobalComponents { |
|||
RouterLink: typeof import('vue-router')['RouterLink'] |
|||
RouterView: typeof import('vue-router')['RouterView'] |
|||
} |
|||
} |
1365
src/views/zhongchou/index.vue
File diff suppressed because it is too large
View File
@ -1,23 +1,83 @@ |
|||
import { defineConfig } from 'vite' |
|||
import vue from '@vitejs/plugin-vue' |
|||
// import { defineConfig } from 'vite'
|
|||
// import vue from '@vitejs/plugin-vue'
|
|||
// import path from 'path'
|
|||
|
|||
// // https://vite.dev/config/
|
|||
// // export default defineConfig({
|
|||
// // plugins: [vue()],
|
|||
// // })
|
|||
|
|||
// https://vite.dev/config/
|
|||
// export default defineConfig({
|
|||
// plugins: [vue()],
|
|||
// plugins: [
|
|||
// vue(),
|
|||
// ],
|
|||
// resolve: {
|
|||
// alias: {
|
|||
// '@': path.resolve(process.cwd(), 'src')
|
|||
// }
|
|||
// },
|
|||
// server: {
|
|||
// proxy: {
|
|||
// '/Api': {
|
|||
// target: 'https://dbqb.nfdxy.net/devLotApi',
|
|||
// // target: 'http://localhost:8080',
|
|||
// changeOrigin: true,
|
|||
// rewrite: (path) => path.replace(/^\/Api/, '')
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
// })
|
|||
|
|||
export default defineConfig({ |
|||
plugins: [ |
|||
vue(), |
|||
], |
|||
server: { |
|||
proxy: { |
|||
'/Api': { |
|||
target: 'https://dbqb.nfdxy.net/devLotApi', |
|||
// target: 'http://localhost:8080',
|
|||
changeOrigin: true, |
|||
rewrite: (path) => path.replace(/^\/Api/, '') |
|||
} |
|||
import { defineConfig, loadEnv } from "vite"; |
|||
import pkg from "./package.json"; // 新增包信息导入
|
|||
import dayjs from "dayjs"; // 新增时间库导入
|
|||
import { fileURLToPath, URL } from "url"; // 新增路径处理模块
|
|||
import { wrapperEnv } from "./build/utils"; |
|||
import { createVitePlugins } from "./build/vite/plugin"; |
|||
import { createProxy } from "./build/vite/proxy"; |
|||
import { createBuild } from "./build/vite/build"; |
|||
|
|||
const { dependencies, devDependencies, name, version } = pkg; |
|||
// 应用信息
|
|||
const __APP_INFO__ = { |
|||
pkg: { dependencies, devDependencies, name, version }, |
|||
lastBuildTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), |
|||
}; |
|||
|
|||
// https://vite.dev/config/
|
|||
export default defineConfig(({ command, mode }) => { |
|||
// console.log('command', command)
|
|||
const root = process.cwd(); // 当前工作目录
|
|||
const isBuild = command === "build"; // 是否是构建 serve
|
|||
const env = loadEnv(mode, root); // 加载env环境
|
|||
// The boolean type read by loadEnv is a string. This function can be converted to boolean type
|
|||
const viteEnv = wrapperEnv(env); |
|||
// console.log('viteEnv', viteEnv)
|
|||
|
|||
const { VITE_PUBLIC_PATH, VITE_OUTPUT_DIR } = viteEnv; |
|||
return { |
|||
base: VITE_PUBLIC_PATH, |
|||
root, |
|||
plugins: createVitePlugins(viteEnv, isBuild), |
|||
resolve: { |
|||
alias: { |
|||
"@": fileURLToPath(new URL("./src", import.meta.url)), |
|||
}, |
|||
}, |
|||
css: { |
|||
preprocessorOptions: { |
|||
scss: { |
|||
charset: false, // 避免出现: build时的 @charset 必须在第一行的警告
|
|||
}, |
|||
}, |
|||
}, |
|||
server: { |
|||
host: true, |
|||
proxy: createProxy(), |
|||
}, |
|||
build: createBuild(viteEnv), |
|||
define: { |
|||
__APP_INFO__: JSON.stringify(__APP_INFO__), |
|||
} |
|||
} |
|||
}) |
|||
}; |
|||
}); |
@ -1,98 +0,0 @@ |
|||
# 抽奖逻辑修改完成总结 |
|||
|
|||
## 修改完成情况 |
|||
|
|||
✅ **已完成所有必要的修改** |
|||
|
|||
## 修改文件清单 |
|||
|
|||
### 1. API接口层 (`src/api/API.js`) |
|||
- ✅ 新增 `drawLottery` 接口 |
|||
- ✅ 支持传递奖项信息和轮次参数 |
|||
|
|||
### 2. 抽奖引擎 (`src/views/choujiang/lottery/lotteryEngine.js`) |
|||
- ✅ 修改 `executeLottery` 函数,每轮抽奖请求后端 |
|||
- ✅ 添加错误处理机制,支持回退到前端随机抽奖 |
|||
- ✅ 适配新的数据格式 `{ jwcode: "xxx", username: "xxx" }` |
|||
|
|||
### 3. 数据管理器 (`src/views/choujiang/lottery/dataManager.js`) |
|||
- ✅ 使用真实用户数据替代假数据 |
|||
- ✅ 确保数据格式与后端返回格式兼容 |
|||
- ✅ 支持新旧两种数据格式 |
|||
|
|||
### 4. 3D显示组件 (`src/views/choujiang/lottery/Lottery3D.vue`) |
|||
- ✅ 修改 `changeCard` 函数,适配新的数据格式 |
|||
- ✅ 支持显示 `jwcode` 和 `username` 字段 |
|||
- ✅ 保持向后兼容性 |
|||
|
|||
### 5. 主抽奖页面 (`src/views/choujiang/index.vue`) |
|||
- ✅ 修改气泡提示逻辑,支持新的数据格式 |
|||
- ✅ 确保中奖用户信息正确显示 |
|||
|
|||
## 核心功能 |
|||
|
|||
### 1. 后端抽奖接口 |
|||
```javascript |
|||
// 请求参数 |
|||
{ |
|||
gradeName: "一等奖", |
|||
prizeName: "iPhone 15", |
|||
perWin: 5, |
|||
round: 1 |
|||
} |
|||
|
|||
// 返回数据 |
|||
{ |
|||
data: [ |
|||
{ jwcode: "5412", username: "猪八戒22" }, |
|||
{ jwcode: "45125", username: "宝玉" } |
|||
] |
|||
} |
|||
``` |
|||
|
|||
### 2. 错误处理机制 |
|||
- 后端请求失败时自动回退到前端随机抽奖 |
|||
- 确保抽奖功能不中断 |
|||
- 提供详细的错误日志 |
|||
|
|||
### 3. 数据格式兼容性 |
|||
- 支持新格式:`{ jwcode: "5412", username: "猪八戒22" }` |
|||
- 支持旧格式:`["5412", "猪八戒22", "PSST"]` |
|||
- 自动识别和适配不同格式 |
|||
|
|||
## 工作流程 |
|||
|
|||
1. **页面初始化** → 获取奖品列表和用户列表 |
|||
2. **开始抽奖** → 用户点击抽奖按钮 |
|||
3. **请求后端** → 发送抽奖请求,包含奖项信息和轮次 |
|||
4. **获取结果** → 后端返回中奖用户列表 |
|||
5. **显示动画** → 前端根据返回的中奖用户显示3D抽奖动画 |
|||
6. **保存结果** → 将中奖用户保存到本地状态 |
|||
|
|||
## 测试建议 |
|||
|
|||
1. **正常流程测试**:验证完整的抽奖流程 |
|||
2. **异常处理测试**:模拟后端接口异常 |
|||
3. **数据格式测试**:验证新旧数据格式兼容性 |
|||
4. **多轮抽奖测试**:验证轮次管理和奖品切换 |
|||
5. **性能测试**:验证大量用户数据下的表现 |
|||
|
|||
## 部署注意事项 |
|||
|
|||
1. **后端接口**:确保实现 `/lottery/draw` 接口 |
|||
2. **数据格式**:确保返回的数据格式符合要求 |
|||
3. **错误处理**:建议后端提供详细的错误信息 |
|||
4. **性能优化**:考虑大量并发抽奖请求的处理 |
|||
|
|||
## 后续优化建议 |
|||
|
|||
1. **缓存机制**:可以考虑缓存用户数据,减少重复请求 |
|||
2. **实时更新**:可以考虑WebSocket实时更新中奖结果 |
|||
3. **数据统计**:可以添加抽奖统计和分析功能 |
|||
4. **界面优化**:可以根据实际需求优化3D动画效果 |
|||
|
|||
--- |
|||
|
|||
**修改完成时间**:2024年12月19日 |
|||
**修改状态**:✅ 已完成 |
|||
**测试状态**:🔄 待测试 |
@ -1,92 +0,0 @@ |
|||
# 抽奖逻辑修改说明 |
|||
|
|||
## 修改概述 |
|||
|
|||
本次修改将抽奖逻辑从前端随机抽奖改为每轮抽奖都请求后端获取中奖数据。 |
|||
|
|||
## 主要修改内容 |
|||
|
|||
### 1. API接口修改 (`src/api/API.js`) |
|||
|
|||
新增了 `drawLottery` 接口,用于每轮抽奖时请求后端: |
|||
|
|||
```javascript |
|||
export function drawLottery(data){ |
|||
return request({ |
|||
url: '/lottery/draw', |
|||
method: 'post', |
|||
data: { |
|||
gradeName: data.gradeName, // 奖项名称 |
|||
prizeName: data.prizeName, // 奖品名称 |
|||
perWin: data.perWin, // 每轮抽奖人数 |
|||
round: data.round // 当前轮次 |
|||
} |
|||
}) |
|||
} |
|||
``` |
|||
|
|||
### 2. 抽奖引擎修改 (`src/views/choujiang/lottery/lotteryEngine.js`) |
|||
|
|||
- 修改 `executeLottery` 函数,每轮抽奖都请求后端 |
|||
- 后端返回数据格式:`{ data: [{ jwcode: "5412", username: "猪八戒22" }, ...] }` |
|||
- 添加了错误处理机制,如果后端请求失败会回退到前端随机抽奖 |
|||
|
|||
### 3. 数据管理器修改 (`src/views/choujiang/lottery/dataManager.js`) |
|||
|
|||
- 使用真实的用户数据替代假数据 |
|||
- 确保数据格式与后端返回格式兼容 |
|||
- 用户数据格式:`{ jwcode: "5412", username: "猪八戒22", company: "公司名称" }` |
|||
|
|||
### 4. 3D显示组件修改 (`src/views/choujiang/lottery/Lottery3D.vue`) |
|||
|
|||
- 修改 `changeCard` 函数,适配新的数据格式 |
|||
- 支持显示 `jwcode` 和 `username` 字段 |
|||
|
|||
## 后端接口要求 |
|||
|
|||
### 抽奖接口 `/lottery/draw` |
|||
|
|||
**请求参数:** |
|||
```json |
|||
{ |
|||
"gradeName": "一等奖", |
|||
"prizeName": "iPhone 15", |
|||
"perWin": 5, |
|||
"round": 1 |
|||
} |
|||
``` |
|||
|
|||
**返回数据格式:** |
|||
```json |
|||
{ |
|||
"data": [ |
|||
{ |
|||
"jwcode": "5412", |
|||
"username": "猪八戒22" |
|||
}, |
|||
{ |
|||
"jwcode": "45125", |
|||
"username": "宝玉" |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
## 工作流程 |
|||
|
|||
1. **初始化**:页面加载时获取奖品列表和用户列表 |
|||
2. **开始抽奖**:用户点击抽奖按钮 |
|||
3. **请求后端**:发送抽奖请求到后端,包含奖项信息和轮次 |
|||
4. **获取结果**:后端返回中奖用户列表 |
|||
5. **显示动画**:前端根据返回的中奖用户显示3D抽奖动画 |
|||
6. **保存结果**:将中奖用户保存到本地状态 |
|||
|
|||
## 错误处理 |
|||
|
|||
如果后端抽奖接口请求失败,系统会自动回退到前端随机抽奖逻辑,确保抽奖功能不会中断。 |
|||
|
|||
## 兼容性 |
|||
|
|||
修改后的代码保持了与原有数据格式的兼容性,支持新旧两种数据格式: |
|||
- 新格式:`{ jwcode: "5412", username: "猪八戒22" }` |
|||
- 旧格式:`["5412", "猪八戒22", "PSST"]` |
@ -1,113 +0,0 @@ |
|||
# 抽奖逻辑测试用例 |
|||
|
|||
## 测试环境准备 |
|||
|
|||
1. 确保后端服务正常运行 |
|||
2. 确保以下接口可用: |
|||
- `/prize/list` - 获取奖品列表 |
|||
- `/user/list` - 获取用户列表 |
|||
- `/lottery/draw` - 抽奖接口(新增) |
|||
|
|||
## 测试用例 |
|||
|
|||
### 测试用例1:正常抽奖流程 |
|||
|
|||
**测试步骤:** |
|||
1. 打开抽奖页面 |
|||
2. 点击"进入抽奖"按钮 |
|||
3. 点击"开始抽奖"按钮 |
|||
4. 点击"结束抽奖"按钮 |
|||
5. 观察抽奖结果 |
|||
|
|||
**预期结果:** |
|||
- 页面正常加载,显示奖品列表和用户卡片 |
|||
- 抽奖动画正常播放 |
|||
- 后端返回中奖用户数据 |
|||
- 3D卡片正确显示中奖用户信息(jwcode和username) |
|||
|
|||
### 测试用例2:后端接口异常处理 |
|||
|
|||
**测试步骤:** |
|||
1. 模拟后端抽奖接口返回错误 |
|||
2. 执行抽奖流程 |
|||
3. 观察系统行为 |
|||
|
|||
**预期结果:** |
|||
- 系统自动回退到前端随机抽奖逻辑 |
|||
- 抽奖功能不中断 |
|||
- 控制台显示错误日志 |
|||
|
|||
### 测试用例3:数据格式兼容性 |
|||
|
|||
**测试步骤:** |
|||
1. 使用新数据格式:`{ jwcode: "5412", username: "猪八戒22" }` |
|||
2. 使用旧数据格式:`["5412", "猪八戒22", "PSST"]` |
|||
3. 观察显示效果 |
|||
|
|||
**预期结果:** |
|||
- 两种数据格式都能正确显示 |
|||
- 卡片内容包含jwcode和username信息 |
|||
|
|||
### 测试用例4:多轮抽奖 |
|||
|
|||
**测试步骤:** |
|||
1. 完成第一轮抽奖 |
|||
2. 继续第二轮抽奖 |
|||
3. 观察轮次信息是否正确传递 |
|||
|
|||
**预期结果:** |
|||
- 每轮抽奖都请求后端 |
|||
- 轮次信息正确递增 |
|||
- 中奖用户不重复 |
|||
|
|||
### 测试用例5:奖品切换 |
|||
|
|||
**测试步骤:** |
|||
1. 完成当前奖品的所有轮次抽奖 |
|||
2. 观察是否自动切换到下一个奖品 |
|||
3. 验证新奖品的抽奖逻辑 |
|||
|
|||
**预期结果:** |
|||
- 奖品自动切换 |
|||
- 新奖品的抽奖参数正确传递 |
|||
- 轮次重新开始计算 |
|||
|
|||
## 调试信息 |
|||
|
|||
在浏览器控制台中查看以下日志: |
|||
|
|||
1. **用户数据加载:** |
|||
``` |
|||
userList {data: Array(5)} |
|||
``` |
|||
|
|||
2. **抽奖请求:** |
|||
``` |
|||
请求后端抽奖,参数: {gradeName: "一等奖", prizeName: "iPhone 15", perWin: 5, round: 1} |
|||
``` |
|||
|
|||
3. **后端返回结果:** |
|||
``` |
|||
后端抽奖返回结果: {data: Array(5)} |
|||
后端返回的中奖用户: [{jwcode: "5412", username: "猪八戒22"}, ...] |
|||
``` |
|||
|
|||
4. **卡片选择:** |
|||
``` |
|||
executeLottery - selectedCardIndex: [12, 34, 56, 78, 90] |
|||
executeLottery - currentLuckys: [{jwcode: "5412", username: "猪八戒22"}, ...] |
|||
``` |
|||
|
|||
## 常见问题排查 |
|||
|
|||
### 问题1:抽奖接口404错误 |
|||
**解决方案:** 检查后端是否实现了 `/lottery/draw` 接口 |
|||
|
|||
### 问题2:数据格式不匹配 |
|||
**解决方案:** 检查后端返回的数据格式是否符合 `{data: [{jwcode: "xxx", username: "xxx"}]}` |
|||
|
|||
### 问题3:用户数据为空 |
|||
**解决方案:** 检查 `/user/list` 接口是否正常返回数据 |
|||
|
|||
### 问题4:奖品数据为空 |
|||
**解决方案:** 检查 `/prize/list` 接口是否正常返回数据 |