Bladeren bron

Merge branch 'base'

Burt 1 jaar geleden
bovenliggende
commit
3635b7801a

+ 41 - 0
.github/workflows/auto-merge.yml

@@ -0,0 +1,41 @@
+name: Auto Merge Base to Other Branches
+
+on:
+  push:
+    branches:
+      - base
+  workflow_dispatch: # 手动触发
+
+jobs:
+  auto-merge:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v3
+        with:
+          fetch-depth: 0
+          token: ${{ secrets.GH_TOKEN_AUTO_MERGE }}
+
+      - name: Merge base into main
+        run: |
+          git config user.name "GitHub Actions"
+          git config user.email "actions@github.com"
+          git checkout main
+          git merge base --no-ff -m "Auto merge base into main"
+          git push origin main
+
+      - name: Merge base into i18n
+        run: |
+          git config user.name "GitHub Actions"
+          git config user.email "actions@github.com"
+          git checkout i18n
+          git merge base --no-ff -m "Auto merge base into i18n"
+          git push origin i18n
+
+      - name: Merge base into tabbar
+        run: |
+          git config user.name "GitHub Actions"
+          git config user.email "actions@github.com"
+          git checkout tabbar
+          git merge base --no-ff -m "Auto merge base into tabbar"
+          git push origin tabbar

+ 3 - 0
.prettierignore

@@ -7,3 +7,6 @@ uni-pages.d.ts
 # 插件生成的文件
 src/pages.json
 src/manifest.json
+
+# 忽略自动生成文件
+src/service/app/**

+ 1 - 12
.vscode/settings.json

@@ -53,16 +53,5 @@
     "WechatMiniprogram",
     "Weixin"
   ],
-  "typescript.tsdk": "node_modules\\typescript\\lib",
-  // 控制相关文件嵌套展示
-  "explorer.fileNesting.enabled": true,
-  "explorer.fileNesting.expand": false,
-  "explorer.fileNesting.patterns": {
-    "*.ts": "$(capture).test.ts, $(capture).test.tsx",
-    "*.tsx": "$(capture).test.ts, $(capture).test.tsx",
-    // "*.env": "$(capture).env.*",
-    "CHANGELOG.md": "CHANGELOG*",
-    "package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,.npmrc,.browserslistrc",
-    ".eslintrc.cjs": ".eslintignore,.prettierignore,.stylelintignore,.commitlintrc.*,.prettierrc.*,.stylelintrc.*,.eslintrc-auto-import.json,.editorconfig,.commitlint.cjs"
-  }
+  "typescript.tsdk": "node_modules\\typescript\\lib"
 }

+ 8 - 0
README.md

@@ -45,6 +45,14 @@
 
 注意旧的地址 [codercup](https://github.com/codercup/unibest) 我进不去了,使用新的 [feige996](https://github.com/feige996/unibest)。PR和 issue 也请使用新地址,否则无法合并。
 
+## 平台兼容性
+
+| H5  | IOS | 安卓 | 微信小程序 | 字节小程序 | 快手小程序 | 支付宝小程序 | 钉钉小程序 | 百度小程序 |
+| --- | --- | ---- | ---------- | ---------- | ---------- | ------------ | ---------- | ---------- |
+| √   | √   | √    | √          | √          | √          | √            | √          | √          |
+
+注意每种 `UI框架` 支持的平台有所不同,详情请看各 `UI框架` 的官网,也可以看 `unibest` 文档。
+
 ## ⚙️ 环境
 
 - node>=18

+ 11 - 0
openapi-ts-request.config.ts

@@ -0,0 +1,11 @@
+import type { GenerateServiceProps } from 'openapi-ts-request'
+
+export default [
+  {
+    schemaPath: 'http://petstore.swagger.io/v2/swagger.json',
+    serversPath: './src/service/app',
+    requestLibPath: `import { request } from '@/utils/http';\n import { CustomRequestOptions } from '@/interceptors/request';`,
+    requestOptionsType: 'CustomRequestOptions',
+    isGenJavaScript: false,
+  },
+] as GenerateServiceProps[]

+ 5 - 1
package.json

@@ -73,7 +73,8 @@
     "prepare": "git init && husky install ",
     "type-check": "vue-tsc --noEmit",
     "release": "standard-version",
-    "cz": "czg"
+    "cz": "czg",
+    "openapi-ts-request": "openapi-ts"
   },
   "lint-staged": {
     "**/*.{html,vue,ts,cjs,json,md}": [
@@ -105,6 +106,8 @@
     "@dcloudio/uni-mp-weixin": "3.0.0-4020920240930001",
     "@dcloudio/uni-mp-xhs": "3.0.0-4020920240930001",
     "@dcloudio/uni-quickapp-webview": "3.0.0-4020920240930001",
+    "@tanstack/vue-query": "^5.62.16",
+    "abortcontroller-polyfill": "^1.7.8",
     "dayjs": "1.11.10",
     "pinia": "2.0.36",
     "pinia-plugin-persistedstate": "3.2.1",
@@ -150,6 +153,7 @@
     "eslint-plugin-vue": "^9.32.0",
     "husky": "^8.0.3",
     "lint-staged": "^15.2.10",
+    "openapi-ts-request": "^1.0.1",
     "postcss": "^8.4.49",
     "postcss-html": "^1.7.0",
     "postcss-scss": "^4.0.9",

File diff suppressed because it is too large
+ 1174 - 185
pnpm-lock.yaml


+ 2 - 1
src/App.vue

@@ -1,5 +1,6 @@
 <script setup lang="ts">
-import { onHide, onLaunch, onShow } from '@dcloudio/uni-app'
+import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
+import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
 
 onLaunch(() => {
   console.log('App Launch')

+ 4 - 1
src/main.ts

@@ -1,10 +1,11 @@
 import '@/style/index.scss'
+import { VueQueryPlugin } from '@tanstack/vue-query'
 import 'virtual:uno.css'
 import { createSSRApp } from 'vue'
+
 import App from './App.vue'
 import { prototypeInterceptor, requestInterceptor, routeInterceptor } from './interceptors'
 import store from './store'
-// 测试 standard-version: feature
 
 export function createApp() {
   const app = createSSRApp(App)
@@ -12,6 +13,8 @@ export function createApp() {
   app.use(routeInterceptor)
   app.use(requestInterceptor)
   app.use(prototypeInterceptor)
+  app.use(VueQueryPlugin)
+
   return {
     app,
   }

+ 16 - 0
src/pages/about/components/request.vue

@@ -37,6 +37,8 @@
 
 <script lang="ts" setup>
 import { getFooAPI, postFooAPI, IFooItem } from '@/service/index/foo'
+import { findPetsByStatus } from '@/service/app'
+import { useQuery } from '@tanstack/vue-query'
 
 const recommendUrl = ref('http://laf.run/signup?code=ohaOgIX')
 
@@ -50,6 +52,20 @@ const { loading, error, data, run } = useRequest<IFooItem>(() => getFooAPI('菲
   immediate: true,
   initialData,
 })
+
+// 使用 vue-query 的 useQuery 来请求数据,只做参考,是否使用请根据实际情况而定
+const {
+  data: data2,
+  error: error2,
+  isLoading: isLoading2,
+  refetch,
+} = useQuery({
+  queryKey: ['findPetsByStatus'],
+  queryFn: () => {
+    return findPetsByStatus({ params: { status: ['available'] } })
+  },
+})
+
 const reset = () => {
   data.value = initialData
 }

+ 11 - 0
src/service/app/displayEnumLabel.ts

@@ -0,0 +1,11 @@
+/* eslint-disable */
+// @ts-ignore
+import * as API from './types'
+
+export function displayStatusEnum(field: API.IStatusEnum) {
+  return { available: 'available', pending: 'pending', sold: 'sold' }[field]
+}
+
+export function displayStatusEnum2(field: API.IStatusEnum2) {
+  return { placed: 'placed', approved: 'approved', delivered: 'delivered' }[field]
+}

+ 8 - 0
src/service/app/index.ts

@@ -0,0 +1,8 @@
+/* eslint-disable */
+// @ts-ignore
+export * from './types'
+export * from './displayEnumLabel'
+
+export * from './pet'
+export * from './store'
+export * from './user'

+ 187 - 0
src/service/app/pet.ts

@@ -0,0 +1,187 @@
+/* eslint-disable */
+// @ts-ignore
+import { request } from '@/utils/http'
+import { CustomRequestOptions } from '@/interceptors/request'
+
+import * as API from './types'
+
+/** Update an existing pet PUT /pet */
+export async function updatePet({
+  body,
+  options,
+}: {
+  body: API.Pet
+  options?: CustomRequestOptions
+}) {
+  return request<unknown>('/pet', {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    data: body,
+    ...(options || {}),
+  })
+}
+
+/** Add a new pet to the store POST /pet */
+export async function addPet({ body, options }: { body: API.Pet; options?: CustomRequestOptions }) {
+  return request<unknown>('/pet', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    data: body,
+    ...(options || {}),
+  })
+}
+
+/** Find pet by ID Returns a single pet GET /pet/${param0} */
+export async function getPetById({
+  params,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.getPetByIdParams
+  options?: CustomRequestOptions
+}) {
+  const { petId: param0, ...queryParams } = params
+
+  return request<API.Pet>(`/pet/${param0}`, {
+    method: 'GET',
+    params: { ...queryParams },
+    ...(options || {}),
+  })
+}
+
+/** Updates a pet in the store with form data POST /pet/${param0} */
+export async function updatePetWithForm({
+  params,
+  body,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.updatePetWithFormParams
+  body: {
+    /** Updated name of the pet */
+    name?: string
+    /** Updated status of the pet */
+    status?: string
+  }
+  options?: CustomRequestOptions
+}) {
+  const { petId: param0, ...queryParams } = params
+
+  return request<unknown>(`/pet/${param0}`, {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/x-www-form-urlencoded',
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {}),
+  })
+}
+
+/** Deletes a pet DELETE /pet/${param0} */
+export async function deletePet({
+  params,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.deletePetParams
+  options?: CustomRequestOptions
+}) {
+  const { petId: param0, ...queryParams } = params
+
+  return request<unknown>(`/pet/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {}),
+  })
+}
+
+/** uploads an image POST /pet/${param0}/uploadImage */
+export async function uploadFile({
+  params,
+  body,
+  file,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.uploadFileParams
+  body: {
+    /** Additional data to pass to server */
+    additionalMetadata?: string
+  }
+  file?: File
+  options?: CustomRequestOptions
+}) {
+  const { petId: param0, ...queryParams } = params
+  const formData = new FormData()
+
+  if (file) {
+    formData.append('file', file)
+  }
+
+  Object.keys(body).forEach((ele) => {
+    const item = (body as { [key: string]: any })[ele]
+
+    if (item !== undefined && item !== null) {
+      if (typeof item === 'object' && !(item instanceof File)) {
+        if (item instanceof Array) {
+          item.forEach((f) => formData.append(ele, f || ''))
+        } else {
+          formData.append(ele, JSON.stringify(item))
+        }
+      } else {
+        formData.append(ele, item)
+      }
+    }
+  })
+
+  return request<API.ApiResponse>(`/pet/${param0}/uploadImage`, {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'multipart/form-data',
+    },
+    params: { ...queryParams },
+    data: formData,
+    ...(options || {}),
+  })
+}
+
+/** Finds Pets by status Multiple status values can be provided with comma separated strings GET /pet/findByStatus */
+export async function findPetsByStatus({
+  params,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.findPetsByStatusParams
+  options?: CustomRequestOptions
+}) {
+  return request<API.Pet[]>('/pet/findByStatus', {
+    method: 'GET',
+    params: {
+      ...params,
+    },
+    ...(options || {}),
+  })
+}
+
+/** Finds Pets by tags Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. GET /pet/findByTags */
+export async function findPetsByTags({
+  params,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.findPetsByTagsParams
+  options?: CustomRequestOptions
+}) {
+  return request<API.Pet[]>('/pet/findByTags', {
+    method: 'GET',
+    params: {
+      ...params,
+    },
+    ...(options || {}),
+  })
+}

+ 68 - 0
src/service/app/store.ts

@@ -0,0 +1,68 @@
+/* eslint-disable */
+// @ts-ignore
+import { request } from '@/utils/http'
+import { CustomRequestOptions } from '@/interceptors/request'
+
+import * as API from './types'
+
+/** Returns pet inventories by status Returns a map of status codes to quantities GET /store/inventory */
+export async function getInventory({ options }: { options?: CustomRequestOptions }) {
+  return request<Record<string, unknown>>('/store/inventory', {
+    method: 'GET',
+    ...(options || {}),
+  })
+}
+
+/** Place an order for a pet POST /store/order */
+export async function placeOrder({
+  body,
+  options,
+}: {
+  body: API.Order
+  options?: CustomRequestOptions
+}) {
+  return request<API.Order>('/store/order', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    data: body,
+    ...(options || {}),
+  })
+}
+
+/** Find purchase order by ID For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions GET /store/order/${param0} */
+export async function getOrderById({
+  params,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.getOrderByIdParams
+  options?: CustomRequestOptions
+}) {
+  const { orderId: param0, ...queryParams } = params
+
+  return request<API.Order>(`/store/order/${param0}`, {
+    method: 'GET',
+    params: { ...queryParams },
+    ...(options || {}),
+  })
+}
+
+/** Delete purchase order by ID For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors DELETE /store/order/${param0} */
+export async function deleteOrder({
+  params,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.deleteOrderParams
+  options?: CustomRequestOptions
+}) {
+  const { orderId: param0, ...queryParams } = params
+
+  return request<unknown>(`/store/order/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {}),
+  })
+}

+ 128 - 0
src/service/app/types.ts

@@ -0,0 +1,128 @@
+/* eslint-disable */
+// @ts-ignore
+
+export type ApiResponse = {
+  code?: number
+  type?: string
+  message?: string
+}
+
+export type Category = {
+  id?: number
+  name?: string
+}
+
+export type deleteOrderParams = {
+  /** ID of the order that needs to be deleted */
+  orderId: number
+}
+
+export type deletePetParams = {
+  /** Pet id to delete */
+  petId: number
+}
+
+export type deleteUserParams = {
+  /** The name that needs to be deleted */
+  username: string
+}
+
+export type findPetsByStatusParams = {
+  /** Status values that need to be considered for filter */
+  status: ('available' | 'pending' | 'sold')[]
+}
+
+export type findPetsByTagsParams = {
+  /** Tags to filter by */
+  tags: string[]
+}
+
+export type getOrderByIdParams = {
+  /** ID of pet that needs to be fetched */
+  orderId: number
+}
+
+export type getPetByIdParams = {
+  /** ID of pet to return */
+  petId: number
+}
+
+export type getUserByNameParams = {
+  /** The name that needs to be fetched. Use user1 for testing.  */
+  username: string
+}
+
+export type loginUserParams = {
+  /** The user name for login */
+  username: string
+  /** The password for login in clear text */
+  password: string
+}
+
+export type Order = {
+  id?: number
+  petId?: number
+  quantity?: number
+  shipDate?: string
+  /** Order Status */
+  status?: 'placed' | 'approved' | 'delivered'
+  complete?: boolean
+}
+
+export type Pet = {
+  id?: number
+  category?: Category
+  name: string
+  photoUrls: string[]
+  tags?: Tag[]
+  /** pet status in the store */
+  status?: 'available' | 'pending' | 'sold'
+}
+
+export enum StatusEnum {
+  available = 'available',
+  pending = 'pending',
+  sold = 'sold',
+}
+
+export type IStatusEnum = keyof typeof StatusEnum
+
+export enum StatusEnum2 {
+  placed = 'placed',
+  approved = 'approved',
+  delivered = 'delivered',
+}
+
+export type IStatusEnum2 = keyof typeof StatusEnum2
+
+export type Tag = {
+  id?: number
+  name?: string
+}
+
+export type updatePetWithFormParams = {
+  /** ID of pet that needs to be updated */
+  petId: number
+}
+
+export type updateUserParams = {
+  /** name that need to be updated */
+  username: string
+}
+
+export type uploadFileParams = {
+  /** ID of pet to update */
+  petId: number
+}
+
+export type User = {
+  id?: number
+  username?: string
+  firstName?: string
+  lastName?: string
+  email?: string
+  password?: string
+  phone?: string
+  /** User Status */
+  userStatus?: number
+}

+ 146 - 0
src/service/app/user.ts

@@ -0,0 +1,146 @@
+/* eslint-disable */
+// @ts-ignore
+import { request } from '@/utils/http'
+import { CustomRequestOptions } from '@/interceptors/request'
+
+import * as API from './types'
+
+/** Create user This can only be done by the logged in user. 返回值: successful operation POST /user */
+export async function createUser({
+  body,
+  options,
+}: {
+  body: API.User
+  options?: CustomRequestOptions
+}) {
+  return request<unknown>('/user', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    data: body,
+    ...(options || {}),
+  })
+}
+
+/** Get user by user name GET /user/${param0} */
+export async function getUserByName({
+  params,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.getUserByNameParams
+  options?: CustomRequestOptions
+}) {
+  const { username: param0, ...queryParams } = params
+
+  return request<API.User>(`/user/${param0}`, {
+    method: 'GET',
+    params: { ...queryParams },
+    ...(options || {}),
+  })
+}
+
+/** Updated user This can only be done by the logged in user. PUT /user/${param0} */
+export async function updateUser({
+  params,
+  body,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.updateUserParams
+  body: API.User
+  options?: CustomRequestOptions
+}) {
+  const { username: param0, ...queryParams } = params
+
+  return request<unknown>(`/user/${param0}`, {
+    method: 'PUT',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    params: { ...queryParams },
+    data: body,
+    ...(options || {}),
+  })
+}
+
+/** Delete user This can only be done by the logged in user. DELETE /user/${param0} */
+export async function deleteUser({
+  params,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.deleteUserParams
+  options?: CustomRequestOptions
+}) {
+  const { username: param0, ...queryParams } = params
+
+  return request<unknown>(`/user/${param0}`, {
+    method: 'DELETE',
+    params: { ...queryParams },
+    ...(options || {}),
+  })
+}
+
+/** Creates list of users with given input array 返回值: successful operation POST /user/createWithArray */
+export async function createUsersWithArrayInput({
+  body,
+  options,
+}: {
+  body: API.User[]
+  options?: CustomRequestOptions
+}) {
+  return request<unknown>('/user/createWithArray', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    data: body,
+    ...(options || {}),
+  })
+}
+
+/** Creates list of users with given input array 返回值: successful operation POST /user/createWithList */
+export async function createUsersWithListInput({
+  body,
+  options,
+}: {
+  body: API.User[]
+  options?: CustomRequestOptions
+}) {
+  return request<unknown>('/user/createWithList', {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    data: body,
+    ...(options || {}),
+  })
+}
+
+/** Logs user into the system GET /user/login */
+export async function loginUser({
+  params,
+  options,
+}: {
+  // 叠加生成的Param类型 (非body参数openapi默认没有生成对象)
+  params: API.loginUserParams
+  options?: CustomRequestOptions
+}) {
+  return request<string>('/user/login', {
+    method: 'GET',
+    params: {
+      ...params,
+    },
+    ...(options || {}),
+  })
+}
+
+/** Logs out current logged in user session 返回值: successful operation GET /user/logout */
+export async function logoutUser({ options }: { options?: CustomRequestOptions }) {
+  return request<unknown>('/user/logout', {
+    method: 'GET',
+    ...(options || {}),
+  })
+}

+ 28 - 0
src/utils/http.ts

@@ -78,3 +78,31 @@ export const httpPost = <T>(
 
 http.get = httpGet
 http.post = httpPost
+
+/*
+ * openapi-ts-request 工具的 request 跨客户端适配方法
+ */
+export const request = <T = unknown>(
+  url: string,
+  options: Omit<CustomRequestOptions, 'url'> & {
+    params?: Record<string, unknown>
+    headers?: Record<string, unknown>
+  },
+) => {
+  const requestOptions = {
+    url,
+    ...options,
+  }
+
+  if (options.params) {
+    requestOptions.query = requestOptions.params
+    delete requestOptions.params
+  }
+
+  if (options.headers) {
+    requestOptions.header = options.headers
+    delete requestOptions.headers
+  }
+
+  return http<T>(requestOptions)
+}