Skip to content

Commit

Permalink
Merge pull request #29 from biaov/release/v1.4.1
Browse files Browse the repository at this point in the history
更新依赖并优化代码
  • Loading branch information
biaov authored Apr 10, 2024
2 parents d183093 + 10c7c23 commit 90a05c3
Show file tree
Hide file tree
Showing 51 changed files with 949 additions and 474 deletions.
9 changes: 9 additions & 0 deletions mobile/.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
# 接口前缀
VITE_BASE_URL=https://ecosystem.biaov.cn/api

# HBuilderX 账号
VITE_USERNAME=

# HBuilderX 密码
VITE_PASSWORD=

# wgt 包下载地址
VITE_WGT_URL=https://ecosystem.biaov.cn/uploads/upgrade.wgt
1 change: 1 addition & 0 deletions mobile/.env.production
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# 接口前缀
VITE_BASE_URL=https://ecosystem.biaov.cn/api
1 change: 1 addition & 0 deletions mobile/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const config = {
'vue/setup-compiler-macros': true
},
globals: {
plus: 'readonly',
uni: 'readonly',
UniApp: 'readonly',
defineSlots: 'readonly',
Expand Down
1 change: 0 additions & 1 deletion mobile/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ fonts
.prettierignore
.prettierrc
LICENSE
package.json
package-lock.json
13 changes: 13 additions & 0 deletions mobile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ npm i

## 运行项目

-`.env.development` 文件中配置环境变量

```sh
npm run dev:%PLATFORM%
```
Expand All @@ -25,6 +27,16 @@ npm run dev:%PLATFORM%
npm run build:%PLATFORM%
```

## APP 打包 APK

- 方法一:使用 HBuilerX 打包
- HBuilerX 打开 `dist/build/app` 目录进行打包发行
- 方法二:使用 HBuilderX cli 打包
- 仍需安装 HBuilerX
- HBuilerX 登录账号
- 配置好 cli 环境变量,即 HBuilderX 软件安装目录的 cli.exe
- 运行 `npm run release` 命令

## 命名规范

- 短横线命名(kebab-case): 文件名, class 类命名, 自定义属性传参
Expand Down Expand Up @@ -60,6 +72,7 @@ npm run build:%PLATFORM%
- `@typescript-eslint/eslint-plugin`: 检测和修复 TS 代码
- `@typescript-eslint/parser`: 解析 TS 代码并生成抽象语法树(AST),以供 eslint 进行代码检查
- `@vitejs/plugin-vue`: Vite 解析 Vue 文件
- `chalk`: 颜色工具
- `eslint`: 代码检查工具
- `eslint-config-airbnb-base`: airbnb-base 代码编写规范
- `eslint-config-prettier`: 将 Prettier 规则集成到 ESlint 检查中
Expand Down
905 changes: 476 additions & 429 deletions mobile/package-lock.json

Large diffs are not rendered by default.

31 changes: 17 additions & 14 deletions mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"build:app": "uni build -p app",
"build:h5": "uni build",
"build:mp-weixin": "uni build -p mp-weixin",
"ncu": "ncu --configFileName .ncurc.json && npm i"
"release": "node scripts/release",
"ncu": "ncu --configFileName .ncurc.json && npm i",
"install": "node scripts/before-server.js"
},
"author": {
"name": "biaov",
Expand Down Expand Up @@ -48,31 +50,32 @@
}
],
"dependencies": {
"@dcloudio/uni-app": "^3.0.0-alpha-4010120240403003",
"@dcloudio/uni-app-plus": "^3.0.0-alpha-4010120240403003",
"@dcloudio/uni-components": "^3.0.0-alpha-4010120240403003",
"@dcloudio/uni-h5": "^3.0.0-alpha-4010120240403003",
"@dcloudio/uni-mp-weixin": "^3.0.0-alpha-4010120240403003",
"@dcloudio/uni-app": "^3.0.0-alpha-4010220240409001",
"@dcloudio/uni-app-plus": "^3.0.0-alpha-4010220240409001",
"@dcloudio/uni-components": "^3.0.0-alpha-4010220240409001",
"@dcloudio/uni-h5": "^3.0.0-alpha-4010220240409001",
"@dcloudio/uni-mp-weixin": "^3.0.0-alpha-4010220240409001",
"dayjs": "^1.11.10",
"pinia": "2.0.36",
"vue": "^3.4.21"
},
"devDependencies": {
"@dcloudio/types": "^3.4.8",
"@dcloudio/uni-automator": "^3.0.0-alpha-4010120240403003",
"@dcloudio/uni-cli-shared": "^3.0.0-alpha-4010120240403003",
"@dcloudio/uni-stacktracey": "^3.0.0-alpha-4010120240403003",
"@dcloudio/vite-plugin-uni": "^3.0.0-alpha-4010120240403003",
"@types/node": "^20.12.5",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"@dcloudio/uni-automator": "^3.0.0-alpha-4010220240409001",
"@dcloudio/uni-cli-shared": "^3.0.0-alpha-4010220240409001",
"@dcloudio/uni-stacktracey": "^3.0.0-alpha-4010220240409001",
"@dcloudio/vite-plugin-uni": "^3.0.0-alpha-4010220240409001",
"@types/node": "^20.12.7",
"@typescript-eslint/eslint-plugin": "^7.6.0",
"@typescript-eslint/parser": "^7.6.0",
"@vitejs/plugin-vue": "^4.6.2",
"chalk": "^5.3.0",
"eslint": "^8.57.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-vue": "^9.24.0",
"eslint-plugin-vue": "^9.24.1",
"less": "^4.2.0",
"prettier": "^3.2.5",
"typescript": "5.4.4",
Expand Down
8 changes: 8 additions & 0 deletions mobile/scripts/before-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { existsSync, cpSync } from 'fs'
import { resolve } from 'path'

const { dirname } = import.meta
const source = resolve(dirname, '../.env')
const output = resolve(dirname, '../.env.development')

!existsSync(output) && cpSync(source, output)
17 changes: 17 additions & 0 deletions mobile/scripts/configure.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"platform": "android",
"android": {
"packagename": "cn.ecosystem.android",
"androidpacktype": "0",
"certalias": "ecosystem",
"certpassword": "123456",
"channels": ""
},
"iscustom": false,
"safemode": true,
"isconfusion": true,
"splashads": false,
"rpads": false,
"pushads": false,
"exchange": false
}
82 changes: 82 additions & 0 deletions mobile/scripts/release.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { resolve } from 'path'
import { cpSync, rmSync, existsSync, mkdirSync, renameSync } from 'fs'
import { execSync } from 'child_process'
import { loadEnv } from 'vite'
import chalk from 'chalk'
import manifestJson from '../src/manifest.json' assert { type: 'json' }

/**
* 转换路径
*/
const transformPath = path => path.replace(/\\/g, '/')

/**
* 相对路径
*/
const { dirname } = import.meta

/**
* 项目打包目录
*/
const output = resolve(dirname, '../dist/build/app')

const outputUnpackage = resolve(output, 'unpackage')
const keystore = resolve(outputUnpackage, 'res/ecosystem.keystore')
const rmOption = { force: true, recursive: true }

/**
* 复制资源
*/
const unpackagePath = resolve(dirname, '../unpackage')

cpSync(unpackagePath, outputUnpackage, rmOption)

/**
* 配置文件路径
*/
const configurePath = resolve(dirname, './configure.json')

/**
* 环境变量
*/
const env = loadEnv('development', resolve(dirname, '../'))
const execOption = { encoding: 'utf-8' }

const release = () => {
execSync('cli open', execOption)
const userInfo = execSync('cli user info', execOption)

if (!userInfo) {
if (!(env.VITE_USERNAME && env.VITE_PASSWORD)) return console.log(chalk.red('请先配置 HbuilderX 或 DCloud 的账号和密码'))
const loginInfo = execSync(`cli user login --username ${env.VITE_USERNAME} --password ${env.VITE_PASSWORD}`, execOption)
if (!loginInfo) return console.log(chalk.red('登录失败'))
console.log(chalk.green('登录成功'))
}

const wgtDir = resolve(outputUnpackage, 'wgt')
// 65001
existsSync(wgtDir) && rmSync(wgtDir, rmOption)
mkdirSync(wgtDir)
console.log()
console.log(chalk.yellow(`开始生成 wgt 包...`))
console.log()
execSync(`cli publish --platform APP --type wgt --project ${transformPath(output)} --path ${wgtDir} --name upgrade.wgt --confuse true`)
console.log(chalk.green(`wgt 包生成完成,路径:${resolve(dirname, '../dist/build/app/unpackage/wgt/upgrade.wgt')}`))
console.log()
/**
* cli: HBuilderX 软件安装目录的 cli.exe
* 由于配置了环境变量,因此此处可以直接可以使用 cli 命令
*/
console.log(chalk.yellow(`开始生成 apk...`))

const result = execSync(`cli pack --config ${transformPath(configurePath)} --project ${transformPath(output)} --android.certfile ${transformPath(keystore)}`, execOption)
let pkgName = result.match(/(?<=dist\/build\/app\/unpackage\/release\/apk\/)(.+\.apk)/g)
if (!pkgName) return console.log(chalk.red('打包失败'))
pkgName = pkgName[0]
const renameDest = resolve(outputUnpackage, `release/apk/ecosystem.${manifestJson.versionName}.apk`)
renameSync(resolve(outputUnpackage, `release/apk/${pkgName}`), renameDest)
console.log()
console.log(chalk.green(`下载成功,APK 路径:${renameDest}`))
execSync('cli app quit', execOption)
}
release()
5 changes: 5 additions & 0 deletions mobile/src/api/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ export const uploadImgApi = command('/upload-img')
* 静默授权
*/
export const silentAuthApi = command('/silent-auth')

/**
* 获取最新版本
*/
export const latestVersionApi = command('https://api.github.com/repos/biaov/ecosystem/releases/latest', { unPrefix: true, unAuth: true })
7 changes: 4 additions & 3 deletions mobile/src/api/factory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { service } from '@/utils/request'
import { defaultPageSize } from '@/config'
import { PagingResponse } from './types'
import type { RequestOption } from '@/utils/types'
import type { PagingResponse } from './types'

export const restful = (path: string) => ({
paging: <T>(query = {}): Promise<PagingResponse<T>> => service.get<PagingResponse<T>>(path, { data: { current: 1, pageSize: defaultPageSize, ...query } }),
Expand All @@ -12,8 +13,8 @@ export const restful = (path: string) => ({
replace: (id: number, data = {}) => service.put(`${path}/${id}`, { data })
})

export const command = (path: string) => ({
get: <T>(query = {}) => service.get(path, { data: query }) as Promise<T>,
export const command = (path: string, option: Partial<RequestOption> = {}) => ({
get: <T>(query = {}) => service.get(path, { ...option, data: query }) as Promise<T>,
post: <T>(data = {}) => service.post(path, { data }) as Promise<T>,
file: <T>(data = {}) => service.file(path, { data }) as Promise<T>
})
140 changes: 140 additions & 0 deletions mobile/src/components/app-upgrador.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<template>
<view-mask v-model:visible="modalVisible">
<view-modal title="更新提示" v-bind="modalPreset[modalTips.type]" @cancel="setModalVisible(false)" @ok="handleSubmit">
<view class="p-tb-60">
<progress-bar :progress="modalTips.progress" class="m-b-20" v-if="modalTips.type === 'progress'" />
<view class="color-primary fs-30">{{ modalTips.message }}</view>
</view>
</view-modal>
</view-mask>
</template>
<script lang="ts" setup>
import { useVisible } from '@/composables/useVisible'
import { toast } from '@/utils/function'
import { latestVersionApi } from '@/api/common'
import type { AppUpgrador } from './types'
const props = withDefaults(
defineProps<{
/**
* 显示状态
*/
visible?: boolean
/**
* 自动检查更新
*/
autoUpdate?: boolean
}>(),
{
visible: false,
autoUpdate: false
}
)
const [modalVisible, setModalVisible] = useVisible()
const modalTips = ref<{
message: string
type: string
progress?: number
}>({ message: '', type: '', progress: 0 })
const defaultPreset = { cancelText: '', okText: '知道了' }
const noFooterPreset = { cancelText: '', okText: '' }
const modalPreset: Readonly<AppUpgrador.ModalPreset> = Object.freeze({
upgrade: { cancelText: '不更新', okText: '更新' },
noUpgrade: defaultPreset,
installFail: defaultPreset,
installing: noFooterPreset,
progress: noFooterPreset,
success: defaultPreset,
downloadFail: defaultPreset
})
/**
* 检测升级器
*/
const checkUpdator = async () => {
const { name } = await latestVersionApi.get<{ name: string }>()
const latestVersion = name.slice(1)
const { appVersion } = uni.getSystemInfoSync()
const version = appVersion.split('.')
const latest = latestVersion.split('.')
if (latest.some((value, i) => value > version[i])) {
modalTips.value = {
message: `发现最新版本 ${name},是否更新?体验更多功能`,
type: 'upgrade'
}
setModalVisible(true)
} else if (!props.autoUpdate) {
modalTips.value = {
message: `当前版本 v${appVersion} 已是最新版本`,
type: 'noUpgrade'
}
setModalVisible(true)
}
}
watch(
() => props.visible,
value => {
if (!value) return
// #ifdef APP-PLUS
checkUpdator()
// #endif
// #ifndef APP-PLUS
toast('只支持 APP 端')
// #endif
},
{ immediate: true }
)
/**
* 格式化文件大小,Bytes -> M
*/
const formatterSize = (value: number) => +(value / 1024 / 1024).toFixed(2)
/**
* 确定
*/
const handleSubmit = () => {
switch (modalTips.value.type) {
case 'upgrade':
uni
.downloadFile({
url: import.meta.env.VITE_WGT_URL,
success: res => {
if (res.statusCode === 200) {
modalTips.value = { message: '下载完成,安装中...', type: 'installing' }
plus.runtime.install(
res.tempFilePath,
{ force: false },
() => {
modalTips.value = { message: '更新完成,须重启应用!', type: 'success' }
},
() => {
modalTips.value = { message: '安装失败', type: 'installFail' }
}
)
} else {
modalTips.value = { message: '下载失败', type: 'downloadFail' }
}
}
})
.onProgressUpdate(res => {
modalTips.value = {
message: `安装包下载中,请稍后 (${formatterSize(res.totalBytesWritten)} / ${formatterSize(res.totalBytesExpectedToWrite)}M)`,
progress: res.progress,
type: 'progress'
}
})
break
case 'success':
plus.runtime.restart()
break
default:
setModalVisible(false)
break
}
}
</script>
Loading

0 comments on commit 90a05c3

Please sign in to comment.