This commit is contained in:
oneao committed 2025-09-30 17:26:30 +08:00
1 parent 92fbbf7c6d
commit b03e2c1e69
149 files changed
+925 -14628

No files matched your search

@@ -1,5 +1,5 @@
{
"name": "base-uniapp2",
"name": "base-uniapp3",
"type": "module",
"version": "0.0.0",
"private": true,
@@ -89,7 +89,7 @@
},
"devDependencies": {
"@antfu/eslint-config": "^5.2.1",
"@dcloudio/types": "^3.4.8",
"@dcloudio/types": "^3.4.21",
"@dcloudio/uni-automator": "3.0.0-4070620250821001",
"@dcloudio/uni-cli-shared": "3.0.0-4070620250821001",
"@dcloudio/uni-stacktracey": "3.0.0-4070620250821001",
@@ -100,7 +100,7 @@
"@types/node": "^20.17.9",
"@uni-helper/plugin-uni": "0.1.0",
"@uni-helper/uni-env": "^0.1.8",
"@uni-helper/uni-types": "^1.0.0-alpha.6",
"@uni-helper/uni-types": "1.0.0-alpha.6",
"@uni-helper/vite-plugin-uni-components": "0.2.0",
"@uni-helper/vite-plugin-uni-layouts": "0.1.11",
"@uni-helper/vite-plugin-uni-manifest": "^0.2.8",
@@ -121,12 +121,7 @@
"terser": "^5.44.0",
"typescript": "~5.8.3",
"unplugin-auto-import": "^20.0.0",
"vite": "npm:rolldown-vite@7.1.12",
"vite": "^7.1.7",
"vue-tsc": "^3.0.7"
},
"pnpm": {
"overrides": {
"vite": "npm:rolldown-vite@7.1.12"
}
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,25 @@
{
"setting": {
"es6": true,
"postcss": true,
"minified": true,
"uglifyFileName": false,
"enhance": true,
"packNpmRelationList": [],
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"useCompilerPlugins": false,
"minifyWXML": true
},
"compileType": "miniprogram",
"simulatorPluginLibVersion": {},
"packOptions": {
"ignore": [],
"include": []
},
"appid": "wxff43f54d4267a569",
"editorSetting": {}
}
@@ -0,0 +1,14 @@
{
"libVersion": "3.10.2",
"projectname": "base-uniapp-main",
"setting": {
"urlCheck": true,
"coverView": true,
"lazyloadPlaceholderEnable": false,
"skylineRenderEnable": false,
"preloadBackgroundData": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"compileHotReLoad": true
}
}
@@ -54,9 +54,10 @@ const emit = defineEmits(['update:visible', 'update:value', 'change'])
const _visible = ref(props.visible)
watch(() => props.visible, val => _visible.value = val)
watch(() => props.visible, val => _visible.value = val)
const loading = ref(true)
const searchValue = ref('')
const pagination = ref({
current: 1,
@@ -100,7 +101,7 @@ function select(option, toggle) {
)
_visible.value = false
emit('update:visible',false)
emit('update:visible', false)
emit('change', selectedOption)
}
}
@@ -193,19 +194,18 @@ function getAutocompleteDataEx() {
disabled: !!item.disabled,
...item,
}))
}).finally(() => {
loading.value = false
})
}
function getAutocompleteDataSingle() {
}
function handleCancel(){
function handleCancel() {
_visible.value = false
emit('update:visible',false)
emit('update:visible', false)
}
</script>
@@ -311,34 +311,35 @@ function handleCancel(){
</sar-radio-group>
</scroll-view>
</view>
</view>
<view class="sar-popout__footer">
<sar-pagination
:current="pagination.current"
:total="pagination.total"
:page-size="pagination.pageSize"
type="simple"
root-class="picker-select__pagination-root"
@change="handlePagationChange"
>
<template #prev>
<sar-button type="default" :disabled="isPrevDisabled" size="mini">
上一页
</sar-button>
</template>
<template #next>
<sar-button type="default" :disabled="isNextDisabled" size="mini" :loading='loading'>
下一页
</sar-button>
</template>
</sar-pagination>
<sar-button
v-if="props.type === 'multiple'"
:root-style="{ width: '100%' }"
>
确认
</sar-button>
<view class="sar-popout__footer">
<sar-pagination
:current="pagination.current"
:total="pagination.total"
:page-size="pagination.pageSize"
type="simple"
root-class="picker-select__pagination-root"
@change="handlePagationChange"
>
<template #prev>
<sar-button type="default" :disabled="isPrevDisabled" size="mini" :loading="loading">
上一页
</sar-button>
</template>
<template #next>
<sar-button type="default" :disabled="isNextDisabled" size="mini" :loading="loading">
下一页
</sar-button>
</template>
</sar-pagination>
<sar-button
v-if="props.type === 'multiple'"
:root-style="{ width: '100%' }"
>
确认
</sar-button>
</view>
</view>
</template>
</sar-popout>
@@ -350,7 +351,7 @@ function handleCancel(){
box-sizing: border-box;
flex-direction: column;
position: absolute;
left: 1rem;
left: 32rpx;
z-index: 2;
display: flex;
flex-direction: row;
@@ -377,7 +378,7 @@ function handleCancel(){
box-sizing: border-box;
display: flex;
flex-direction: column;
gap: 0.5rem;
gap: 16rpx;
align-items: center;
padding: var(--sar-popout-footer-gap-y) var(--sar-popout-footer-gap-x);
}
@@ -2,6 +2,7 @@ import { useUserStore } from '@/store'
const whiteList = [
'/pages-sub/login/index',
'/pages/account/index',
]
export const navigateToInterceptor = {
@@ -165,6 +165,8 @@ page {
</style>
<style lang="scss" scoped>
@import '@/style/mixins.scss';
.form-container {
padding: 0rpx 32rpx;
}
@@ -187,12 +189,11 @@ page {
.form-list {
display: flex;
flex-direction: column;
gap: 36rpx;
@include flexGap(36rpx, column);
}
.form-label {
display: flex;
gap: 0.5rem;
font-size: 28rpx;
}
@@ -0,0 +1,101 @@
<script setup lang="ts">
import { dialog, toast } from 'sard-uniapp'
import { useUserStore } from '@/store'
const userStore = useUserStore()
function handleLoginOut() {
dialog.confirm({
title: '提示',
message: '确定退出登录?',
onConfirm() {
toast.success('退出成功')
userStore.reset()
},
})
}
</script>
<template>
<view class="account-container">
<view class="account-header">
<view class="header-bg" />
<view class="welcome">
<view class="welcome-title">
{{ userStore.isLogined ? '✨ 您好,欢迎回来!' : '你好,请登录!' }}
</view>
<sar-tag v-if="userStore.isLogined" theme="primary" round>
已登录
</sar-tag>
<sar-tag v-else theme="secondary">
未登录
</sar-tag>
</view>
<view class="info-row">
<sar-icon name="user" size="28rpx" color="#0064fa" />
<view class="info-label">
账号
</view>
<view class="info-value">
{{ userStore.isLogined ? userStore.userInfo.userid : '登录后查看' }}
</view>
</view>
<view class="info-row">
<sar-icon name="organization" size="28rpx" color="#0064fa" />
<view class="info-label">
机构码
</view>
<view class="info-value">
{{ userStore.isLogined ? userStore.userInfo.orgid : '登录后查看' }}
</view>
</view>
</view>
<sar-list style="margin-top: 32rpx;">
<sar-list-item title="修改密码" hover arrow />
<sar-list-item title="退出登录" hover arrow @click="handleLoginOut" />
</sar-list>
</view>
</template>
<style lang="scss" scoped>
.account-header {
position: relative;
padding: 40rpx 32rpx;
background-color: #fff;
border-bottom-left-radius: 24rpx;
border-bottom-right-radius: 24rpx;
.welcome {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 32rpx;
z-index: 1;
.welcome-title {
font-weight: 600;
font-size: 34rpx;
color: #222;
}
}
.info-row {
display: flex;
align-items: center;
font-size: 28rpx;
z-index: 1;
margin-top: 24rpx;
.info-label {
width: 120rpx;
color: #555;
}
.info-value {
flex: 1;
color: #111;
font-weight: 500;
}
}
}
</style>
@@ -0,0 +1,104 @@
<script setup lang="ts">
import { ref } from 'vue'
const swiperCurrent = ref(0)
const swiperList = [
{},
{},
{},
]
</script>
<template>
<view>
<view class="swiper-container">
<swiper
:current="swiperCurrent"
autoplay
:interval="3000"
class="swiper"
@change="swiperCurrent = $event.detail.current"
>
<swiper-item>
<image
src="@/static/images/800x400.png"
style="width: 100%;height:100%"
/>
</swiper-item>
<swiper-item>
<image
src="@/static/images/800x400.png"
style="width: 100%;height:100%"
/>
</swiper-item>
<swiper-item>
<image
src="@/static/images/800x400.png"
style="width: 100%;height:100%"
/>
</swiper-item>
</swiper>
<sar-swiper-dot
:current="swiperCurrent"
:list="swiperList"
/>
</view>
<view class="grid-container">
<sar-grid :columns="2" gap="20rpx">
<sar-grid-item
text="装箱"
icon="image"
:root-style="{
flex: '0 0 100%',
width: '100%',
}"
>
<view class="grid-item">
<image src="@/static/images/柴犬.png" />
<text>内容</text>
</view>
</sar-grid-item>
<sar-grid-item>
<view class="grid-item">
<image src="@/static/images/柴犬.png" />
<text>内容</text>
</view>
</sar-grid-item>
<sar-grid-item>
<view class="grid-item">
<image src="@/static/images/柴犬.png" />
<text>内容</text>
</view>
</sar-grid-item>
</sar-grid>
</view>
</view>
</template>
<style lang="scss" scoped>
.swiper-container {
position: relative;
.swiper {
height: 400rpx;
width: 100%;
}
}
.grid-container {
margin-top: 32rpx;
.grid-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 28rpx;
image {
width: 128rpx;
height: 128rpx;
}
text {
margin-top: 16rpx;
font-weight: bold;
}
}
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@@ -0,0 +1,29 @@
@font-face {
font-family: 'iconfont'; /* Project id 5031675 */
src: url('data:font/ttf;charset=utf-8;base64,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 truncated
format('truetype');
}
.iconfont {
font-family: 'iconfont' !important;
font-size: 32rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.iconfont-chaiquan:before {
content: '\e647';
}
.iconfont-company:before {
content: '\e6b1';
}
.iconfont-lock:before {
content: '\e85f';
}
.iconfont-user:before {
content: '\e888';
}
@@ -0,0 +1,23 @@
@mixin flexGap($size, $direction) {
/* #ifndef WEB */
gap: $size; // 先写声明
/* #endif */
/* #ifdef WEB */
@if $direction == column {
& > * {
margin-bottom: $size;
}
& > *:last-child {
margin-bottom: 0;
}
} @else {
& > * {
margin-right: $size;
}
& > *:last-child {
margin-right: 0;
}
}
/* #endif */
}
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人中心</title>
<style>
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: #f4f5f7;
color: #333;
}
.header {
background: linear-gradient(135deg, #2f3e46, #354f52);
color: white;
padding: 20px;
}
.header h2 {
margin: 0 0 6px;
font-size: 18px;
font-weight: 600;
}
.header p {
margin: 4px 0;
font-size: 14px;
color: #d9d9d9;
}
.list {
margin: 16px;
background: #fff;
border-radius: 10px;
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
overflow: hidden;
}
.list-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 16px;
font-size: 15px;
border-bottom: 1px solid #eee;
cursor: pointer;
}
.list-item:last-child {
border-bottom: none;
}
.list-item span {
color: #666;
}
.list-item.danger {
color: #d9534f;
font-weight: 500;
}
.footer {
text-align: center;
padding: 12px;
font-size: 12px;
color: #aaa;
}
</style>
</head>
<body>
<div class="header">
<h2>个人中心</h2>
<p>机构码:123456</p>
<p>账户:zhangsan</p>
</div>
<div class="list">
<div class="list-item">
<span>修改密码</span>
</div>
<div class="list-item danger">
<span>退出登录</span>
</div>
</div>
<div class="footer">
© 2025 MyApp
</div>
</body>
</html>
@@ -14,7 +14,7 @@ import AutoImport from 'unplugin-auto-import/vite'
import { defineConfig, loadEnv } from 'vite'
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
export default defineConfig(({ command, mode }) => {
const { UNI_PLATFORM } = process.env
const env = loadEnv(mode, path.resolve(process.cwd(), 'env'))
@@ -25,7 +25,8 @@ export default defineConfig(({ mode }) => {
return defineConfig({
envDir: './env',
plugins: [
legacy({
(command === 'build' && UNI_PLATFORM === 'h5')
&& legacy({
targets: ['defaults', 'ie >= 11', 'chrome 52'],
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
}),
@@ -112,22 +113,17 @@ export default defineConfig(({ mode }) => {
// esbuild: {
// drop: VITE_DELETE_CONSOLE === 'true' ? ['console', 'debugger'] : ['debugger'],
// },
// 构建优化
build: {
sourcemap: false,
// 方便非h5端调试
// sourcemap: VITE_SHOW_SOURCEMAP === 'true', // 默认是false
target: 'es6', // legacy 插件会处理 polyfill
minify: mode === 'development' ? false : 'terser', // 使用 terser 保证 ES6 语法降级
terserOptions: {
compress: {
drop_debugger: true,
},
},
target: 'es6',
// 开发环境不用压缩
minify: mode === 'development' ? false : 'esbuild',
},
optimizeDeps: {
exclude: ['sard-uniapp'],
rollupOptions: {
// 这里放依赖优化相关配置,例如 external 或 output.manualChunks
},
},
})
})
-22
View File
@@ -1,22 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
-56
View File
@@ -1,56 +0,0 @@
{
"editor.cursorSmoothCaretAnimation": "on",
// Disable the default formatter, use eslint instead
"prettier.enable": false,
"editor.formatOnSave": false,
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "style/*", "severity": "off", "fixable": true },
{ "rule": "format/*", "severity": "off", "fixable": true },
{ "rule": "*-indent", "severity": "off", "fixable": true },
{ "rule": "*-spacing", "severity": "off", "fixable": true },
{ "rule": "*-spaces", "severity": "off", "fixable": true },
{ "rule": "*-order", "severity": "off", "fixable": true },
{ "rule": "*-dangle", "severity": "off", "fixable": true },
{ "rule": "*-newline", "severity": "off", "fixable": true },
{ "rule": "*quotes", "severity": "off", "fixable": true },
{ "rule": "*semi", "severity": "off", "fixable": true }
],
// Enable eslint for all supported languages
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml",
"toml",
"xml",
"gql",
"graphql",
"astro",
"svelte",
"css",
"less",
"scss",
"pcss",
"postcss"
],
"files.associations": {
"pages.json": "jsonc",
"manifest.json": "jsonc"
}
}
-2
View File
@@ -1,2 +0,0 @@
VITE_APP_PORT = 9000
-9
View File
@@ -1,9 +0,0 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE = false
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false
# 后台请求地址
# VITE_SERVER_BASEURL = 'https://dev.xxx.com'
-7
View File
@@ -1,7 +0,0 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'production'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE = true
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false
-6
View File
@@ -1,6 +0,0 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE = false
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false
-23
View File
@@ -1,23 +0,0 @@
<!doctype html>
<html build-time="%BUILD_TIME%">
<head>
<meta charset="UTF-8" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<script>
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' : ''}" />`)
</script>
<title>unibest</title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
-127
View File
@@ -1,127 +0,0 @@
{
"name": "base-uniapp",
"type": "module",
"version": "0.0.0",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
"dev:app": "uni -p app",
"dev:app:test": "uni -p app --mode test",
"dev:app:prod": "uni -p app --mode production",
"dev:app-android": "uni -p app-android",
"dev:app-ios": "uni -p app-ios",
"dev:custom": "uni -p",
"dev": "node --experimental-loader ./scripts/window-path-loader.js node_modules/@dcloudio/vite-plugin-uni/bin/uni.js",
"dev:test": "uni --mode test",
"dev:prod": "uni --mode production",
"dev:h5": "uni",
"dev:h5:test": "uni --mode test",
"dev:h5:prod": "uni --mode production",
"dev:h5:ssr": "uni --ssr",
"dev:mp": "uni -p mp-weixin",
"dev:mp:test": "uni -p mp-weixin --mode test",
"dev:mp:prod": "uni -p mp-weixin --mode production",
"dev:mp-alipay": "uni -p mp-alipay",
"dev:mp-baidu": "uni -p mp-baidu",
"dev:mp-jd": "uni -p mp-jd",
"dev:mp-kuaishou": "uni -p mp-kuaishou",
"dev:mp-lark": "uni -p mp-lark",
"dev:mp-qq": "uni -p mp-qq",
"dev:mp-toutiao": "uni -p mp-toutiao",
"dev:mp-weixin": "uni -p mp-weixin",
"dev:mp-xhs": "uni -p mp-xhs",
"dev:quickapp-webview": "uni -p quickapp-webview",
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
"build:app": "uni build -p app",
"build:app:test": "uni build -p app --mode test",
"build:app:prod": "uni build -p app --mode production",
"build:app-android": "uni build -p app-android",
"build:app-ios": "uni build -p app-ios",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5:test": "uni build --mode test",
"build:h5:prod": "uni build --mode production",
"build": "uni build",
"build:test": "uni build --mode test",
"build:prod": "uni build --mode production",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "uni build -p mp-alipay",
"build:mp": "uni build -p mp-weixin",
"build:mp:test": "uni build -p mp-weixin --mode test",
"build:mp:prod": "uni build -p mp-weixin --mode production",
"build:mp-baidu": "uni build -p mp-baidu",
"build:mp-jd": "uni build -p mp-jd",
"build:mp-kuaishou": "uni build -p mp-kuaishou",
"build:mp-lark": "uni build -p mp-lark",
"build:mp-qq": "uni build -p mp-qq",
"build:mp-toutiao": "uni build -p mp-toutiao",
"build:mp-weixin": "uni build -p mp-weixin",
"build:mp-xhs": "uni build -p mp-xhs",
"build:quickapp-webview": "uni build -p quickapp-webview",
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "uni build -p quickapp-webview-union"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-4070620250821001",
"@dcloudio/uni-app-harmony": "3.0.0-4070620250821001",
"@dcloudio/uni-app-plus": "3.0.0-4070620250821001",
"@dcloudio/uni-components": "3.0.0-4070620250821001",
"@dcloudio/uni-h5": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-alipay": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-baidu": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-harmony": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-jd": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-lark": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-qq": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-toutiao": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-weixin": "3.0.0-4070620250821001",
"@dcloudio/uni-mp-xhs": "3.0.0-4070620250821001",
"@dcloudio/uni-quickapp-webview": "3.0.0-4070620250821001",
"@iconify/vue": "^5.0.0",
"abortcontroller-polyfill": "^1.7.8",
"dayjs": "1.11.10",
"pinia": "2.0.36",
"pinia-plugin-persistedstate": "3.2.1",
"sard-uniapp": "^1.24.6",
"vue": "^3.5.21",
"z-paging": "2.8.7"
},
"devDependencies": {
"@antfu/eslint-config": "^5.2.1",
"@dcloudio/types": "^3.4.8",
"@dcloudio/uni-automator": "3.0.0-4070620250821001",
"@dcloudio/uni-cli-shared": "3.0.0-4070620250821001",
"@dcloudio/uni-stacktracey": "3.0.0-4070620250821001",
"@dcloudio/vite-plugin-uni": "3.0.0-4070620250821001",
"@esbuild/darwin-arm64": "0.20.2",
"@esbuild/darwin-x64": "0.20.2",
"@rollup/rollup-darwin-x64": "^4.28.0",
"@types/node": "^20.17.9",
"@uni-helper/plugin-uni": "0.1.0",
"@uni-helper/uni-env": "^0.1.8",
"@uni-helper/uni-types": "^1.0.0-alpha.6",
"@uni-helper/vite-plugin-uni-components": "0.2.0",
"@uni-helper/vite-plugin-uni-layouts": "0.1.11",
"@uni-helper/vite-plugin-uni-manifest": "^0.2.8",
"@uni-helper/vite-plugin-uni-platform": "^0.0.5",
"@uni-ku/bundle-optimizer": "^1.3.3",
"@vitejs/plugin-legacy": "^6.0.0",
"@vitejs/plugin-vue": "^6.0.1",
"@vue/tsconfig": "^0.8.1",
"eslint": "^9.34.0",
"eslint-plugin-format": "^1.0.1",
"miniprogram-api-typings": "^4.1.0",
"postcss": "^8.4.49",
"postcss-html": "^1.8.0",
"postcss-scss": "^4.0.9",
"rollup-plugin-visualizer": "^6.0.3",
"sass": "1.77.8",
"terser": "^5.44.0",
"typescript": "~5.8.0",
"unplugin-auto-import": "^20.0.0",
"vite": "^5.3.5",
"vue-tsc": "^3.0.6"
}
}
@@ -1,83 +0,0 @@
import { exec } from 'node:child_process'
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
/**
* 打开开发者工具
*/
function _openDevTools() {
const platform = process.platform // darwin, win32, linux
const { UNI_PLATFORM } = process.env // mp, mp-weixin, mp-alipay
const uniPlatformText = UNI_PLATFORM === 'mp' || UNI_PLATFORM === 'mp-weixin' ? '微信小程序' : UNI_PLATFORM === 'mp-alipay' ? '支付宝小程序' : '小程序'
// 项目路径(构建输出目录)
const projectPath = path.resolve(process.cwd(), `dist/dev/${UNI_PLATFORM}`)
// 检查构建输出目录是否存在
if (!fs.existsSync(projectPath)) {
console.log(`❌ ${uniPlatformText}构建目录不存在:`, projectPath)
return
}
console.log(`🚀 正在打开${uniPlatformText}开发者工具...`)
// 根据不同操作系统执行不同命令
let command = ''
if (platform === 'darwin') {
// macOS
if (UNI_PLATFORM === 'mp-weixin') {
command = `/Applications/wechatwebdevtools.app/Contents/MacOS/cli -o "${projectPath}"`
}
else if (UNI_PLATFORM === 'mp-alipay') {
command = `/Applications/小程序开发者工具.app/Contents/MacOS/小程序开发者工具 --p "${projectPath}"`
}
}
else if (platform === 'win32' || platform === 'win64') {
// Windows
if (UNI_PLATFORM === 'mp-weixin') {
command = `"C:\\Program Files (x86)\\Tencent\\微信web开发者工具\\cli.bat" -o "${projectPath}"`
}
}
else {
// Linux 或其他系统
console.log('❌ 当前系统不支持自动打开微信开发者工具')
return
}
exec(command, (error, stdout, stderr) => {
if (error) {
console.log(`❌ 打开${uniPlatformText}开发者工具失败:`, error.message)
console.log(`💡 请确保${uniPlatformText}开发者工具服务端口已启用`)
console.log(`💡 可以手动打开${uniPlatformText}开发者工具并导入项目:`, projectPath)
return
}
if (stderr) {
console.log('⚠️ 警告:', stderr)
}
console.log(`✅ ${uniPlatformText}开发者工具已打开`)
if (stdout) {
console.log(stdout)
}
})
}
export default function openDevTools() {
// 首次构建标记
let isFirstBuild = true
return {
name: 'uni-devtools',
writeBundle() {
if (isFirstBuild && process.env.UNI_PLATFORM?.includes('mp')) {
isFirstBuild = false
_openDevTools()
}
},
}
}
@@ -1,384 +0,0 @@
<script setup lang="ts">
import type { PropType } from 'vue'
import { useIndeterminate } from 'sard-uniapp'
import { computed, ref } from 'vue'
import { getAutocompleteDataApi, getAutocompleteDataExApi } from '@/request/api'
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
type: {
type: String as PropType<'radio' | 'multiple'>,
default: 'radio',
},
value: {
type: null as unknown as PropType<any | any[]>,
default: undefined,
},
labelField: {
type: String,
required: true,
},
valueField: {
type: String,
required: true,
},
viewname: {
type: String,
},
searchcondition: {
type: String,
required: false,
},
userid: {
type: String,
required: false,
},
field1: {
type: String,
required: true,
},
field2: {
type: String,
required: true,
},
searchType: {
type: String as PropType<'default' | 'ex' | 'single'>,
default: 'default',
required: false,
},
})
const emit = defineEmits(['update:visible', 'update:value', 'change'])
const _visible = ref(props.visible)
watch(() => props.visible, val => _visible.value = val)
const loading = ref(true)
const searchValue = ref('')
const pagination = ref({
current: 1,
pageSize: 10,
total: 0,
})
const isPrevDisabled = computed(() => pagination.value.current <= 1)
const isNextDisabled = computed(() =>
pagination.value.current >= Math.ceil(pagination.value.total / pagination.value.pageSize),
)
// 内部 value,双向绑定 props.value
const _value = computed({
get: () => {
if (props.type === 'multiple') {
return Array.isArray(props.value) ? props.value : []
}
return props.value ?? null
},
set: (val) => {
emit('update:value', val)
},
})
const options = ref<any[]>([])
const { allChecked, isIndeterminate, onAllChange } = useIndeterminate(
_value,
options,
)
function select(option, toggle) {
if (!option.disabled) {
toggle(option.value)
if (props.type === 'radio') {
_visible.value = false
const selectedOption = options.value.find(
o => o.value === option.value,
)
_visible.value = false
emit('update:visible',false)
emit('change', selectedOption)
}
}
}
// 显示数量
const count = computed(() => {
if (props.type === 'multiple') {
return `${(_value.value).length || 0} / ${options.value.length}`
}
else {
return _value.value != null ? `1 / ${options.value.length}` : `0 / ${options.value.length}`
}
})
function handleAfterEnter() {
getData()
}
function handlePagationChange(page: number) {
pagination.value.current = page
getData()
}
function handleSearch() {
pagination.value.current = 1
pagination.value.total = 0
pagination.value.pageSize = 10
getData()
}
function getData() {
if (props.searchType === 'ex') {
getAutocompleteDataEx()
}
else if (props.searchType === 'single') {
getAutocompleteDataSingle()
}
else {
getAutocompleteData()
}
}
function getAutocompleteData() {
loading.value = true
getAutocompleteDataApi({
q: searchValue.value,
page: pagination.value.current,
limit: pagination.value.pageSize,
viewname: props.viewname,
field1: props.field1,
field2: props.field2,
}).then((res) => {
pagination.value.total = res.data.total
options.value = res.data.rows.map(item => ({
label: item[props.labelField] ?? '',
value: item[props.valueField] ?? undefined,
disabled: !!item.disabled,
...item,
}))
console.log(res.data.rows)
}).finally(() => {
loading.value = false
})
}
function getAutocompleteDataEx() {
loading.value = true
getAutocompleteDataExApi({
q: searchValue.value,
page: pagination.value.current,
limit: pagination.value.pageSize,
viewname: props.viewname,
field1: props.field1,
field2: props.field2,
userid: props.userid,
searchcondition: props.searchcondition,
}).then((res) => {
pagination.value.total = res.data.total
options.value = res.data.rows.map(item => ({
label: item[props.labelField] ?? '',
value: item[props.valueField] ?? undefined,
disabled: !!item.disabled,
...item,
}))
}).finally(() => {
loading.value = false
})
}
function getAutocompleteDataSingle() {
}
function handleCancel(){
_visible.value = false
emit('update:visible',false)
}
</script>
<template>
<sar-popout
:visible="_visible"
:show-footer="false"
title="请选择"
@enter="handleAfterEnter"
@close="handleCancel"
>
<template v-if="props.type === 'multiple'" #title-prepend>
<view class="sar-checkbox-popout__check-all">
<sar-checkbox
v-model:checked="allChecked"
:indeterminate="isIndeterminate"
@change="onAllChange"
>
{{ count }}
</sar-checkbox>
</view>
</template>
<template #visible="{ already }">
<view v-if="already">
<sar-list-item>
<sar-input
v-model="searchValue"
placeholder="请输入搜索的值"
clearable
@confirm="handleSearch"
>
<template #prepend>
<sar-icon family="sari" name="search" />
</template>
</sar-input>
</sar-list-item>
<view class="sar-checkbox-popout__container">
<scroll-view
class="sar-checkbox-popout__scroll_searchable sar-checkbox-popout__scroll"
scroll-y
trap-scroll
:upper-threshold="0"
:lower-threshold="0"
:throttle="false"
>
<sar-empty
v-if="options.length === 0"
:root-style="{ height: '100%' }"
/>
<sar-checkbox-group
v-else-if="props.type === 'multiple'"
v-model="_value"
:validate-event="false"
>
<template #custom="{ toggle }">
<sar-list inlaid>
<sar-list-item
v-for="option in options"
:key="option.value"
:title="option.label"
@click="select(option, toggle)"
>
<template #icon>
<sar-checkbox
readonly
:value="option.value"
:validate-event="false"
/>
</template>
</sar-list-item>
</sar-list>
</template>
</sar-checkbox-group>
<sar-radio-group
v-else
v-model="_value"
:validate-event="false"
>
<template #custom="{ toggle }">
<sar-list inlaid>
<sar-list-item
v-for="option in options"
:key="option.value"
:title="option.label"
:hover="!option.disabled"
@click="select(option, toggle)"
>
<template #icon>
<sar-radio
:key="option.value"
readonly
:disabled="option.disabled"
:value="option.value"
/>
</template>
</sar-list-item>
</sar-list>
</template>
</sar-radio-group>
</scroll-view>
</view>
</view>
<view class="sar-popout__footer">
<sar-pagination
:current="pagination.current"
:total="pagination.total"
:page-size="pagination.pageSize"
type="simple"
root-class="picker-select__pagination-root"
@change="handlePagationChange"
>
<template #prev>
<sar-button type="default" :disabled="isPrevDisabled" size="mini">
上一页
</sar-button>
</template>
<template #next>
<sar-button type="default" :disabled="isNextDisabled" size="mini" :loading='loading'>
下一页
</sar-button>
</template>
</sar-pagination>
<sar-button
v-if="props.type === 'multiple'"
:root-style="{ width: '100%' }"
>
确认
</sar-button>
</view>
</template>
</sar-popout>
</template>
<style lang="scss" scoped>
.sar-checkbox-popout__check-all {
position: relative;
box-sizing: border-box;
flex-direction: column;
position: absolute;
left: 1rem;
z-index: 2;
display: flex;
flex-direction: row;
align-items: center;
color: var(--sar-tertiary-color);
font-size: var(--sar-text-sm);
}
.sar-checkbox-popout__container {
position: relative;
}
.sar-checkbox-popout__scroll_searchable {
height: var(--sar-checkbox-popout-max-height);
}
.sar-checkbox-popout__scroll {
max-height: var(--sar-checkbox-popout-max-height);
}
.sar-popout__footer {
width: 100%;
position: relative;
box-sizing: border-box;
display: flex;
flex-direction: column;
gap: 0.5rem;
align-items: center;
padding: var(--sar-popout-footer-gap-y) var(--sar-popout-footer-gap-x);
}
</style>
-23
View File
@@ -1,23 +0,0 @@
/// <reference types="vite/client" />
/// <reference types="vite-svg-loader" />
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
interface ImportMetaEnv {
/** 服务端口号 */
readonly VITE_SERVER_PORT: string
/** 是否清除console */
readonly VITE_DELETE_CONSOLE: string
}
interface ImportMeta {
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,41 +0,0 @@
import { useUserStore } from '@/store'
const whiteList = [
'/pages-sub/login/index',
]
export const navigateToInterceptor = {
invoke(args: UniApp.NavigateToOptions) {
const userStore = useUserStore()
console.log('switch')
// 白名单直接放行
if (whiteList.some(path => args.url.startsWith(path))) {
return args
}
console.log('放行')
// 调用 requireLogin,如果未登录,会自动提示并跳转
const ok = userStore.requireLogin()
console.log(`验证结果:${ok}`)
if (!ok) {
return false // 阻止路由跳转
}
console.log('已登录放行')
return args // 已登录则放行
},
}
export const routeInterceptor = {
install() {
uni.addInterceptor('navigateTo', navigateToInterceptor)
uni.addInterceptor('reLaunch', navigateToInterceptor)
uni.addInterceptor('redirectTo', navigateToInterceptor)
uni.addInterceptor('switchTab', navigateToInterceptor)
},
}
@@ -1,6 +0,0 @@
<script setup lang="ts">
</script>
<template>
<div>account</div>
</template>
@@ -1,49 +0,0 @@
<script setup lang="ts">
import { ref } from 'vue'
const label = ref('004')
const value = ref('004')
const visible = ref(false)
function test(){
visible.value = true
}
</script>
<template>
<sar-form label-width="240rpx">
<sar-form-item label="label">
<picker-select-input
v-model:label="label"
v-model:value="value"
viewname="b_user"
label-field="b_name"
value-field="b_id"
field1="b_name"
field2="b_id"
/>
</sar-form-item>
<sar-form-item label="label">
<picker-select-input
v-model:label="label"
v-model:value="value"
viewname="b_con_type"
label-field="b_name"
value-field="b_name"
field1="b_name"
field2="b_id"
/>
</sar-form-item>
</sar-form>
<!-- 调试输出 -->
<view class="p-4">
<view>当前 label: {{ label }}</view>
<view>当前 value: {{ value }}</view>
</view>
</template>
<style lang="scss">
</style>
@@ -1,225 +0,0 @@
import { toast } from 'sard-uniapp'
import dbJson from '@/static/db.json'
import { useUserStore } from '@/store'
import { joinUrl } from '@/utils/common'
import { isH5 } from '@/utils/platform'
function request<T = any>(option: UniApp.RequestOptions): Promise<IResData<T>> & { abort: () => void } {
let task: UniApp.RequestTask | undefined
let aborted = false
const promise = new Promise<IResData<T>>((resolve, reject) => {
// 判断是否是登录请求
const isLogin = option.url?.includes('login')
const readDbJson = new Promise<Record<string, string>>((res, rej) => {
if (isH5) {
// H5:用 request 请求,带时间戳保证最新
const timestamp = Date.now()
uni.request({
url: `/static/db.json?t=${timestamp}`,
method: 'GET',
success: r => res(r.data as Record<string, string>),
fail: err => rej(err),
})
}
else {
// 非 H5 直接返回本地导入的 JSON
res(dbJson)
}
})
readDbJson
.then((dbRes) => {
if (aborted)
return reject(new Error('请求已取消'))
// 组织请求 URL
let reqUrl = ''
const userStore = useUserStore()
const { token, userid, orgid } = userStore.userInfo || {}
if (!dbRes || Object.keys(dbRes).length === 0) {
toast.fail('机构配置获取失败,请联系管理人员!')
return reject(new Error('机构配置获取失败,请联系管理人员!'))
}
if (isLogin) {
const orgidFromData = (option.data as any)?.orgid || ''
reqUrl = dbRes[orgidFromData]
}
else {
reqUrl = dbRes[orgid || '']
}
if (!reqUrl) {
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
const currentRoute = `/${currentPage.route}`
if (currentRoute !== '/pages-sub/login/index') {
uni.showToast({ title: '当前登录已过期,请重新登录', icon: 'error' })
uni.navigateTo({
url: '/pages-sub/login/index',
})
}
else {
uni.showToast({ title: '机构码错误', icon: 'error' })
}
return reject(new Error('机构码错误'))
}
// 设置 headers
const headers: Record<string, any> = { ...(option.header || {}) }
if (!isLogin) {
headers.Authorization = `Bearer ${token}`
headers.userid = encodeURIComponent(userid)
headers.orgid = orgid
}
// 拼接完整 URL
option.url = joinUrl(reqUrl, option.url || '')
option.header = headers
// 发请求
task = uni.request({
...option,
url: option.url,
success: (res) => {
if (aborted)
return reject(new Error('请求已取消'))
if (res.statusCode !== 200) {
console.error('HTTP错误', res.statusCode, res.data)
toast.fail(`请求失败:${res.statusCode}`)
return reject(new Error(`HTTP错误: ${res.statusCode}`))
}
let data: IResData<T>
try {
// 解析最外层响应
data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
// 如果 data.data 是字符串,则解析成对象
if (data.data && typeof data.data === 'string') {
try {
data.data = JSON.parse(data.data)
}
catch {
// 如果解析失败,保持原始字符串即可
console.warn('data.data 不是合法 JSON 字符串', data.data)
}
}
}
catch (err) {
console.log(`解析响应JSON失败:${err}`)
toast.fail('响应数据解析失败')
return reject(new Error('响应数据解析失败'))
}
if (data.code === 200) {
resolve(data)
}
else {
toast.fail(data.message || '请求错误')
reject(new Error(data.message || '请求错误'))
}
// 登录失效处理
if (data.code === 600) {
uni.showToast({ title: '请重新登录', icon: 'none' })
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
const currentRoute = `/${currentPage.route}`
if (currentRoute !== '/pages-sub/login/index') {
uni.navigateTo({ url: '/pages-sub/login/index' })
}
}
},
fail: (err) => {
if (aborted)
return reject(new Error('请求已取消'))
console.log(err)
toast.fail('网络请求失败,请联系管理人员')
reject(new Error(err.errMsg || '网络请求失败'))
},
})
})
.catch((err) => {
toast.fail('机构配置获取失败,请联系管理人员!')
console.error(err)
reject(new Error('机构配置获取失败,请联系管理人员!'))
})
}) as Promise<IResData<T>> & { abort: () => void }
promise.abort = () => {
aborted = true
task?.abort()
}
return promise
}
// GET
request.get = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
return request<T>({
method: 'GET',
url,
data,
...option,
})
}
// PUT
request.put = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
return request<T>({
method: 'PUT',
url,
data,
...option,
})
}
// DELETE
request.delete = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
return request<T>({
method: 'DELETE',
url,
data,
...option,
})
}
// POST JSON
request.postJson = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
return request<T>({
method: 'POST',
url,
data,
header: {
'Content-Type': 'application/json',
...(option?.header || {}),
},
...option,
})
}
// POST 表单
request.postForm = <T = any>(url: string, data?: any, option?: UniApp.RequestOptions) => {
return request<T>({
method: 'POST',
url,
data,
header: {
'Content-Type': 'application/x-www-form-urlencoded',
...(option?.header || {}),
},
...option,
})
}
export default request
@@ -1,25 +0,0 @@
@font-face {
font-family: "iconfont"; /* Project id 5031675 */
src:
url('data:font/ttf;charset=utf-8;base64,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') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.iconfont-company:before {
content: "\e6b1";
}
.iconfont-lock:before {
content: "\e85f";
}
.iconfont-user:before {
content: "\e888";
}
@@ -1,154 +0,0 @@
import path from 'node:path'
import process from 'node:process'
import Uni from '@uni-helper/plugin-uni'
import Components from '@uni-helper/vite-plugin-uni-components'
import UniLayouts from '@uni-helper/vite-plugin-uni-layouts'
import UniPlatform from '@uni-helper/vite-plugin-uni-platform'
import Optimization from '@uni-ku/bundle-optimizer'
import legacy from '@vitejs/plugin-legacy'
import { visualizer } from 'rollup-plugin-visualizer'
import AutoImport from 'unplugin-auto-import/vite'
import { defineConfig, loadEnv } from 'vite'
import openDevTools from './scripts/open-dev-tools'
// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
const { UNI_PLATFORM } = process.env
const env = loadEnv(mode, path.resolve(process.cwd(), 'env'))
const {
VITE_APP_PORT,
VITE_DELETE_CONSOLE,
VITE_APP_PUBLIC_BASE,
VITE_APP_PROXY_ENABLE,
} = env
return defineConfig({
envDir: './env', // 自定义env目录
plugins: [
legacy({
targets: ['defaults', 'ie >= 11', 'chrome 52'], // 需要兼容的目标列表,可以设置多个
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
renderLegacyChunks: true,
polyfills: [
'es.symbol',
'es.array.filter',
'es.promise',
'es.promise.finally',
'es/map',
'es/set',
'es.array.for-each',
'es.object.define-properties',
'es.object.define-property',
'es.object.get-own-property-descriptor',
'es.object.get-own-property-descriptors',
'es.object.keys',
'es.object.to-string',
'web.dom-collections.for-each',
'esnext.global-this',
'esnext.string.match-all',
],
}),
UniLayouts(),
UniPlatform(),
// UniXXX 需要在 Uni 之前引入
{
// 临时解决 dcloudio 官方的 @dcloudio/uni-mp-compiler 出现的编译 BUG
// 参考 github issue: https://github.com/dcloudio/uni-app/issues/4952
// 自定义插件禁用 vite:vue 插件的 devToolsEnabled,强制编译 vue 模板时 inline 为 true
name: 'fix-vite-plugin-vue',
configResolved(config) {
const plugin = config.plugins.find(p => p.name === 'vite:vue')
if (plugin && plugin.api && plugin.api.options) {
plugin.api.options.devToolsEnabled = false
}
},
},
AutoImport({
imports: ['vue', 'uni-app'],
dts: 'src/types/auto-import.d.ts',
dirs: ['src/hooks'], // 自动导入 hooks
vueTemplate: true, // default false
}),
// Optimization 插件需要 page.json 文件,故应在 UniPages 插件之后执行
Optimization({
enable: {
'optimization': true,
'async-import': true,
'async-component': true,
},
dts: {
base: 'src/types',
},
logger: false,
}),
// 打包分析插件,h5 + 生产环境才弹出
UNI_PLATFORM === 'h5'
&& mode === 'production'
&& visualizer({
filename: './node_modules/.cache/visualizer/stats.html',
open: true,
gzipSize: true,
brotliSize: true,
}),
// 只有在 app 平台时才启用 copyNativeRes 插件
// UNI_PLATFORM === 'app' && copyNativeRes(),
Components({
extensions: ['vue'],
deep: true, // 是否递归扫描子目录,
directoryAsNamespace: false, // 是否把目录名作为命名空间前缀,true 时组件名为 目录名+组件名,
dts: 'src/types/components.d.ts', // 自动生成的组件类型声明文件路径(用于 TypeScript 支持)
}),
Uni(),
// 自动打开开发者工具插件 (必须修改 .env 文件中的 VITE_WX_APPID)
// openDevTools(),
],
define: {
__UNI_PLATFORM__: JSON.stringify(UNI_PLATFORM),
__VITE_APP_PROXY__: JSON.stringify(VITE_APP_PROXY_ENABLE),
},
css: {
postcss: {
plugins: [
// autoprefixer({
// // 指定目标浏览器
// overrideBrowserslist: ['> 1%', 'last 2 versions'],
// }),
],
},
},
resolve: {
alias: {
'@': path.join(process.cwd(), './src'),
'@img': path.join(process.cwd(), './src/static/images'),
},
},
server: {
host: '0.0.0.0',
hmr: true,
port: Number.parseInt(VITE_APP_PORT, 10),
},
// esbuild: {
// drop: VITE_DELETE_CONSOLE === 'true' ? ['console', 'debugger'] : ['debugger'],
// },
build: {
sourcemap: false,
// 方便非h5端调试
// sourcemap: VITE_SHOW_SOURCEMAP === 'true', // 默认是false
target: 'es6', // legacy 插件会处理 polyfill
minify: mode === 'development' ? false : 'terser', // 使用 terser 保证 ES6 语法降级
terserOptions: {
compress: {
drop_console: VITE_DELETE_CONSOLE === 'true',
drop_debugger: true,
},
},
},
optimizeDeps: {
exclude: ['sard-uniapp'],
},
})
})
@@ -1,3 +0,0 @@
{
"recommendations": ["Vue.volar"]
}
-56
View File
@@ -1,56 +0,0 @@
{
"editor.cursorSmoothCaretAnimation": "on",
// Disable the default formatter, use eslint instead
"prettier.enable": false,
"editor.formatOnSave": false,
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "style/*", "severity": "off", "fixable": true },
{ "rule": "format/*", "severity": "off", "fixable": true },
{ "rule": "*-indent", "severity": "off", "fixable": true },
{ "rule": "*-spacing", "severity": "off", "fixable": true },
{ "rule": "*-spaces", "severity": "off", "fixable": true },
{ "rule": "*-order", "severity": "off", "fixable": true },
{ "rule": "*-dangle", "severity": "off", "fixable": true },
{ "rule": "*-newline", "severity": "off", "fixable": true },
{ "rule": "*quotes", "severity": "off", "fixable": true },
{ "rule": "*semi", "severity": "off", "fixable": true }
],
// Enable eslint for all supported languages
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml",
"toml",
"xml",
"gql",
"graphql",
"astro",
"svelte",
"css",
"less",
"scss",
"pcss",
"postcss"
],
"files.associations": {
"pages.json": "jsonc",
"manifest.json": "jsonc"
}
}
-2
View File
@@ -1,2 +0,0 @@
VITE_APP_PORT = 9000
-9
View File
@@ -1,9 +0,0 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE = false
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false
# 后台请求地址
# VITE_SERVER_BASEURL = 'https://dev.xxx.com'
-7
View File
@@ -1,7 +0,0 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'production'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE = true
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false
-6
View File
@@ -1,6 +0,0 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE = false
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false
@@ -1,21 +0,0 @@
// eslint.config.mjs
import antfu from '@antfu/eslint-config'
export default antfu({
vue: true,
stylistic: {
indent: 2,
quotes: 'single',
},
formatters: {
css: true,
html: true,
markdown: 'prettier',
},
rules: {
'no-console': 'off', // 允许 console.log 不报错
},
})
File diff suppressed because it is too large. Load diff
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,39 +0,0 @@
<script setup lang="ts">
import { onHide, onLaunch, onShow } from '@dcloudio/uni-app'
import { useUserStore } from './store'
const userStore = useUserStore()
onLaunch(() => {
console.log('App Launch')
})
onShow(() => {
userStore.requireLogin()
console.log('App Show')
})
onHide(() => {
console.log('App Hide')
})
</script>
<style>
page {
background-color: #fcfbfe;
}
</style>
<style lang="scss">
swiper,
scroll-view {
flex: 1;
height: 100%;
overflow: hidden;
}
image {
width: 100%;
height: 100%;
vertical-align: middle;
}
</style>
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

Before

Width:  |  Height:  |  Size: 496 B

@@ -1,55 +0,0 @@
<script setup lang="ts">
import PickerSelect from '../picker-select/index.vue'
const props = defineProps({
label: { type: String, default: '' },
value: { type: null as unknown as PropType<any>, default: undefined },
labelField: { type: String, required: true },
valueField: { type: String, required: true },
viewname: { type: String, required: true },
field1: { type: String, required: true },
field2: { type: String, required: true },
placeholder: { type: String, default: '请选择' },
})
const emits = defineEmits<{
(e: 'update:label', val: string): void
(e: 'update:value', val: any): void
}>()
const _visible = ref(false)
const _label = ref(props.label)
// 同步 props.label
watch(() => props.label, (val) => {
_label.value = val
})
// 选中时只处理 label
function handleSelectChange(selectValue: any) {
if (!selectValue)
return
_label.value = selectValue[props.labelField]
emits('update:label', _label.value)
}
</script>
<template>
<sar-popout-input
v-model="_label"
:placeholder="props.placeholder"
@click="_visible = true"
>
<PickerSelect
v-model:visible="_visible"
:value="props.value"
:viewname="props.viewname"
:field1="props.field1"
:field2="props.field2"
:label-field="props.labelField"
:value-field="props.valueField"
@update:value="emits('update:value', $event)"
@change="handleSelectChange"
/>
</sar-popout-input>
</template>
Loaded 100 of 149 files, more files were not shown because too many files have changed in this diff. Show more