提交 36f51b77 作者: 方治民

Merge branch '3.x' of https://gitlab.yiring.com/basic/basic-uniapp-v3 into examples

node_modules
.DS_Store
dist
.npmrc
.cache
tests/server/static
......
strict-peer-dependencies=false
shell-emulator=true
/dist/*
.local
.output.js
.npmrc
.nvmrc
/node_modules/**
**/*.svg
......
......@@ -34,4 +34,3 @@
- [x] 接入 [消息推送](https://uniapp.dcloud.net.cn/unipush.html)
- [x] 接入 [APP 升级中心](https://uniapp.dcloud.net.cn/uniCloud/upgrade-center.html)
- [ ] 适配上传/下载接口的自动化生成模板(包装 uni.uploadFile 与 uni.downloadFile 方法实现)
- [ ] f-index-list 组件重写为虚拟滚动,改进大列表性能,参考 [vue-virtual-scroller](https://github.com/Akryum/vue-virtual-scroller)
import type { Plugin } from 'vite'
// https://github.com/ErKeLost/unplugin-imagemin
import imagemin from 'unplugin-imagemin/vite'
export function configImageminPlugin(): Plugin {
return imagemin({
// https://github.com/ErKeLost/unplugin-imagemin#warning
// mode: 'sharp',
cache: true,
})
}
......@@ -26,9 +26,6 @@ export function createVitePlugins(viteEnv: ViteEnv) {
// unplugin-vue-components
vitePlugins.push(configImportPlugin())
// unplugin-imagemin
// vitePlugins.push(configImageminPlugin())
// uni-app
vitePlugins.push(configUniPlugin())
......
import fs from 'node:fs'
import type { Plugin } from 'vite'
import fs from 'fs'
import prettier from 'prettier'
// uni-app
import uni from '@dcloudio/vite-plugin-uni'
// @dcloudio/uni-helper-json
import tags from '@dcloudio/uni-helper-json/dist/tags.json'
......@@ -11,12 +12,19 @@ import tags from '@dcloudio/uni-helper-json/dist/tags.json'
* 根据 @dcloudio/uni-helper-json 生成组件 .d.ts 描述文件,对组件进行高亮展示
*/
function generateUniComponentsTypes() {
const components = Object.keys(tags).map((key) => `'${key}': typeof HTMLElement`)
const components = Object.keys(tags).map((key) => `'${key}': UniComponent`)
const content = `
// generated by @dcloudio/uni-helper-json/dist/tags.json
declare module 'vue' {
// uni-app 内置组件高亮
// shime-uni.d.ts
type Hooks = App.AppInstance & Page.PageInstance;
type ComponentCustomOptions = Hooks
// uni-app components
interface UniComponent {
[key in string]: any
}
export interface GlobalComponents {
${components.join(',\n\t')}
}
......@@ -26,9 +34,10 @@ function generateUniComponentsTypes() {
const formatted = prettier.format(content, {
parser: 'typescript',
// eslint-disable-next-line @typescript-eslint/no-require-imports
...require('../../prettier.config'),
})
fs.writeFileSync('./types/uni-components.d.ts', formatted, 'utf8')
fs.writeFileSync('./types/uni.d.ts', formatted, 'utf8')
}
/**
......
......@@ -3,6 +3,7 @@ import type { Plugin } from 'vite'
// https://github.com/antfu/unplugin-auto-import
import AutoImport from 'unplugin-auto-import/vite'
// https://github.com/antfu/unplugin-vue-components
import Components from 'unplugin-vue-components/vite'
......@@ -39,7 +40,7 @@ export function configComponentsImportPlugin(): Plugin {
(name: string) => {
// FIX: 修复 easycom 在 APP 下不生效问题(原因不明
if (name.startsWith('fui-')) {
return path.resolve(__dirname, `src/components/FirstUI/${name}/${name}.vue`).replaceAll('\\', '/')
return path.resolve(__dirname, `src/components/firstui/${name}/${name}.vue`).replaceAll('\\', '/')
}
// if (name.startsWith('uni-')) {
// return `@dcloudio/uni-ui/lib/${name}/${name}.vue`
......
const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')
const fs = require('node:fs')
const path = require('node:path')
const { execSync } = require('node:child_process')
const scopes = fs
.readdirSync(path.resolve(__dirname, 'src'), { withFileTypes: true })
......
......@@ -21,7 +21,7 @@
- [Lodash](https://github.com/lodash/lodash) 函数库
- [Dayjs](https://github.com/iamkun/dayjs) 时间库
- [@vueuse/core](https://github.com/vueuse/vueuse) Vue2/3 实用工具集
- [mock.js](https://github.com/nuysoft/Mock) 数据模拟
- [faker-js](https://github.com/faker-js/faker) 数据模拟
- [UnoCSS](https://github.com/unocss/unocss) UnoCSS
### 网络
......@@ -40,7 +40,7 @@
<!-- prettier-ignore -->
- [HBuilderX Latest](https://www.dcloud.io/hbuilderx.html)
- [Vite v4.x](https://vitejs.dev)
- [Vite](https://vitejs.dev)
### 其他插件
......
......@@ -3,14 +3,14 @@
<head>
<meta charset="UTF-8" />
<script>
var coverSupport =
const coverSupport =
'CSS' in window &&
typeof CSS.supports === 'function' &&
(CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') +
'" />',
`<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0${
coverSupport ? ', viewport-fit=cover' : ''
}" />`,
)
</script>
<title></title>
......
{
"name": "basic-app",
"version": "3.0.2.5",
"version": "3.0.3.0",
"description": "APP 基础工程",
"keywords": [
"app",
......@@ -57,7 +57,7 @@
"lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
"lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
"log": "conventional-changelog -p angular -i CHANGELOG.md -s",
"up": "pnpx @dcloudio/uvm alpha",
"u": "pnpx @dcloudio/uvm vue3",
"prepare": "husky install"
},
"config": {
......@@ -66,29 +66,30 @@
}
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-app-plus": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-components": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-h5": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-mp-alipay": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-mp-baidu": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-mp-jd": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-mp-lark": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-mp-qq": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-mp-toutiao": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-ui": "^1.4.26",
"@dcloudio/uni-app": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-app-plus": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-components": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-h5": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-mp-alipay": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-mp-baidu": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-mp-jd": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-mp-lark": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-mp-qq": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-mp-toutiao": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-ui": "^1.4.27",
"@faker-js/faker": "^7.6.0",
"@vue/runtime-core": "^3.2.47",
"@vueuse/core": "^9.13.0",
"@vueuse/core": "^10.1.0",
"axios": "^0.26.1",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.7",
"lodash-es": "^4.17.21",
"nanoid": "^4.0.1",
"pinia": "^2.0.33",
"pinyin-pro": "^3.13.1",
"nanoid": "^4.0.2",
"pinia": "^2.0.35",
"pinyin-pro": "^3.13.2",
"qs": "~6.9.7",
"stompjs": "^2.3.3",
"urijs": "^1.19.11",
......@@ -98,71 +99,69 @@
"vue-types": "^5.0.2"
},
"devDependencies": {
"@antfu/eslint-config": "^0.37.0",
"@commitlint/cli": "^17.4.4",
"@commitlint/config-conventional": "^17.4.4",
"@antfu/eslint-config": "^0.38.5",
"@commitlint/cli": "^17.6.1",
"@commitlint/config-conventional": "^17.6.1",
"@dcloudio/types": "^3.3.2",
"@dcloudio/uni-automator": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-cli-shared": "3.0.0-alpha-3070720230316001",
"@dcloudio/uni-automator": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-cli-shared": "3.0.0-alpha-3071320230417001",
"@dcloudio/uni-helper-json": "^1.0.13",
"@dcloudio/uni-stacktracey": "3.0.0-alpha-3070720230316001",
"@dcloudio/vite-plugin-uni": "3.0.0-alpha-3070720230316001",
"@iconify/json": "^2.2.36",
"@dcloudio/uni-stacktracey": "3.0.0-alpha-3071320230417001",
"@dcloudio/vite-plugin-uni": "3.0.0-alpha-3071320230417001",
"@iconify/json": "^2.2.54",
"@types/crypto-js": "^4.1.1",
"@types/lodash-es": "^4.17.7",
"@types/mapbox-gl": "^2.7.10",
"@types/mockjs": "^1.0.7",
"@types/node": "^18.15.3",
"@types/node": "^18.15.13",
"@types/prettier": "^2.7.2",
"@types/qs": "^6.9.7",
"@types/stompjs": "^2.3.5",
"@types/urijs": "^1.19.19",
"@typescript-eslint/eslint-plugin": "^5.55.0",
"@typescript-eslint/parser": "^5.55.0",
"@typescript-eslint/eslint-plugin": "^5.59.0",
"@typescript-eslint/parser": "^5.59.0",
"commitizen": "^4.3.0",
"conventional-changelog-cli": "^2.2.2",
"cz-conventional-changelog": "^3.3.0",
"cz-customizable": "^7.0.0",
"cz-git": "^1.6.0",
"czg": "^1.6.0",
"cz-git": "^1.6.1",
"czg": "^1.6.1",
"dotenv": "^16.0.3",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.7.0",
"eslint": "^8.39.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.9.0",
"eslint-plugin-vue": "^9.11.0",
"husky": "^8.0.3",
"jest": "27.0.4",
"jest-environment-node": "27.5.1",
"less": "^4.1.3",
"lint-staged": "^13.2.0",
"mapbox-gl": "^2.13.0",
"lint-staged": "^13.2.1",
"mapbox-gl": "^2.14.1",
"npm-run-all": "^4.1.5",
"picocolors": "^1.0.0",
"pont-engine": "^1.5.7",
"postcss": "^8.4.21",
"postcss": "^8.4.23",
"postcss-html": "^1.5.0",
"postcss-less": "^6.0.0",
"prettier": "^2.8.4",
"rimraf": "^4.4.0",
"sass": "^1.59.3",
"prettier": "^2.8.7",
"rimraf": "^4.4.1",
"sass": "^1.62.0",
"sort-package-json": "^2.4.1",
"stylelint": "^14.16.1",
"stylelint": "^15.6.0",
"stylelint-config-html": "^1.1.0",
"stylelint-config-prettier": "^9.0.5",
"stylelint-config-recommended": "^9.0.0",
"stylelint-config-standard": "^29.0.0",
"stylelint-order": "^5.0.0",
"stylus": "^0.59.0",
"terser": "^5.16.6",
"typescript": "^4.9.5",
"unocss": "^0.50.6",
"unocss-preset-weapp": "^0.5.1",
"unplugin-auto-import": "^0.15.1",
"unplugin-imagemin": "^0.3.11",
"stylelint-config-recommended": "^11.0.0",
"stylelint-config-standard": "^32.0.0",
"stylelint-order": "^6.0.3",
"typescript": "^5.0.4",
"unocss": "^0.50.8",
"unocss-preset-weapp": "^0.5.3",
"unplugin-auto-import": "^0.15.3",
"unplugin-vue-components": "^0.24.1",
"vite": "^4.2.0",
"vue-eslint-parser": "^9.1.0"
"vite": "^4.3.1",
"vue-eslint-parser": "^9.1.1"
},
"engines": {
"node": ">=16"
"node": ">=16",
"pnpm": ">=8.1.0"
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
// import * as Pont from 'pont-engine'
import { Interface, BaseClass, Property, CodeGenerator } from 'pont-engine'
import type { BaseClass, Interface } from 'pont-engine'
import { CodeGenerator, Property } from 'pont-engine'
// 接口 API 前缀
// 通常与项目的 env 配置中的 VITE_GLOB_API_URL_PREFIX 相同
......@@ -7,6 +8,7 @@ const API_URL_PREFIX = '/api'
export default class BasicGenerator extends CodeGenerator {
checkJsonParam(inter: Interface, paramsCode: string): boolean {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const prettier = require('prettier')
const requestParams = inter.getRequestParams(this.surrounding)
const code = prettier.format(paramsCode, { parser: 'typescript' })
......@@ -28,6 +30,7 @@ export default class BasicGenerator extends CodeGenerator {
let requestParams = inter.getRequestParams(this.surrounding)
let bodyTypeDef = ''
// eslint-disable-next-line @typescript-eslint/no-require-imports
const prettier = require('prettier')
if (prettier.format(paramsCode, { parser: 'typescript' }).includes('{}')) {
if (!requestParams.includes('form')) {
......@@ -44,7 +47,7 @@ export default class BasicGenerator extends CodeGenerator {
return `${requestParams.replace(
'options?: any',
`config?: http.RequestConfig<${
bodyTypeDef ? bodyTypeDef : `Params${requestParams.includes('form') ? ' | FormData' : ''}`
bodyTypeDef || `Params${requestParams.includes('form') ? ' | FormData' : ''}`
}>`,
)}, options?: http.RequestOptions`
}
......
import { StandardDataSource } from 'pont-engine'
import type { StandardDataSource } from 'pont-engine'
export default function (dataSource: StandardDataSource): StandardDataSource {
return dataSource
......
<script setup lang="ts">
import { checkUpgrade } from '@/utils/upgrade'
// import * as Push from '@/utils/push'
onLaunch(() => {
......@@ -9,10 +10,10 @@
checkUpgrade()
// 清除消息角标
// Push.setBadge()
// Push.setBadge(0)
// 监听在线消息
// Push.listenMessage()
// Push.listen()
})
onShow(() => {
......@@ -36,13 +37,20 @@
/* common css */
/* #ifndef APP-PLUS-NVUE */
/* uni.css - 通用组件、模板样式库,可以当作一套ui库应用 */
@import './common/uni.css';
@import url('./common/uni.css');
/* #endif */
/*每个页面公共css */
@import './common/fui-app.css';
@import './components/firstui/fui-theme/fui-theme.css';
/* 每个页面公共css */
@import url('./common/fui-app.css');
@import url('./components/firstui/fui-theme/fui-theme.css');
// 全局样式
@import './common/public.less';
@import url('./common/public.less');
/** #ifdef H5 */
uni-page-body,
page {
height: 100%;
}
/** #endif */
</style>
export const Message = {
/**
* 消息轻提示
* @param text 消息内容
* @param title 消息内容
*/
toast: (text: string, duration?: 'short' | 'long'): void => {
if (text) {
toast: (title: string, duration?: 'short' | 'long'): void => {
if (title) {
// #ifndef APP-PLUS
uni.showToast({
title: text,
title,
icon: 'none',
duration: duration === 'short' ? 2000 : 3500,
})
// #endif
// #ifdef APP-PLUS
plus.nativeUI.toast(text, {
plus.nativeUI.toast(title, {
duration: duration || 'short',
})
// #endif
......@@ -22,16 +22,16 @@ export const Message = {
},
/**
* 消息弹窗提示
* @param message 消息内容
* @param content 消息内容
* @param title 标题
* @returns Promise<void>
*/
alert: (message: string, title = '提示', confirmText = '确定'): Promise<void> => {
alert: (content: string, title = '提示', confirmText = '确定'): Promise<void> => {
return new Promise((resolve, reject) => {
// #ifndef APP-PLUS
uni.showModal({
title,
content: message,
content,
showCancel: false,
confirmText,
success: () => resolve(),
......@@ -40,24 +40,24 @@ export const Message = {
// #endif
// #ifdef APP-PLUS
plus.nativeUI.alert(message, resolve, title, confirmText)
plus.nativeUI.alert(content, resolve, title, confirmText)
// #endif
})
},
/**
* 消息确认提示
* @param title 标题
* @param message 提示内容
* @param content 提示内容
* @param confirmText 确认按钮文字
* @param showCancel 是否显示取消按钮
* @returns Promise<boolean> 是否点击了确认按钮
*/
confirm: (message: string, title = '提示', confirmText = '确定', showCancel = true): Promise<boolean> => {
confirm: (content: string, title = '提示', confirmText = '确定', showCancel = true): Promise<boolean> => {
return new Promise((resolve, reject) => {
// #ifndef APP-PLUS
uni.showModal({
title,
content: message,
content,
showCancel,
confirmText,
success: (res) => resolve(res.confirm),
......@@ -66,7 +66,7 @@ export const Message = {
// #endif
// #ifdef APP-PLUS
plus.nativeUI.confirm(message, ({ index }) => resolve(index === 0), {
plus.nativeUI.confirm(content, ({ index }) => resolve(index === 0), {
title,
buttons: ['确认', '取消'],
verticalAlign: 'center',
......@@ -76,11 +76,11 @@ export const Message = {
},
/**
* 加载中
* @param text 加载中文字
* @param title 加载中文字
*/
loading: (text = '加载中...'): void => {
loading: (title = '加载中...'): void => {
uni.showLoading({
title: text,
title,
mask: true,
})
},
......
<script setup lang="ts">
import md5 from 'crypto-js/md5'
const props = defineProps({
width: {
type: [String, Number],
default: '320',
},
height: {
type: [String, Number],
default: '240',
},
radius: {
type: [String, Number],
default: 0,
},
mode: {
type: String,
default: 'scaleToFill',
},
background: {
type: String,
default: '#F7F7F7',
},
src: {
type: String,
required: true,
},
})
const src = ref()
const hashCacheKey = ref()
onMounted(async () => {
// 尝试缓存图片,如果失败则使用原始图片
await tryCache()
})
async function tryCache() {
let url = props.src
// #ifdef APP-PLUS
const hash = md5(url).toString()
hashCacheKey.value = `G_CACHE_IMAGE_${hash}`
if (uni.getStorageSync(hashCacheKey.value)) {
console.debug('CacheImage cache hit')
url = uni.getStorageSync(hashCacheKey.value)
} else {
console.debug('CacheImage cache miss')
try {
const res = await uni.downloadFile({ url })
if (res.statusCode === 200) {
const { savedFilePath } = await new Promise<UniApp.SaveFileSuccess>((resolve, reject) => {
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (res) => resolve(res),
fail: (err) => reject(err),
})
})
url = `${savedFilePath}`
// 缓存图片本地地址
uni.setStorageSync(hashCacheKey.value, url)
}
} catch (e) {
console.error(e)
}
}
console.debug(props.src, '=>', url, hash, hashCacheKey.value)
// #endif
src.value = url
}
const hasError = ref(false)
function onError() {
if (hasError.value) {
return
}
hasError.value = true
src.value = props.src
// 清除缓存
hashCacheKey.value && uni.removeStorageSync(hashCacheKey.value)
console.warn('CacheImage cache error')
}
</script>
<template>
<fui-lazyload
:mode="props.mode"
:width="props.width"
:height="props.height"
:radius="props.radius"
:background="props.background"
:src="src"
@error="onError"
>
<slot></slot>
</fui-lazyload>
</template>
......@@ -26,7 +26,7 @@
</view>
</template>
<style>
<style scoped>
.empty {
width: 100%;
height: 100%;
......@@ -45,6 +45,6 @@
.empty .empty-tips {
display: flex;
font-size: 30rpx;
color: #999999;
color: #999;
}
</style>
......@@ -14,7 +14,7 @@ export const tk = 'aa0ccd36f2dbb86dbb16cbf63f0034a6'
const host = 'https://gis.kshg.yiring.com'
// 构建天地图图层地址
export const buildTdtTileUrl = (id: string, tk: string) => {
export function buildTdtTileUrl(id: string, tk: string) {
return `${host}/api/tdt/cache/${id}/{z}/{y}/{x}/${tk}?v=2022`
}
......@@ -547,10 +547,12 @@ export function loadMapboxLibs() {
}
export const getMapInstance = (ref: Ref<any>): mapboxgl.Map => toRaw(ref.value?.map) as mapboxgl.Map
export const getGeoJSONSource = (map: mapboxgl.Map, sourceName: string): mapboxgl.GeoJSONSource =>
map.getSource(sourceName) as mapboxgl.GeoJSONSource
export const getImageSource = (map: mapboxgl.Map, sourceName: string): mapboxgl.ImageSource =>
map.getSource(sourceName) as mapboxgl.ImageSource
export function getGeoJSONSource(map: mapboxgl.Map, sourceName: string): mapboxgl.GeoJSONSource {
return map.getSource(sourceName) as mapboxgl.GeoJSONSource
}
export function getImageSource(map: mapboxgl.Map, sourceName: string): mapboxgl.ImageSource {
return map.getSource(sourceName) as mapboxgl.ImageSource
}
export const EmptyImage =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABlBMVEXMzMz/+v+u+uEzAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAACklEQVQImWNgAAAAAgAB9HFkpgAAAABJRU5ErkJggg=='
<script lang="ts" setup>
import type { PropType } from 'vue'
import md5 from 'crypto-js/md5'
import { nanoid } from 'nanoid'
import { getPoster, isImage, isVideo } from './utils'
import CacheImage from '@/components/CacheImage/index.vue'
type URLs = { url: string }[]
type Asset = Recordable & { url: string }
const props = defineProps({
width: {
type: [String, Number],
......@@ -17,21 +18,35 @@
type: String,
default: 'aspectFit',
},
background: {
type: String,
default: '#F7F7f7',
},
assets: {
type: Array as PropType<Recordable & URLs>,
type: Array as PropType<Asset[]>,
},
})
// 生成预览容器高度
const containerHeight = `${props.height}rpx`
const height = computed(() => `${props.height}rpx`)
// 分离图片和视频资源地址
const images = computed(() => props.assets.filter((item) => isImage(item.url)))
const videos = computed(() => props.assets.filter((item) => isVideo(item.url)))
// 预览图片
const preview = (index: number) => {
function preview(index: number) {
uni.previewImage({
urls: images.value.map((item) => item.url),
urls: images.value.map((item) => {
// #ifdef APP-PLUS
const hash = md5(item.url).toString()
const key = `G_CACHE_IMAGE_${hash}`
if (uni.getStorageSync(key)) {
return uni.getStorageSync(key)
}
// #endif
return item.url
}),
current: index,
})
}
......@@ -41,15 +56,16 @@
const videoContext = ref()
const playVideoSrc = ref()
// 播放视频
const play = (index: number) => {
function play(index: number) {
playVideoSrc.value = videos.value[index].url
videoContext.value?.requestFullScreen()
videoContext.value?.play()
}
const videoFullScreenChange = (e: any) => {
function videoFullScreenChange(e: any) {
// 非全屏状态下停止播放
if (!e.detail.fullScreen) {
videoContext.value?.stop()
videoContext.value.seek(0)
videoContext.value.pause()
}
}
......@@ -62,8 +78,9 @@
<template>
<view class="preview-wrap">
<!-- 视频预览 -->
<fui-lazyload
<CacheImage
class="preview-video"
:background="props.background"
:mode="props.mode"
v-for="(item, index) in videos"
:key="item.url"
......@@ -76,11 +93,12 @@
<view class="icon-wrap" :style="{ width: props.width, height: props.height }">
<fui-icon class="video-play-icon" name="suspend" size="40" color="#fff" />
</view>
</fui-lazyload>
</CacheImage>
<!-- 图片预览 -->
<fui-lazyload
<CacheImage
class="preview-image"
:background="props.background"
:mode="props.mode"
v-for="(item, index) in images"
:key="item.url"
......@@ -115,7 +133,7 @@
position: relative;
:deep(.fui-lazyload__img) {
height: v-bind(containerHeight) !important;
height: v-bind(height) !important;
}
.icon-wrap {
......@@ -124,7 +142,7 @@
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
background-color: rgb(0 0 0 / 50%);
border-radius: 10rpx;
.video-play-icon {
......
# 组件更新说明
1. 从 https://firstui.cn/user/order 下载更新版本包
2. 在本地解压,找到 \FirstUI\components\firstui 目录,使用 vscode 打开当前目录
3. 清理掉组件文件头部的 license 信息,使用 vscode 全局替换
4. 全局替换换行符 \r\n\n [引用](https://segmentfault.com/q/1010000011799577)
5. 将文件拷贝到 src\components\FirstUI\ 目录下,检查 git diff,手动处理哪些文件需要更新
......@@ -67,7 +67,11 @@
tips: {
type: String,
default: '请签名!'
}
},
suffix: {
type: String,
default: 'png'
},
},
watch: {
width(val) {
......@@ -310,7 +314,7 @@
x: 0,
y: 0,
canvasId: this.canvasId,
fileType: 'png',
fileType: this.suffix,
quality: 1,
success: function(res) {
callback && callback(res.tempFilePath)
......@@ -329,7 +333,7 @@
this.h * 2,
this.w * 2,
this.h * 2,
"png",
this.suffix,
1,
function(res) {
callback && callback(res.tempFilePath)
......
import GCanvas from './env/canvas';
import GImage from './env/image';
import GWebGLRenderingContext from './context-webgl/RenderingContext';
import GWebGLRenderingContext from './context-webgl/RenderingContext';// 2021-5-6变更
import GContext2D from './context-2d/RenderingContext';
import GBridgeWeex from './bridge/bridge-weex';
......@@ -12,12 +12,12 @@ export let WeexBridge = GBridgeWeex;
export function enable(el, {
bridge,
debug,
debug,// 2021-5-6变更
disableAutoSwap,
disableComboCommands
} = {}) {
const GBridge = GImage.GBridge = GCanvas.GBridge = GWebGLRenderingContext.GBridge = GContext2D.GBridge = bridge;
const GBridge = GImage.GBridge = GCanvas.GBridge = GWebGLRenderingContext.GBridge = GContext2D.GBridge = bridge;// 功能需要优化
GBridge.callEnable(el.ref, [
0, // renderMode: 0--RENDERMODE_WHEN_DIRTY, 1--RENDERMODE_CONTINUOUSLY
......@@ -29,7 +29,7 @@ export function enable(el, {
false // sameLevel: newCanvasMode = true && true => GCanvasView and Webview is same level
]);
if (debug === true) {
if (debug === true) {// echo建议
GBridge.callEnableDebug();
}
if (disableComboCommands) {
......@@ -41,7 +41,7 @@ export function enable(el, {
});
let pixelRatio = uni.getSystemInfoSync().pixelRatio;
canvas.width = el.style.width * pixelRatio;
canvas.height = el.style.height * pixelRatio;
canvas.height = el.style.height * pixelRatio;// 新特性待增加
return canvas;
};
......@@ -159,11 +159,11 @@
styl += `width:${this.width}rpx;`
}
if (this.position === 'fixed') {
let tb = this.top ? `top:${this.top}rpx;` : '';
tb += this.bottom ? `bottom:${this.bottom}rpx;` : '';
let tb = Number(this.top) ? `top:${this.top}rpx;` : '';
tb += Number(this.bottom) ? `bottom:${this.bottom}rpx;` : '';
styl += tb ? tb : `top:${this.top}rpx;`
let lr = this.left ? `left:${this.left}rpx;` : '';
lr += this.right ? `right:${this.right}rpx;` : '';
let lr = Number(this.left) ? `left:${this.left}rpx;` : '';
lr += Number(this.right) ? `right:${this.right}rpx;` : '';
styl += lr ? lr : `left:${this.left}rpx;`;
} else {
// #ifdef APP-NVUE
......@@ -184,6 +184,13 @@
break;
}
// #endif
let tb = Number(this.top) ? `margin-top:${this.top}rpx;` : '';
tb += Number(this.bottom) ? `margin-top:-${this.bottom}rpx;` : '';
styl += tb ? tb : `margin-top:${this.top}rpx;`
let lr = Number(this.left) ? `margin-left:${this.left}rpx;` : '';
lr += Number(this.right) ? `margin-left:-${this.right}rpx;` : '';
styl += lr ? lr : `margin-left:${this.left}rpx;`;
}
return styl
},
......@@ -320,6 +327,9 @@
/* #ifdef APP-NVUE */
transition: opacity 0.3s ease-in-out;
/* #endif */
/* margin-top: -120rpx; */
/* margin-left: 20rpx; */
}
......
......@@ -26,7 +26,7 @@ const fuiConfig = {
},
fuiFormItem: {
labelSize: 32,
labelWidth: 140,
labelWidth: 160,
labelRight: 16
}
}
......
......@@ -203,9 +203,8 @@
let iphonex = false;
let models = ['iphonex', 'iphonexr', 'iphonexsmax', 'iphone11', 'iphone11pro', 'iphone11promax',
'iphone12', 'iphone12mini', 'iphone12pro', 'iphone12promax', 'iphone13', 'iphone13mini',
'iphone13pro', 'iphone13promax', 'iphone14', 'iphone14mini', 'iphone14plus',
'iphone14pro', 'iphone14promax', 'iphone15', 'iphone15mini', 'iphone15plus',
'iphone15pro', 'iphone15promax'
'iphone13pro', 'iphone13promax', 'iphone14', 'iphone14mini',
'iphone14pro', 'iphone14promax'
]
const model = res.model.replace(/\s/g, "").toLowerCase()
const newModel = model.split('<')[0]
......
......@@ -5,22 +5,24 @@
:class="[dragging?'fui-drag-item__show':'fui-drag-item__hidden']">
<!-- #endif -->
<!-- #ifdef APP-VUE || MP-WEIXIN || H5 -->
<view class="fui-drag__wrap" :class="[dragging?'fui-drag-item__show':'fui-drag-item__hidden']" ref="fui_drag"
:id="elId" :style="{width:wrapWidth+'px',height:(rows * cellHeight)+'px'}" :list="list"
<!-- #ifdef VUE2 -->
<view class="fui-drag__wrap" :catch:touchmove="wxDrag?handler.stopTouchMove:''"
:class="[dragging?'fui-drag-item__show':'fui-drag-item__hidden']" ref="fui_drag" :id="elId"
:style="{width:wrapWidth+'px',height:(rows * cellHeight)+'px'}" :list="list"
:change:list="handler.listChange" :param="param" :change:param="handler.paramChange">
<!-- #ifndef MP-WEIXIN -->
<!-- #endif -->
<!-- #ifdef VUE3 -->
<!-- vue3下编译到小程序data数据与wxs混用中无法获取 $data数据无法直接应用到页面,uni-app官方编译bug-->
<view class="fui-drag__wrap" :catch:touchmove="wxDrag?true:''"
:class="[dragging?'fui-drag-item__show':'fui-drag-item__hidden']" ref="fui_drag" :id="elId"
:style="{width:wrapWidth+'px',height:(rows * cellHeight)+'px'}" :list="list"
:change:list="handler.listChange" :param="param" :change:param="handler.paramChange">
<!-- #endif -->
<view class="fui-drag-item__wrap" :style="{width:cellWidth+'px',height:cellHeight+'px'}"
v-for="(item, index) in list" :key="item.id" :data-index="index" @longpress="handler.longPress"
:data-param="param" :data-isdrag="isDrag && dragging?1:0" @touchstart="handler.touchStart"
@touchmove="handler.touchMove" @touchend="handler.touchEnd" @mousedown="handler.mousedown"
@tap="itemClick(index)">
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="fui-drag-item__wrap" :style="{width:cellWidth+'px',height:cellHeight+'px'}"
v-for="(item, index) in list" :key="item.id" :data-index="index" @longpress="handler.longPress"
:data-param="param" :data-isdrag="isDrag && dragging?1:0" @touchstart="handler.touchStart"
:catch:touchmove="wxDrag?handler.touchMove:''" @touchend="handler.touchEnd" @tap="itemClick(index)">
<!-- #endif -->
<template v-if="custom">
<slot :model="item.entity" :width="cellWidth" :height="cellHeight" :index="index"></slot>
</template>
......
......@@ -273,6 +273,10 @@ function mousedown(e, ins) {
}
function stopTouchMove(e) {
return true
}
module.exports = {
longPress: longPress,
touchStart: touchStart,
......@@ -280,5 +284,6 @@ module.exports = {
touchEnd: touchEnd,
paramChange: paramChange,
listChange: listChange,
mousedown: mousedown
mousedown: mousedown,
stopTouchMove:stopTouchMove
}
......@@ -3,7 +3,7 @@
:style="{paddingTop:padding[0] || 0,paddingRight:padding[1] || 0,paddingBottom:padding[2] || padding[0] || 0,paddingLeft:padding[3] || padding[1] || 0,background:background,marginTop:marginTop+'rpx',marginBottom:marginBottom+'rpx',borderRadius:radius}"
@tap="handleClick">
<!-- #ifdef APP-NVUE -->
<view class="fui-form__asterisk" v-if="asterisk">
<view class="fui-form__asterisk" :style="{left:getAkPosi}" v-if="asterisk">
<text :style="{color:asteriskColor || akColor || '#FF2B2B'}">*</text>
</view>
<!-- #endif -->
......@@ -141,11 +141,11 @@
return `${this.labelSize || this.lSize || labelSize}rpx`
},
getLabelWidth() {
const labelWidth = (uni.$fui && uni.$fui.fuiFormItem && uni.$fui.fuiFormItem.labelWidth) || 140
const labelWidth = (uni.$fui && uni.$fui.fuiFormItem && uni.$fui.fuiFormItem.labelWidth) || 160
return `${this.labelWidth || this.lWidth || labelWidth}rpx`
},
getLabelRight() {
const labelRight = (uni.$fui && uni.$fui.fuiFormItem && uni.$fui.fuiFormItem.labelRight) || 16
const labelRight = (uni.$fui && uni.$fui.fuiFormItem && uni.$fui.fuiFormItem.labelRight) || 30
return `${this.labelRight || labelRight}rpx`
},
getLabelAlign() {
......
......@@ -11,6 +11,7 @@
<script>
export default {
name: "fui-grid-item",
emits: ['click'],
inject: ['grid'],
// #ifdef MP-WEIXIN
options: {
......@@ -79,11 +80,13 @@
}
},
handleClick() {
this.grid.handleClick({
const e = {
detail: {
index: this.index
}
})
}
this.grid && this.grid.handleClick(e)
this.$emit('click', e)
}
}
}
......
......@@ -307,6 +307,13 @@
font-weight: 500;
}
/* #ifdef H5 */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
/* #endif */
.fui-number__disabled {
opacity: 0.6;
}
......
......@@ -64,7 +64,7 @@ export default [{
cn: '晋',
en: 'P'
}]
}, {
}, {// echo建议
id: 'f_p3',
keys: [{
cn: '蒙',
......@@ -82,7 +82,7 @@ export default [{
cn: '贵',
en: 'G'
}, {
cn: '粤',
cn: '粤',// 功能需要优化
en: 'H'
}, {
cn: '青',
......@@ -97,10 +97,10 @@ export default [{
cn: '宁',
en: ''
}]
}, {
}, {// 新特性待增加
id: 'f_p4',
keys: [{
cn: 'ABC',
cn: 'ABC',// echo建议
en: '返回'
}, {
cn: '琼',
......@@ -119,7 +119,7 @@ export default [{
en: 'B'
}, {
cn: '港',
en: 'N'
en: 'N'// 新特性待增加
}, {
cn: '澳',
en: 'M'
......
......@@ -15,10 +15,10 @@
<view class="fui-modal__button"
:class="{'fui-modal__button-col':direction==='column' && index!==vals.length-1,'fui-modal__button-bg':!entity.plain && !entity.background,'fui-modal__button-border':entity.plain,'fui-modal__button-bc':entity.plain && !entity.background}"
:style="{borderRadius:radius+'rpx',background:entity.plain?'transparent':(entity.background || '#465CFF'),borderColor:entity.plain?(entity.background || '#465CFF'):'transparent'}"
v-for="(entity,index) in vals" :key="index" @tap.stop="handleClick($event,index)">
v-for="(entity,index) in vals" :key="index">
<text class="fui-modal__button-inner"
:class="{'fui-modal__button-color': !entity.color && entity.plain}"
:style="{color:entity.color || (entity.plain?'#465CFF':'#fff')}">{{entity.text}}</text>
:style="{color:entity.color || (entity.plain?'#465CFF':'#fff'),borderRadius:radius+'rpx'}" @tap.stop="handleClick($event,index)">{{entity.text}}</text>
</view>
</view>
</view>
......@@ -338,6 +338,9 @@
border-width: 1rpx;
transform: translateZ(0);
/* #endif */
/* #ifdef H5 */
border-width: 1px;
/* #endif */
border-style: solid;
}
......
......@@ -9,7 +9,7 @@
//背景颜色
background: {
type: String,
default: '#FFFFFF'
default: 'transparent'
}
},
created() {
......
......@@ -34,9 +34,10 @@
<view class="fui-select__flex">
<view class="fui-select__icon-box"
:class="{'fui-select__icon-ml':!isReverse && type==='select','fui-select__icon-mr':isReverse}"
:style="{width:iconWidth+'rpx',height:iconWidth+'rpx'}" v-if="model.src">
:style="{width:iconWidth+'rpx',height:iconWidth+'rpx',backgroundColor:iconBgColor}"
v-if="model.src">
<image :src="model.src" :style="{width:iconWidth+'rpx',height:iconWidth+'rpx'}"
mode="widthFix"></image>
:mode="iconMode"></image>
</view>
<text class="fui-select__item-text"
:class="{'fui-select__text-pl':!isReverse && (type==='select' || model.src),'fui-select__text-pr':isReverse && (type==='select' || model.src)}"
......@@ -181,6 +182,14 @@
type: [Number, String],
default: 48
},
iconBgColor: {
type: String,
default: 'rgba(0,0,0,0)'
},
iconMode: {
type: String,
default: 'widthFix'
},
size: {
type: [Number, String],
default: 30
......@@ -484,7 +493,9 @@
/* #ifndef APP-NVUE */
width: 100%;
/* #endif */
flex: 1;
/* #ifdef APP-NVUE */
width: 750rpx;
/* #endif */
}
.fui-select__list {
......@@ -600,10 +611,12 @@
.fui-select__icon-box {
overflow: hidden;
background-color: #F1F4FA;
/* #ifndef APP-NVUE */
flex-shrink: 0;
display: flex;
/* #endif */
align-items: center;
justify-content: center;
}
.fui-select__icon-ml {
......@@ -619,13 +632,14 @@
width: 100%;
display: flex;
/* #endif */
flex: 1;
/* #ifdef APP-NVUE */
width: 750rpx;
/* #endif */
height: 98rpx;
flex-direction: row;
align-items: center;
justify-content: center;
position: relative;
}
.fui-select__header-line {
......
......@@ -9,7 +9,7 @@ export default {
},
watch: {
show(newVal) {
// if (this.autoClose) return
if (this.autoClose) return
if (this.stop) return
this.stop = true
if (newVal) {
......@@ -55,6 +55,7 @@ export default {
})
},
touchstart(e) {
if (this.disabled) return
// 每次只触发一次,避免多次监听造成闪烁
if (this.stop) return
this.stop = true
......@@ -62,7 +63,7 @@ export default {
this.group.closeAuto(this)
}
const rightWidth = this.button.right.width
const rightWidth = this.button.right.width || 0
let expression = this.range(this.x, -rightWidth, 0)
let rightExpression = this.range(this.x + rightWidth, 0, rightWidth)
......@@ -93,7 +94,7 @@ export default {
},
bindTiming(x) {
const left = this.x
const rightWidth = this.button.right.width
const rightWidth = this.button.right.width || 0
const threshold = Number(this.threshold)
if (!this.isopen) {
if (left < -threshold) {
......@@ -102,7 +103,7 @@ export default {
this.open(false)
}
} else {
if ((x < threshold && x > 0) || (x + leftWidth < -threshold)) {
if ((x < threshold && x > 0) || (x < -threshold)) {
this.open(true)
} else {
this.open(false)
......@@ -120,7 +121,7 @@ export default {
},
animation(type) {
const time = 300
const rightWidth = this.button.right.width
const rightWidth = this.button.right.width || 0
if (this.eventpan && this.eventpan.token) {
BindingX.unbind({
token: this.eventpan.token,
......
......@@ -24,8 +24,12 @@ function getDom(ins, ownerInstance) {
return;
}
if (isH5 || isPC()) {
if (rightDom['$el']) {
state.rightWidth = rightDom['$el'].offsetWidth || 0
} else {
state.rightWidth = 0
}
} else {
var rightStyles = rightDom.getBoundingClientRect()
state.rightWidth = rightStyles.width || 0
}
......
......@@ -25,9 +25,13 @@ export default {
}
},
mounted() {
this.$nextTick(() => {
setTimeout(() => {
this.isShow = this.show
this.isDisabled = this.disabled
this.thresholdVal = Number(this.threshold)
}, 10)
})
},
methods: {
closeSwipe(e) {
......@@ -37,7 +41,7 @@ export default {
change(e) {
this.$emit('change', {
isOpen: e.open === 'right',
param:this.param
param: this.param
})
if (this.isShow !== e.open) {
this.isShow = e.open
......
......@@ -9,7 +9,7 @@
<view class="fui-switch__input-def" :style="{background:val?color:'#dfdfdf',borderColor:val?color:borderColor}"
:class="{'fui-switch__input--checked':val,'fui-checkbox__disabled':disabled,'fui-switch__color':val && !color}"
v-if="type==='switch'">
<switch class="fui-switch__hidden" @change="change" :name="name" :checked="val" :disabled="disabled"
<switch class="fui-switch__hidden" :class="{'fui-pointer__events':isLabel}" @change="change" :name="name" :checked="val" :disabled="disabled"
:color="color">
</switch>
</view>
......@@ -18,7 +18,8 @@
:style="{background:val?color:'#fff',border:val?`1px solid ${color}`:`1px solid ${borderColor}`}" v-else>
<view class="fui-check__mark" :style="{borderBottomColor:checkMarkColor,borderRightColor:checkMarkColor}"
v-if="val"></view>
<switch class="fui-switch__hidden" style="opacity: 0;position: absolute;" @change="change" :name="name" :type="isNvue?'switch':'checkbox'"
<switch class="fui-switch__hidden" :class="{'fui-pointer__events':isLabel}"
style="opacity: 0;position: absolute;" @change="change" :name="name" :type="isNvue?'switch':'checkbox'"
:checked="val" :disabled="disabled"></switch>
</view>
</view>
......@@ -87,7 +88,8 @@
// #endif
return {
val: false,
isNvue: isNvue
isNvue: isNvue,
isLabel: false
};
},
watch: {
......@@ -99,6 +101,7 @@
this.val = this.checked;
this.label = this.getParent();
if (this.label) {
this.isLabel = true
this.label.childrens.push(this)
}
},
......@@ -273,6 +276,13 @@
/* #endif */
}
/* #ifdef H5 */
.fui-pointer__events {
pointer-events: none;
}
/* #endif */
.fui-checkbox__disabled {
opacity: 0.6;
}
......
......@@ -482,6 +482,7 @@
.fui-tabs__line-center {
justify-content: center;
left: 0;
}
.fui-tabs__ac-line {
......@@ -492,10 +493,6 @@
width: 45rpx !important;
}
.fui-tabs__line-center {
left: 0;
}
/* #ifndef APP-NVUE */
.fui-tabs__selected-color {
color: var(--fui-color-primary, #465CFF) !important;
......
......@@ -57,4 +57,6 @@ export function useI18n(namespace?: string): {
// 为什么要编写此函数?
// 主要用于配合vscode i18nn ally插件。此功能仅用于路由和菜单。请在其他地方使用useI18n
export const t = (key: string) => key
export function t(key: string) {
return key
}
......@@ -26,7 +26,7 @@ const Message = {
},
}
const createErrorModal = (options: { title: string; content: string }) => {
function createErrorModal(options: { title: string; content: string }) {
uni.showModal({
title: options.title,
content: options.content,
......
......@@ -2,7 +2,7 @@ import type { GlobConfig } from '/#/config'
import { getAppEnvConfig } from '/@/utils/env'
export const useGlobSetting = (): Readonly<GlobConfig> => {
export function useGlobSetting(): Readonly<GlobConfig> {
const {
VITE_GLOB_APP_NAME,
VITE_GLOB_APP_DESCRIPTION,
......
import { createSSRApp } from 'vue'
import * as Pinia from 'pinia'
import App from './App.vue'
import { setupAppConfig } from '/@/config/app'
import { setupStore } from '/@/store'
import { setupI18n } from '/@/locales'
import fuiConfig from './components/FirstUI/fui-config'
import 'uno.css'
import App from './App.vue'
import { setupAppConfig } from '@/config/app'
import { setupStore } from '@/store'
import { setupI18n } from '@/locales'
import FuiConfig from '@/components/firstui/fui-config'
export function createApp() {
const app = createSSRApp(App)
......@@ -24,7 +22,7 @@ export function createApp() {
// 全局组件配置
// @ts-expect-error
uni.$fui = fuiConfig
uni.$fui = FuiConfig
return {
app,
......
......@@ -2,8 +2,8 @@
"name" : "Beta App",
"appid" : "__UNI__2E9441A",
"description" : "APP 基础工程",
"versionName" : "3.0.2.5",
"versionCode" : 111,
"versionName" : "3.0.3.0",
"versionCode" : 112,
"transformPx" : false,
"locale" : "zh-Hans",
/* 5+App特有相关 */// 配置文件详细说明
......
......@@ -75,7 +75,7 @@
"autoscan": true,
"custom": {
// https://doc.firstui.cn/docs/introduce.html
"^fui-(.*)": "@/components/FirstUI/fui-$1/fui-$1.vue",
"^fui-(.*)": "@/components/firstui/fui-$1/fui-$1.vue",
// https://ext.dcloud.net.cn/plugin?id=55#detail
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
......@@ -84,7 +84,11 @@
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
"backgroundColor": "#F8F8F8",
"app-plus": {
"bounce": "none",
"scrollIndicator": "none"
}
},
"resizable": true
}
......@@ -38,7 +38,7 @@
</view>
</template>
<style>
<style scoped>
page {
background-color: #fff;
font-weight: normal;
......@@ -68,7 +68,7 @@
.fui-title {
text-align: center;
font-weight: 500;
color: #333333;
color: #333;
padding-top: 48rpx;
}
......
......@@ -27,7 +27,7 @@
}))
})
const preview = (index: number) => {
function preview(index: number) {
uni.previewImage({
urls: images.value.map((item: { src: string }) => item.src),
current: index,
......
......@@ -70,7 +70,7 @@
model.search = e.detail.value || ''
}
const choose = (value: any) => {
function choose(value: any) {
if (model.params?.multiple) {
data.value.list[value.index].data[value.subIndex].checked = !value.checked
} else {
......@@ -79,7 +79,7 @@
}
}
const callback = (result: any) => {
function callback(result: any) {
uni.$emit('chooseShootOrderReceiverUser', result)
uni.navigateBack()
}
......@@ -156,7 +156,7 @@
justify-content: space-between;
padding: 20rpx 30rpx;
background-color: #fff;
box-shadow: 0 -2rpx 10rpx 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 -2rpx 10rpx 0 rgb(0 0 0 / 10%);
.opts-wrap {
width: 100%;
......
......@@ -86,7 +86,7 @@
display: flex;
align-items: center;
justify-content: center;
margin: 50rpx 0 30rpx 0;
margin: 50rpx 0 30rpx;
}
.fui-item__icon,
......
......@@ -259,12 +259,18 @@ export class VAxios {
const { requestOptions } = this.options
const opt: RequestOptions = Object.assign({}, requestOptions, options)
let opt: RequestOptions = Object.assign({}, requestOptions, options)
const { beforeRequestHook, requestCatchHook, transformRequestHook } = transform || {}
const { beforeRequestHook, requestCatchHook, transformRequestHook, inject } = transform || {}
if (inject && isFunction(inject)) {
const result = inject(conf, opt)
conf = result.config
opt = result.options
}
if (beforeRequestHook && isFunction(beforeRequestHook)) {
conf = beforeRequestHook(conf, opt)
}
conf.requestOptions = opt
conf = this.supportFormData(conf)
......
......@@ -5,7 +5,9 @@ import { isFunction } from '/@/utils/is'
// Used to store the identification and cancellation function of each request
let pendingMap = new Map<string, Canceler>()
export const getPendingUrl = (config: AxiosRequestConfig) => [config.method, config.url].join('&')
export function getPendingUrl(config: AxiosRequestConfig) {
return [config.method, config.url].join('&')
}
export class AxiosCanceler {
/**
......
import type { AxiosError, AxiosInstance } from 'axios'
/**
* 请求重试机制
*/
......
......@@ -12,6 +12,15 @@ export interface CreateAxiosOptions extends AxiosRequestConfig {
export abstract class AxiosTransform {
/**
* 注入自定义配置,在请求方法调用时
* 允许动态修改本次请求的 config 和 options
*/
inject?: (
config: AxiosRequestConfig,
options: RequestOptions,
) => { config: AxiosRequestConfig; options: RequestOptions }
/**
* @description: Process configuration before request
* @description: Process configuration before request
*/
......
......@@ -267,8 +267,14 @@ export const defHttp = createAxios({
// other api url
// export const otherHttp = createAxios({
// transform: {
// inject: (config: AxiosRequestConfig<any>, options: http.RequestOptions) => {
// // TODO: 根据实际项目配置
// return { config, options }
// },
// },
// requestOptions: {
// apiUrl: 'xxx',
// urlPrefix: 'xxx',
// },
// });
// })
......@@ -3,7 +3,7 @@ import type { App, Plugin } from 'vue'
import { unref } from 'vue'
import { isObject } from '/@/utils/is'
export const noop = () => {}
export function noop() {}
/**
* @description: Set ui mount node
......@@ -50,7 +50,7 @@ export function getDynamicProps<T, U>(props: T): Partial<U> {
return ret as Partial<U>
}
export const withInstall = <T>(component: T, alias?: string) => {
export function withInstall<T>(component: T, alias?: string) {
const comp = component as any
comp.install = (app: App) => {
app.component(comp.name || comp.displayName, component)
......
......@@ -15,7 +15,7 @@ const PROXY_LIST: [[string, string]?] = [
* 将内部地址(内网)转换成代理/预览地址(公网)
* @param url 内网地址
*/
export const getExtranetUrl = (url: string): string => {
export function getExtranetUrl(url: string): string {
let uri = url
PROXY_LIST.forEach((proxy) => {
......@@ -30,7 +30,7 @@ export const getExtranetUrl = (url: string): string => {
* eg: 主要用于解决内网文件上传后预览,但是实际上传存储时还是内网地址的问题
* @param url 包含代理/公网地址的内容
*/
export const getIntranetUrl = (url: string): string => {
export function getIntranetUrl(url: string): string {
let uri = url
PROXY_LIST.forEach((proxy) => {
......@@ -45,7 +45,7 @@ export const getIntranetUrl = (url: string): string => {
* @param body 接口返回的内容
* @returns 替换本地链接后的数据结果
*/
export const handleResponseResource = <T>(body: T, options: Recordable) => {
export function handleResponseResource<T>(body: T, options: Recordable) {
for (const [intranet, extranet] of PROXY_LIST) {
// 当需要处理内外网资源地址映射时,进行内容处理
const isIntranet = options.apiUrl.includes(intranet)
......
......@@ -10,7 +10,7 @@ export function setBadge(number = 0) {
// #endif
}
export function listenMessage() {
export function listen() {
// 监听在线消息
uni.onPushMessage((res) => {
if (res.type !== 'receive') {
......
// #ifdef APP-PLUS
import checkVersion from '@/uni_modules/uni-upgrade-center-app/utils/check-update'
// #endif
export function checkUpgrade(toast = false) {
......
......@@ -2,7 +2,7 @@ module.exports = {
root: true,
plugins: ['stylelint-order'],
customSyntax: 'postcss-less',
extends: ['stylelint-config-standard', 'stylelint-config-prettier'],
extends: ['stylelint-config-standard'],
rules: {
'selector-class-pattern': null,
'selector-pseudo-class-no-unknown': [
......@@ -36,12 +36,8 @@ module.exports = {
],
'no-empty-source': null,
'named-grid-areas-no-invalid': null,
'unicode-bom': 'never',
'no-descending-specificity': null,
'font-family-no-missing-generic-family-keyword': null,
'declaration-colon-space-after': 'always-single-line',
'declaration-colon-space-before': 'never',
// 'declaration-block-trailing-semicolon': 'always',
'rule-empty-line-before': [
'always',
{
......
// generated by @dcloudio/uni-helper-json/dist/tags.json
declare module 'vue' {
// uni-app 内置组件高亮
export interface GlobalComponents {
block: typeof HTMLElement
view: typeof HTMLElement
'scroll-view': typeof HTMLElement
'match-media': typeof HTMLElement
swiper: typeof HTMLElement
'swiper-item': typeof HTMLElement
'movable-view': typeof HTMLElement
'movable-area': typeof HTMLElement
text: typeof HTMLElement
'rich-text': typeof HTMLElement
progress: typeof HTMLElement
button: typeof HTMLElement
'checkbox-group': typeof HTMLElement
checkbox: typeof HTMLElement
form: typeof HTMLElement
input: typeof HTMLElement
label: typeof HTMLElement
picker: typeof HTMLElement
'picker-view': typeof HTMLElement
'radio-group': typeof HTMLElement
radio: typeof HTMLElement
slider: typeof HTMLElement
switch: typeof HTMLElement
textarea: typeof HTMLElement
navigator: typeof HTMLElement
audio: typeof HTMLElement
image: typeof HTMLElement
video: typeof HTMLElement
map: typeof HTMLElement
canvas: typeof HTMLElement
'web-view': typeof HTMLElement
'cover-view': typeof HTMLElement
'cover-image': typeof HTMLElement
icon: typeof HTMLElement
'picker-view-column': typeof HTMLElement
camera: typeof HTMLElement
'live-player': typeof HTMLElement
'live-pusher': typeof HTMLElement
'open-data': typeof HTMLElement
ad: typeof HTMLElement
'ad-draw': typeof HTMLElement
'navigation-bar': typeof HTMLElement
'custom-tab-bar': typeof HTMLElement
'page-meta': typeof HTMLElement
editor: typeof HTMLElement
'unicloud-db': typeof HTMLElement
}
}
export {}
// generated by @dcloudio/uni-helper-json/dist/tags.json
declare module 'vue' {
// shime-uni.d.ts
type Hooks = App.AppInstance & Page.PageInstance
type ComponentCustomOptions = Hooks
// uni-app components
interface UniComponent {
[key in string]: any
}
export interface GlobalComponents {
block: UniComponent
view: UniComponent
'scroll-view': UniComponent
'match-media': UniComponent
swiper: UniComponent
'swiper-item': UniComponent
'movable-view': UniComponent
'movable-area': UniComponent
text: UniComponent
'rich-text': UniComponent
progress: UniComponent
button: UniComponent
'checkbox-group': UniComponent
checkbox: UniComponent
form: UniComponent
input: UniComponent
label: UniComponent
picker: UniComponent
'picker-view': UniComponent
'radio-group': UniComponent
radio: UniComponent
slider: UniComponent
switch: UniComponent
textarea: UniComponent
navigator: UniComponent
audio: UniComponent
image: UniComponent
video: UniComponent
map: UniComponent
canvas: UniComponent
'web-view': UniComponent
'cover-view': UniComponent
'cover-image': UniComponent
icon: UniComponent
'picker-view-column': UniComponent
camera: UniComponent
'live-player': UniComponent
'live-pusher': UniComponent
'open-data': UniComponent
ad: UniComponent
'ad-draw': UniComponent
'navigation-bar': UniComponent
'custom-tab-bar': UniComponent
'page-meta': UniComponent
editor: UniComponent
'unicloud-db': UniComponent
}
}
export {}
import { defineConfig } from 'unocss'
// https://github.com/MellowCo/unocss-preset-weapp
import presetWeapp from 'unocss-preset-weapp'
import { defaultAttributes, transformerAttributify, transformerClass } from 'unocss-preset-weapp/transformer'
......
......@@ -30,6 +30,9 @@ export default ({ mode }: ConfigEnv): UserConfig => {
optimizeDeps: {
include: ['lodash-es', '@vueuse/core'],
},
esbuild: {
drop: ['console', 'debugger'],
},
build: {
target: 'es2015',
sourcemap: !!isDevFn(mode),
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论