diff --git a/.gitignore b/.gitignore
index 14456214..41b91f56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,2 @@
# 忽略 software 文件夹及其所有内容
-software/
-
-build/
\ No newline at end of file
+software/
\ No newline at end of file
diff --git a/code/iibta/iibta-vue/.eslintignore b/code/iibta/iibta-vue/.eslintignore
new file mode 100644
index 00000000..c2658d7d
--- /dev/null
+++ b/code/iibta/iibta-vue/.eslintignore
@@ -0,0 +1 @@
+node_modules/
diff --git a/code/iibta/iibta-vue/.eslintrc-auto-import.json b/code/iibta/iibta-vue/.eslintrc-auto-import.json
new file mode 100644
index 00000000..27df73d1
--- /dev/null
+++ b/code/iibta/iibta-vue/.eslintrc-auto-import.json
@@ -0,0 +1,101 @@
+{
+ "globals": {
+ "Component": true,
+ "ComponentPublicInstance": true,
+ "ComputedRef": true,
+ "EffectScope": true,
+ "ExtractDefaultPropTypes": true,
+ "ExtractPropTypes": true,
+ "ExtractPublicPropTypes": true,
+ "InjectionKey": true,
+ "PropType": true,
+ "Ref": true,
+ "VNode": true,
+ "WritableComputedRef": true,
+ "computed": true,
+ "createApp": true,
+ "customRef": true,
+ "defineAsyncComponent": true,
+ "defineComponent": true,
+ "effectScope": true,
+ "getCurrentInstance": true,
+ "getCurrentScope": true,
+ "h": true,
+ "inject": true,
+ "isProxy": true,
+ "isReactive": true,
+ "isReadonly": true,
+ "isRef": true,
+ "markRaw": true,
+ "nextTick": true,
+ "onActivated": true,
+ "onAddToFavorites": true,
+ "onBackPress": true,
+ "onBeforeMount": true,
+ "onBeforeUnmount": true,
+ "onBeforeUpdate": true,
+ "onDeactivated": true,
+ "onError": true,
+ "onErrorCaptured": true,
+ "onHide": true,
+ "onLaunch": true,
+ "onLoad": true,
+ "onMounted": true,
+ "onNavigationBarButtonTap": true,
+ "onNavigationBarSearchInputChanged": true,
+ "onNavigationBarSearchInputClicked": true,
+ "onNavigationBarSearchInputConfirmed": true,
+ "onNavigationBarSearchInputFocusChanged": true,
+ "onPageNotFound": true,
+ "onPageScroll": true,
+ "onPullDownRefresh": true,
+ "onReachBottom": true,
+ "onReady": true,
+ "onRenderTracked": true,
+ "onRenderTriggered": true,
+ "onResize": true,
+ "onScopeDispose": true,
+ "onServerPrefetch": true,
+ "onShareAppMessage": true,
+ "onShareTimeline": true,
+ "onShow": true,
+ "onTabItemTap": true,
+ "onThemeChange": true,
+ "onUnhandledRejection": true,
+ "onUnload": true,
+ "onUnmounted": true,
+ "onUpdated": true,
+ "provide": true,
+ "reactive": true,
+ "readonly": true,
+ "ref": true,
+ "resolveComponent": true,
+ "shallowReactive": true,
+ "shallowReadonly": true,
+ "shallowRef": true,
+ "toRaw": true,
+ "toRef": true,
+ "toRefs": true,
+ "toValue": true,
+ "triggerRef": true,
+ "unref": true,
+ "useAttrs": true,
+ "useCssModule": true,
+ "useCssVars": true,
+ "useRequest": true,
+ "useSlots": true,
+ "useUpload": true,
+ "useUpload2": true,
+ "watch": true,
+ "watchEffect": true,
+ "watchPostEffect": true,
+ "watchSyncEffect": true,
+ "DirectiveBinding": true,
+ "MaybeRef": true,
+ "MaybeRefOrGetter": true,
+ "onWatcherCleanup": true,
+ "useId": true,
+ "useModel": true,
+ "useTemplateRef": true
+ }
+}
diff --git a/code/iibta/iibta-vue/.eslintrc.cjs b/code/iibta/iibta-vue/.eslintrc.cjs
new file mode 100644
index 00000000..78d367b1
--- /dev/null
+++ b/code/iibta/iibta-vue/.eslintrc.cjs
@@ -0,0 +1,27 @@
+module.exports = {
+ root: true,
+ env: {
+ node: true,
+ browser: true,
+ es2021: true,
+ },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:vue/vue3-recommended',
+ 'plugin:prettier/recommended',
+ './.eslintrc-auto-import.json',
+ ],
+ parserOptions: {
+ ecmaVersion: 'latest',
+ parser: '@typescript-eslint/parser',
+ sourceType: 'module',
+ },
+ plugins: ['@typescript-eslint', 'prettier', 'vue'],
+ rules: {
+ 'no-undef': 'off', // 在 Vue 文件中关闭 `no-undef` 规则
+ 'vue/multi-word-component-names': 'off', // 禁用该规则
+ '@typescript-eslint/no-explicit-any': 'warn',
+ 'vue/no-reserved-props': 'off',
+ },
+}
diff --git a/code/iibta/iibta-vue/.prettierignore b/code/iibta/iibta-vue/.prettierignore
new file mode 100644
index 00000000..bb2cd547
--- /dev/null
+++ b/code/iibta/iibta-vue/.prettierignore
@@ -0,0 +1,2 @@
+node_modules/
+src-tauri/
\ No newline at end of file
diff --git a/code/iibta/iibta-vue/.prettierrc.cjs b/code/iibta/iibta-vue/.prettierrc.cjs
new file mode 100644
index 00000000..9c37b4ee
--- /dev/null
+++ b/code/iibta/iibta-vue/.prettierrc.cjs
@@ -0,0 +1,18 @@
+module.exports = {
+ singleQuote: true,
+ printWidth: 100,
+ tabWidth: 2,
+ useTabs: false,
+ semi: false,
+ trailingComma: 'all',
+ endOfLine: 'auto',
+ htmlWhitespaceSensitivity: 'ignore',
+ overrides: [
+ {
+ files: '*.json',
+ options: {
+ trailingComma: 'none',
+ },
+ },
+ ],
+}
diff --git a/code/iibta/iibta-vue/.vscode/extensions.json b/code/iibta/iibta-vue/.vscode/extensions.json
index 0ff6f8e2..8cf43d04 100644
--- a/code/iibta/iibta-vue/.vscode/extensions.json
+++ b/code/iibta/iibta-vue/.vscode/extensions.json
@@ -1,14 +1,7 @@
{
"recommendations": [
- "afzalsayed96.icones",
+ "Vue.volar",
"antfu.iconify",
- "antfu.unocss",
- "dbaeumer.vscode-eslint",
- "editorconfig.editorconfig",
- "esbenp.prettier-vscode",
- "mhutchie.git-graph",
- "mikestead.dotenv",
- "sdras.vue-vscode-snippets",
- "vue.volar",
+ "antfu.unocss"
]
-}
\ No newline at end of file
+}
diff --git a/code/iibta/iibta-vue/.vscode/settings.json b/code/iibta/iibta-vue/.vscode/settings.json
index 837d8615..9a61a595 100644
--- a/code/iibta/iibta-vue/.vscode/settings.json
+++ b/code/iibta/iibta-vue/.vscode/settings.json
@@ -1,22 +1,27 @@
{
+ "editor.cursorSmoothCaretAnimation": "on",
+ "css.validate": false,
+ "less.validate": false,
+ "scss.validate": false,
+
+ // 默认格式化工具选择prettier
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ // 保存的时候自动格式化
+ "editor.formatOnSave": true,
+ //开启自动修复
"editor.codeActionsOnSave": {
+ "source.fixAll": "explicit",
"source.fixAll.eslint": "explicit",
- "source.organizeImports": "never"
+ "source.fixAll.stylelint": "explicit"
},
- "editor.formatOnSave": false,
- "eslint.validate": [
- "html",
- "css",
- "scss",
- "json",
- "jsonc",
- "javascript",
- "javascriptreact",
- "typescript",
- "typescriptreact",
- "vue"
- ],
- "prettier.enable": false,
- "typescript.tsdk": "node_modules/typescript/lib",
- "unocss.root": ["./"]
+ "[vue]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[typescript]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "[jsonc]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode"
+ },
+ "eslint.validate": ["javascript", "javascriptreact", "vue", "typescript", "typescriptreact"]
}
diff --git a/code/iibta/iibta-vue/build/config/index.ts b/code/iibta/iibta-vue/build/config/index.ts
new file mode 100644
index 00000000..e828089d
--- /dev/null
+++ b/code/iibta/iibta-vue/build/config/index.ts
@@ -0,0 +1,12 @@
+import dayjs from 'dayjs'
+import utc from 'dayjs/plugin/utc'
+import timezone from 'dayjs/plugin/timezone'
+
+export function getBuildTime() {
+ dayjs.extend(utc)
+ dayjs.extend(timezone)
+
+ const buildTime = dayjs.tz(Date.now(), 'Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss')
+
+ return buildTime
+}
diff --git a/code/iibta/iibta-vue/build/config/time.ts b/code/iibta/iibta-vue/build/config/time.ts
new file mode 100644
index 00000000..ee29a493
--- /dev/null
+++ b/code/iibta/iibta-vue/build/config/time.ts
@@ -0,0 +1 @@
+export * from './time'
diff --git a/code/iibta/iibta-vue/build/plugins/auto-import.ts b/code/iibta/iibta-vue/build/plugins/auto-import.ts
new file mode 100644
index 00000000..70880be2
--- /dev/null
+++ b/code/iibta/iibta-vue/build/plugins/auto-import.ts
@@ -0,0 +1,34 @@
+import IconsResolver from 'unplugin-icons/resolver'
+import Components from 'unplugin-vue-components/vite'
+import { ArcoResolver } from 'unplugin-vue-components/resolvers'
+import type { PluginOption } from 'vite'
+
+export function setupAutoImport(viteEnv: Env.ImportMeta) {
+ // 从环境变量中提取图标相关的前缀
+ const { VITE_ICON_PREFIX, VITE_ICON_LOCAL_PREFIX } = viteEnv
+
+ // 从本地图标前缀中提取图标集合名称
+ const collectionName = VITE_ICON_LOCAL_PREFIX.replace(`${VITE_ICON_PREFIX}-`, '')
+ const plugins: PluginOption[] = [
+ Components({
+ // 自动导入的组件类型声明文件
+ dts: 'src/types/auto-import.d.ts',
+ types: [
+ {
+ from: 'vue-router',
+ names: ['RouterLink', 'RouterView'],
+ },
+ ],
+
+ // 配置图标解析器
+ resolvers: [
+ IconsResolver({
+ customCollections: [collectionName], // 本地图标集合
+ componentPrefix: VITE_ICON_PREFIX, // 图标组件的前缀
+ }),
+ ArcoResolver(),
+ ],
+ }),
+ ]
+ return plugins
+}
diff --git a/code/iibta/iibta-vue/build/plugins/html.ts b/code/iibta/iibta-vue/build/plugins/html.ts
new file mode 100644
index 00000000..c98b13b0
--- /dev/null
+++ b/code/iibta/iibta-vue/build/plugins/html.ts
@@ -0,0 +1,13 @@
+import type { Plugin } from 'vite'
+
+export function setupHtmlPlugin(buildTime: string) {
+ const plugin: Plugin = {
+ name: 'html-plugin',
+ apply: 'build',
+ transformIndexHtml(html) {
+ return html.replace('
', `\n `)
+ },
+ }
+
+ return plugin
+}
diff --git a/code/iibta/iibta-vue/build/plugins/index.ts b/code/iibta/iibta-vue/build/plugins/index.ts
new file mode 100644
index 00000000..6e4196d5
--- /dev/null
+++ b/code/iibta/iibta-vue/build/plugins/index.ts
@@ -0,0 +1,22 @@
+import type { PluginOption } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import VueDevtools from 'vite-plugin-vue-devtools'
+import progress from 'vite-plugin-progress'
+import { setupUnocss } from './unocss'
+import { setupHtmlPlugin } from './html'
+import { setupUnPluginIcon } from './unplugin-icon'
+import { setupAutoImport } from './auto-import'
+
+export function setupVitePlugins(viteEnv: Env.ImportMeta, buildTime: string) {
+ const plugins: PluginOption = [
+ vue(),
+ VueDevtools(),
+ progress(),
+ setupUnocss(viteEnv),
+ setupHtmlPlugin(buildTime),
+ setupAutoImport(viteEnv),
+ ...setupUnPluginIcon(viteEnv),
+ ]
+
+ return plugins
+}
diff --git a/code/iibta/iibta-vue/build/plugins/unocss.ts b/code/iibta/iibta-vue/build/plugins/unocss.ts
new file mode 100644
index 00000000..c0d4b6b0
--- /dev/null
+++ b/code/iibta/iibta-vue/build/plugins/unocss.ts
@@ -0,0 +1,32 @@
+import process from 'node:process'
+import path from 'node:path'
+import unocss from '@unocss/vite'
+import presetIcons from '@unocss/preset-icons'
+import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
+
+export function setupUnocss(viteEnv: Env.ImportMeta) {
+ const { VITE_ICON_PREFIX, VITE_ICON_LOCAL_PREFIX } = viteEnv
+
+ const localIconPath = path.join(process.cwd(), 'src/assets/svg-icon')
+
+ /** The name of the local icon collection */
+ const collectionName = VITE_ICON_LOCAL_PREFIX.replace(`${VITE_ICON_PREFIX}-`, '')
+
+ return unocss({
+ presets: [
+ presetIcons({
+ prefix: `${VITE_ICON_PREFIX}-`,
+ scale: 1,
+ extraProperties: {
+ display: 'inline-block',
+ },
+ collections: {
+ [collectionName]: FileSystemIconLoader(localIconPath, (svg) =>
+ svg.replace(/^