Compare commits
No commits in common. "main" and "base" have entirely different histories.
36
.github/workflows/auto-merge.yml
vendored
36
.github/workflows/auto-merge.yml
vendored
@ -42,39 +42,3 @@ jobs:
|
|||||||
git checkout base-sard-ui
|
git checkout base-sard-ui
|
||||||
git merge main --no-ff -m "Auto merge main into base-sard-ui"
|
git merge main --no-ff -m "Auto merge main into base-sard-ui"
|
||||||
git push origin base-sard-ui
|
git push origin base-sard-ui
|
||||||
|
|
||||||
merge-to-base-uv-ui:
|
|
||||||
name: Merge main into base-uv-ui
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
token: ${{ secrets.GH_TOKEN_AUTO_MERGE }}
|
|
||||||
|
|
||||||
- name: Merge main into base-uv-ui
|
|
||||||
run: |
|
|
||||||
git config user.name "GitHub Actions"
|
|
||||||
git config user.email "actions@github.com"
|
|
||||||
git checkout base-uv-ui
|
|
||||||
git merge main --no-ff -m "Auto merge main into base-uv-ui"
|
|
||||||
git push origin base-uv-ui
|
|
||||||
|
|
||||||
merge-to-base-uview-plus:
|
|
||||||
name: Merge main into base-uview-plus
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
token: ${{ secrets.GH_TOKEN_AUTO_MERGE }}
|
|
||||||
|
|
||||||
- name: Merge main into base-uview-plus
|
|
||||||
run: |
|
|
||||||
git config user.name "GitHub Actions"
|
|
||||||
git config user.email "actions@github.com"
|
|
||||||
git checkout base-uview-plus
|
|
||||||
git merge main --no-ff -m "Auto merge main into base-uview-plus"
|
|
||||||
git push origin base-uview-plus
|
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -27,7 +27,7 @@ dist
|
|||||||
docs/.vitepress/dist
|
docs/.vitepress/dist
|
||||||
docs/.vitepress/cache
|
docs/.vitepress/cache
|
||||||
|
|
||||||
src/types
|
types
|
||||||
|
|
||||||
# lock 文件还是不要了,我主要的版本写死就好了
|
# lock 文件还是不要了,我主要的版本写死就好了
|
||||||
# pnpm-lock.yaml
|
# pnpm-lock.yaml
|
||||||
|
35
.vscode/settings.json
vendored
35
.vscode/settings.json
vendored
@ -41,7 +41,6 @@
|
|||||||
"tabbar",
|
"tabbar",
|
||||||
"Toutiao",
|
"Toutiao",
|
||||||
"unibest",
|
"unibest",
|
||||||
"uview",
|
|
||||||
"uvui",
|
"uvui",
|
||||||
"Wechat",
|
"Wechat",
|
||||||
"WechatMiniprogram",
|
"WechatMiniprogram",
|
||||||
@ -53,29 +52,29 @@
|
|||||||
"explorer.fileNesting.patterns": {
|
"explorer.fileNesting.patterns": {
|
||||||
"README.md": "index.html,favicon.ico,robots.txt,CHANGELOG.md",
|
"README.md": "index.html,favicon.ico,robots.txt,CHANGELOG.md",
|
||||||
"pages.config.ts": "manifest.config.ts,openapi-ts-request.config.ts",
|
"pages.config.ts": "manifest.config.ts,openapi-ts-request.config.ts",
|
||||||
"package.json": "tsconfig.json,pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,.npmrc,.browserslistrc",
|
"package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,.npmrc,.browserslistrc",
|
||||||
"eslint.config.mjs": ".commitlintrc.*,.prettier*,.editorconfig,.commitlint.cjs,.eslint*"
|
"eslint.config.mjs": "tsconfig.json,.commitlintrc.*,.prettier*,.editorconfig,.commitlint.cjs,.eslint*"
|
||||||
},
|
},
|
||||||
|
|
||||||
// // 保存的时候自动格式化
|
// 保存的时候自动格式化
|
||||||
// "prettier.enable": true,
|
"prettier.enable": true,
|
||||||
// "editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
// // 开启自动修复
|
// 开启自动修复
|
||||||
// "editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
// "source.fixAll": "explicit",
|
"source.fixAll": "explicit",
|
||||||
// "source.fixAll.eslint": "explicit",
|
"source.fixAll.eslint": "explicit",
|
||||||
// "source.fixAll.stylelint": "explicit"
|
"source.fixAll.stylelint": "explicit"
|
||||||
// },
|
},
|
||||||
|
|
||||||
// Disable the default formatter, use eslint instead
|
// Disable the default formatter, use eslint instead
|
||||||
"prettier.enable": false,
|
// "prettier.enable": false,
|
||||||
"editor.formatOnSave": false,
|
// "editor.formatOnSave": false,
|
||||||
|
|
||||||
// Auto fix
|
// Auto fix
|
||||||
"editor.codeActionsOnSave": {
|
// "editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": "explicit",
|
// "source.fixAll.eslint": "explicit",
|
||||||
"source.organizeImports": "never"
|
// "source.organizeImports": "never"
|
||||||
},
|
// },
|
||||||
|
|
||||||
// Silent the stylistic rules in you IDE, but still auto fix them
|
// Silent the stylistic rules in you IDE, but still auto fix them
|
||||||
"eslint.rules.customizations": [
|
"eslint.rules.customizations": [
|
||||||
|
24
.vscode/vue3.code-snippets
vendored
24
.vscode/vue3.code-snippets
vendored
@ -27,12 +27,12 @@
|
|||||||
" },",
|
" },",
|
||||||
"}",
|
"}",
|
||||||
"</route>\n",
|
"</route>\n",
|
||||||
"<script lang=\"ts\" setup>",
|
|
||||||
"//$3",
|
|
||||||
"</script>\n",
|
|
||||||
"<template>",
|
"<template>",
|
||||||
" <view class=\"\">$2</view>",
|
" <view class=\"\">$2</view>",
|
||||||
"</template>\n",
|
"</template>\n",
|
||||||
|
"<script lang=\"ts\" setup>",
|
||||||
|
"//$3",
|
||||||
|
"</script>\n",
|
||||||
"<style lang=\"scss\" scoped>",
|
"<style lang=\"scss\" scoped>",
|
||||||
"//$4",
|
"//$4",
|
||||||
"</style>\n",
|
"</style>\n",
|
||||||
@ -41,28 +41,16 @@
|
|||||||
"Print unibest style": {
|
"Print unibest style": {
|
||||||
"scope": "vue",
|
"scope": "vue",
|
||||||
"prefix": "st",
|
"prefix": "st",
|
||||||
"body": [
|
"body": ["<style lang=\"scss\" scoped>", "//", "</style>\n"],
|
||||||
"<style lang=\"scss\" scoped>",
|
|
||||||
"//",
|
|
||||||
"</style>\n"
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
"Print unibest script": {
|
"Print unibest script": {
|
||||||
"scope": "vue",
|
"scope": "vue",
|
||||||
"prefix": "sc",
|
"prefix": "sc",
|
||||||
"body": [
|
"body": ["<script lang=\"ts\" setup>", "//$3", "</script>\n"],
|
||||||
"<script lang=\"ts\" setup>",
|
|
||||||
"//$3",
|
|
||||||
"</script>\n"
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
"Print unibest template": {
|
"Print unibest template": {
|
||||||
"scope": "vue",
|
"scope": "vue",
|
||||||
"prefix": "te",
|
"prefix": "te",
|
||||||
"body": [
|
"body": ["<template>", " <view class=\"\">$1</view>", "</template>\n"],
|
||||||
"<template>",
|
|
||||||
" <view class=\"\">$1</view>",
|
|
||||||
"</template>\n"
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "unibest",
|
"name": "unibest",
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"version": "3.1.0",
|
"version": "3.0.0",
|
||||||
"description": "unibest - 最好的 uniapp 开发模板",
|
"description": "unibest - 最好的 uniapp 开发模板",
|
||||||
"update-time": "2025-06-21",
|
"update-time": "2025-06-21",
|
||||||
"author": {
|
"author": {
|
||||||
@ -98,6 +98,7 @@
|
|||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"pinia": "2.0.36",
|
"pinia": "2.0.36",
|
||||||
"pinia-plugin-persistedstate": "3.2.1",
|
"pinia-plugin-persistedstate": "3.2.1",
|
||||||
|
"qs": "6.5.3",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
"wot-design-uni": "^1.9.1",
|
"wot-design-uni": "^1.9.1",
|
||||||
"z-paging": "2.8.7"
|
"z-paging": "2.8.7"
|
||||||
|
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@ -82,6 +82,9 @@ importers:
|
|||||||
pinia-plugin-persistedstate:
|
pinia-plugin-persistedstate:
|
||||||
specifier: 3.2.1
|
specifier: 3.2.1
|
||||||
version: 3.2.1(pinia@2.0.36(typescript@5.7.2)(vue@3.5.15(typescript@5.7.2)))
|
version: 3.2.1(pinia@2.0.36(typescript@5.7.2)(vue@3.5.15(typescript@5.7.2)))
|
||||||
|
qs:
|
||||||
|
specifier: 6.5.3
|
||||||
|
version: 6.5.3
|
||||||
vue:
|
vue:
|
||||||
specifier: ^3.4.21
|
specifier: ^3.4.21
|
||||||
version: 3.5.15(typescript@5.7.2)
|
version: 3.5.15(typescript@5.7.2)
|
||||||
@ -5437,6 +5440,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
|
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
|
||||||
engines: {node: '>=0.6'}
|
engines: {node: '>=0.6'}
|
||||||
|
|
||||||
|
qs@6.5.3:
|
||||||
|
resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==}
|
||||||
|
engines: {node: '>=0.6'}
|
||||||
|
|
||||||
quansync@0.2.10:
|
quansync@0.2.10:
|
||||||
resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==}
|
resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==}
|
||||||
|
|
||||||
@ -13250,6 +13257,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
side-channel: 1.0.6
|
side-channel: 1.0.6
|
||||||
|
|
||||||
|
qs@6.5.3: {}
|
||||||
|
|
||||||
quansync@0.2.10: {}
|
quansync@0.2.10: {}
|
||||||
|
|
||||||
querystringify@2.2.0: {}
|
querystringify@2.2.0: {}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { ICaptcha, IUpdateInfo, IUpdatePassword, IUserInfoVo, IUserLogin } from './types/login'
|
import type { ICaptcha, IUpdateInfo, IUpdatePassword, IUserInfoVo, IUserLogin } from './login.typings'
|
||||||
import { http } from '@/utils/http'
|
import { http } from '@/utils/http'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
3
src/env.d.ts
vendored
3
src/env.d.ts
vendored
@ -29,6 +29,3 @@ interface ImportMetaEnv {
|
|||||||
interface ImportMeta {
|
interface ImportMeta {
|
||||||
readonly env: ImportMetaEnv
|
readonly env: ImportMetaEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const __VITE_APP_PROXY__: 'true' | 'false'
|
|
||||||
declare const __UNI_PLATFORM__: 'app' | 'h5' | 'mp-alipay' | 'mp-baidu' | 'mp-kuaishou' | 'mp-lark' | 'mp-qq' | 'mp-tiktok' | 'mp-weixin' | 'mp-xiaochengxu'
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
import qs from 'qs'
|
||||||
import { useUserStore } from '@/store'
|
import { useUserStore } from '@/store'
|
||||||
import { getEnvBaseUrl } from '@/utils'
|
import { getEnvBaseUrl } from '@/utils'
|
||||||
import { platform } from '@/utils/platform'
|
import { platform } from '@/utils/platform'
|
||||||
import { stringifyQuery } from '@/utils/queryString'
|
|
||||||
|
|
||||||
export type CustomRequestOptions = UniApp.RequestOptions & {
|
export type CustomRequestOptions = UniApp.RequestOptions & {
|
||||||
query?: Record<string, any>
|
query?: Record<string, any>
|
||||||
@ -18,7 +18,7 @@ const httpInterceptor = {
|
|||||||
invoke(options: CustomRequestOptions) {
|
invoke(options: CustomRequestOptions) {
|
||||||
// 接口请求支持通过 query 参数配置 queryString
|
// 接口请求支持通过 query 参数配置 queryString
|
||||||
if (options.query) {
|
if (options.query) {
|
||||||
const queryStr = stringifyQuery(options.query)
|
const queryStr = qs.stringify(options.query)
|
||||||
if (options.url.includes('?')) {
|
if (options.url.includes('?')) {
|
||||||
options.url += `&${queryStr}`
|
options.url += `&${queryStr}`
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
# tabbar 说明
|
# tabbar 说明
|
||||||
|
|
||||||
`tabbar` 分为 `4 种` 情况:
|
tabbar 分为4种情况:
|
||||||
|
|
||||||
- `完全原生 tabbar`,使用 `switchTab` 切换 tabbar,`tabbar` 页面有缓存。
|
- 完全原生tabbar,使用 switchTab 切换 tabbar,tabbar页面有缓存。
|
||||||
- 优势:原生自带的tabbar,最先渲染,有缓存。
|
- 优势:原生自带的tabbar,最先渲染,有缓存。
|
||||||
- 劣势:只能使用2组图片来切换选中和非选中状态,修改颜色只能重新换图片(或者用iconfont)。
|
- 劣势:只能使用2组图片来切换选中和非选中状态,修改颜色只能重新换图片(或者用iconfont)。
|
||||||
- `半自定义 tabbar`,使用 `switchTab` 切换 tabbar,`tabbar` 页面有缓存。使用了第三方 UI 库的 `tabbar` 组件,并隐藏了原生 `tabbar` 的显示。
|
- 半自定义tabbar,使用 switchTab 切换 tabbar,tabbar页面有缓存。使用了第三方UI库的 tabbar 组件,并隐藏了原生 tabbar 的显示。
|
||||||
- 优势:可以随意配置自己想要的 `svg icon`,切换字体颜色方便。有缓存。可以实现各种花里胡哨的动效等。
|
- 优势:可以随意配置自己想要的 svg icon,切换字体颜色方便。有缓存。可以实现各种花里胡哨的动效等。
|
||||||
- 劣势:首次点击tababr会闪烁。
|
- 劣势:首次点击tababr会闪烁。
|
||||||
- `全自定义 tabbar`,使用 `navigateTo` 切换 `tabbar`,`tabbar` 页面无缓存。使用了第三方 UI 库的 `tabbar` 组件。
|
- 全自定义tabbar,使用 navigateTo 切换tabbar,tabbar页面无缓存。使用了第三方UI库的 tabbar 组件。
|
||||||
- 优势:可以随意配置自己想要的 svg icon,切换字体颜色方便。可以实现各种花里胡哨的动效等。
|
- 优势:可以随意配置自己想要的 svg icon,切换字体颜色方便。可以实现各种花里胡哨的动效等。
|
||||||
- 劣势:首次点击 `tababr` 会闪烁,无缓存。
|
- 劣势:首次点击tababr会闪烁,无缓存。
|
||||||
- `无 tabbar`,只有一个页面入口,底部无 `tabbar` 显示;常用语临时活动页。
|
- 无tabbar,只有一个页面入口,底部无tabbar显示;常用语临时活动页。
|
||||||
|
|
||||||
> 注意:花里胡哨的效果需要自己实现,本模版不提供。
|
> 注意:花里胡哨的效果需要自己实现,本模版不提供。
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* tabbar 选择的策略,更详细的介绍见 tabbar.md 文件
|
* tabbar 选择的策略,更详细的介绍见 tabbar.md 文件
|
||||||
* 0: 'NATIVE_TABBAR' `完全原生 tabbar`
|
* 0: 'NATIVE_TABBAR'
|
||||||
* 2: 'FULL_CUSTOM_TABBAR' `全自定义 tabbar`
|
* 2: 'FULL_CUSTOM_TABBAR'
|
||||||
* 1: 'HALF_CUSTOM_TABBAR' `半自定义 tabbar`
|
* 1: 'HALF_CUSTOM_TABBAR'
|
||||||
* 3: 'NO_TABBAR' `无 tabbar`
|
* 3: 'NO_TABBAR'
|
||||||
*
|
*
|
||||||
* 温馨提示:本文件的任何代码更改了之后,都需要重新运行,否则 pages.json 不会更新导致错误
|
* 温馨提示:本文件的任何代码更改了之后,都需要重新运行,否则 pages.json 不会更新导致错误
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
"pagePath": "pages/index/index",
|
"pagePath": "pages/index/index",
|
||||||
"text": "首页",
|
"text": "首页",
|
||||||
"icon": "home",
|
"icon": "home",
|
||||||
"iconType": "uiLib"
|
"iconType": "wot"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"iconPath": "static/tabbar/example.png",
|
"iconPath": "static/tabbar/example.png",
|
||||||
|
@ -53,7 +53,7 @@ console.log('index')
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="bg-white px-4 pt-2" :style="{ marginTop: `${safeAreaInsets?.top}px` }">
|
<view class="bg-white px-4 pt-2" :style="{ marginTop: `${safeAreaInsets?.top}px` }">
|
||||||
<view class="mt-10">
|
<view class="mt-12">
|
||||||
<image src="/static/logo.svg" alt="" class="mx-auto block h-28 w-28" />
|
<image src="/static/logo.svg" alt="" class="mx-auto block h-28 w-28" />
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-4 text-center text-4xl text-[#d14328]">
|
<view class="mt-4 text-center text-4xl text-[#d14328]">
|
||||||
@ -66,19 +66,6 @@ console.log('index')
|
|||||||
<view class="m-auto mb-2 max-w-100 text-justify indent text-4">
|
<view class="m-auto mb-2 max-w-100 text-justify indent text-4">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
</view>
|
</view>
|
||||||
<view class="mt-4 text-center">
|
|
||||||
作者:
|
|
||||||
<text class="text-green-500">
|
|
||||||
菲鸽
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
<view class="mt-4 text-center">
|
|
||||||
官网地址:
|
|
||||||
<text class="text-green-500">
|
|
||||||
https://unibest.tech
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
<view class="mt-6 h-1px bg-#eee" />
|
|
||||||
<view class="mt-8 text-center">
|
<view class="mt-8 text-center">
|
||||||
当前平台是:
|
当前平台是:
|
||||||
<text class="text-green-500">
|
<text class="text-green-500">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { IUserInfoVo } from '@/api/types/login'
|
import type { IUserInfoVo } from '@/api/login.typings'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import {
|
import {
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
* 将对象序列化为URL查询字符串,用于替代第三方的 qs 库,节省宝贵的体积
|
|
||||||
* 支持基本类型值和数组,不支持嵌套对象
|
|
||||||
* @param obj 要序列化的对象
|
|
||||||
* @returns 序列化后的查询字符串
|
|
||||||
*/
|
|
||||||
export function stringifyQuery(obj: Record<string, any>): string {
|
|
||||||
if (!obj || typeof obj !== 'object' || Array.isArray(obj))
|
|
||||||
return ''
|
|
||||||
|
|
||||||
return Object.entries(obj)
|
|
||||||
.filter(([_, value]) => value !== undefined && value !== null)
|
|
||||||
.map(([key, value]) => {
|
|
||||||
// 对键进行编码
|
|
||||||
const encodedKey = encodeURIComponent(key)
|
|
||||||
|
|
||||||
// 处理数组类型
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
return value
|
|
||||||
.filter(item => item !== undefined && item !== null)
|
|
||||||
.map(item => `${encodedKey}=${encodeURIComponent(item)}`)
|
|
||||||
.join('&')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理基本类型
|
|
||||||
return `${encodedKey}=${encodeURIComponent(value)}`
|
|
||||||
})
|
|
||||||
.join('&')
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user