u
This commit is contained in:
1 parent
9954a33f89
commit
aa10a8c1f7
80 files changed
+14576
-732
No files matched your search
@@ -1,20 +1,17 @@
|
||||
<!doctype html>
|
||||
<html build-time="BUILD_TIME">
|
||||
<html build-time="%BUILD_TIME%">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
|
||||
|
||||
<script>
|
||||
var coverSupport =
|
||||
'CSS' in window &&
|
||||
typeof CSS.supports === 'function' &&
|
||||
(CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
|
||||
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>VITE_APP_TITLE</title>
|
||||
<title>unibest</title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
"@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": "^7.2.1",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"eslint": "^9.34.0",
|
||||
@@ -117,6 +118,7 @@
|
||||
"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.2.8",
|
||||
|
||||
+433
-470
File diff suppressed because it is too large.
Load diff
@@ -52,16 +52,12 @@ const props = defineProps({
|
||||
})
|
||||
const emit = defineEmits(['update:visible', 'update:value', 'change'])
|
||||
|
||||
const _visible = computed({
|
||||
get: () => props.visible,
|
||||
set: (val: boolean) => {
|
||||
emit('update:visible', val)
|
||||
},
|
||||
})
|
||||
const _visible = ref(props.visible)
|
||||
|
||||
const _loading = ref(true)
|
||||
watch(() => props.visible, val => _visible.value = val)
|
||||
|
||||
const loading = ref(true)
|
||||
const searchValue = ref('')
|
||||
|
||||
const pagination = ref({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
@@ -77,10 +73,9 @@ const isNextDisabled = computed(() =>
|
||||
const _value = computed({
|
||||
get: () => {
|
||||
if (props.type === 'multiple') {
|
||||
// 只在不是数组时才兜底成 []
|
||||
return Array.isArray(props.value) ? props.value : []
|
||||
}
|
||||
return props.value
|
||||
return props.value ?? null
|
||||
},
|
||||
set: (val) => {
|
||||
emit('update:value', val)
|
||||
@@ -89,15 +84,6 @@ const _value = computed({
|
||||
|
||||
const options = ref<any[]>([])
|
||||
|
||||
function setOptions(val: any[]) {
|
||||
options.value = val.map(item => ({
|
||||
label: item[props.labelField] ?? '',
|
||||
value: item[props.valueField] ?? undefined,
|
||||
disabled: !!item.disabled,
|
||||
...item,
|
||||
}))
|
||||
}
|
||||
|
||||
const { allChecked, isIndeterminate, onAllChange } = useIndeterminate(
|
||||
_value,
|
||||
options,
|
||||
@@ -113,7 +99,8 @@ function select(option, toggle) {
|
||||
o => o.value === option.value,
|
||||
)
|
||||
|
||||
// 触发事件或者更新内部 _label
|
||||
_visible.value = false
|
||||
emit('update:visible',false)
|
||||
emit('change', selectedOption)
|
||||
}
|
||||
}
|
||||
@@ -160,7 +147,7 @@ function getData() {
|
||||
}
|
||||
|
||||
function getAutocompleteData() {
|
||||
_loading.value = true
|
||||
loading.value = true
|
||||
|
||||
getAutocompleteDataApi({
|
||||
q: searchValue.value,
|
||||
@@ -172,14 +159,21 @@ function getAutocompleteData() {
|
||||
}).then((res) => {
|
||||
pagination.value.total = res.data.total
|
||||
|
||||
setOptions(res.data.rows)
|
||||
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
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function getAutocompleteDataEx() {
|
||||
_loading.value = true
|
||||
loading.value = true
|
||||
|
||||
getAutocompleteDataExApi({
|
||||
q: searchValue.value,
|
||||
@@ -193,37 +187,35 @@ function getAutocompleteDataEx() {
|
||||
}).then((res) => {
|
||||
pagination.value.total = res.data.total
|
||||
|
||||
setOptions(res.data.rows)
|
||||
options.value = res.data.rows.map(item => ({
|
||||
label: item[props.labelField] ?? '',
|
||||
value: item[props.valueField] ?? undefined,
|
||||
disabled: !!item.disabled,
|
||||
...item,
|
||||
}))
|
||||
|
||||
}).finally(() => {
|
||||
_loading.value = false
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function getAutocompleteDataSingle() {
|
||||
// _loading.value = true
|
||||
// getAutocompleteDataSingleApi({
|
||||
// q: searchValue.value,
|
||||
// page: pagination.value.current,
|
||||
// limit: pagination.value.pageSize,
|
||||
// viewname: props.viewname,
|
||||
// field: props.labelField,
|
||||
// userid: props.userid,
|
||||
// }).then((res) => {
|
||||
// pagination.value.total = res.data.total
|
||||
|
||||
}
|
||||
|
||||
// setOptions(res.data.rows)
|
||||
// }).finally(() => {
|
||||
// _loading.value = false
|
||||
// })
|
||||
function handleCancel(){
|
||||
_visible.value = false
|
||||
emit('update:visible',false)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<sar-popout
|
||||
v-model:visible="_visible"
|
||||
:visible="_visible"
|
||||
:show-footer="false"
|
||||
title="请选择"
|
||||
@after-enter="handleAfterEnter"
|
||||
@enter="handleAfterEnter"
|
||||
@close="handleCancel"
|
||||
>
|
||||
<template v-if="props.type === 'multiple'" #title-prepend>
|
||||
<view class="sar-checkbox-popout__check-all">
|
||||
@@ -307,6 +299,7 @@ function getAutocompleteDataSingle() {
|
||||
>
|
||||
<template #icon>
|
||||
<sar-radio
|
||||
:key="option.value"
|
||||
readonly
|
||||
:disabled="option.disabled"
|
||||
:value="option.value"
|
||||
@@ -334,13 +327,13 @@ function getAutocompleteDataSingle() {
|
||||
</sar-button>
|
||||
</template>
|
||||
<template #next>
|
||||
<sar-button type="default" :disabled="isNextDisabled" size="mini">
|
||||
<sar-button type="default" :disabled="isNextDisabled" size="mini" :loading='loading'>
|
||||
下一页
|
||||
</sar-button>
|
||||
</template>
|
||||
</sar-pagination>
|
||||
|
||||
<sar-button
|
||||
<sar-button
|
||||
v-if="props.type === 'multiple'"
|
||||
:root-style="{ width: '100%' }"
|
||||
>
|
||||
|
||||
@@ -3,6 +3,13 @@ import { ref } from 'vue'
|
||||
|
||||
const label = ref('004')
|
||||
const value = ref('004')
|
||||
|
||||
|
||||
const visible = ref(false)
|
||||
|
||||
function test(){
|
||||
visible.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>后台管理首页</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "PingFang SC","Microsoft YaHei",Arial,sans-serif;
|
||||
background: #f5f5f5;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 轮播 */
|
||||
.carousel {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.carousel img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
/* 功能模块 */
|
||||
.modules {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background: #fff;
|
||||
margin: 0 8px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.module {
|
||||
width: 25%;
|
||||
padding: 14px 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.module img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.module span {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.module:active {
|
||||
background: #e6f0ff;
|
||||
}
|
||||
|
||||
/* 数据统计卡片 */
|
||||
.cards {
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
padding: 12px 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.card {
|
||||
min-width: 120px;
|
||||
background: #fff;
|
||||
margin-right: 12px;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.card h3 {
|
||||
margin: 6px 0 0;
|
||||
font-size: 18px;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.card p {
|
||||
margin: 2px 0 0;
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.cards::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- 轮播图 -->
|
||||
<div class="carousel" id="carousel">
|
||||
<img src="https://via.placeholder.com/400x160?text=公告1" alt="公告1">
|
||||
<img src="https://via.placeholder.com/400x160?text=公告2" alt="公告2" style="display:none;">
|
||||
<img src="https://via.placeholder.com/400x160?text=公告3" alt="公告3" style="display:none;">
|
||||
</div>
|
||||
|
||||
<!-- 功能模块 -->
|
||||
<div class="modules">
|
||||
<div class="module">
|
||||
<img src="https://via.placeholder.com/36" alt="用户管理">
|
||||
<span>用户管理</span>
|
||||
</div>
|
||||
<div class="module">
|
||||
<img src="https://via.placeholder.com/36" alt="订单管理">
|
||||
<span>订单管理</span>
|
||||
</div>
|
||||
<div class="module">
|
||||
<img src="https://via.placeholder.com/36" alt="报表统计">
|
||||
<span>报表统计</span>
|
||||
</div>
|
||||
<div class="module">
|
||||
<img src="https://via.placeholder.com/36" alt="系统设置">
|
||||
<span>系统设置</span>
|
||||
</div>
|
||||
<div class="module">
|
||||
<img src="https://via.placeholder.com/36" alt="权限管理">
|
||||
<span>权限管理</span>
|
||||
</div>
|
||||
<div class="module">
|
||||
<img src="https://via.placeholder.com/36" alt="日志管理">
|
||||
<span>日志管理</span>
|
||||
</div>
|
||||
<div class="module">
|
||||
<img src="https://via.placeholder.com/36" alt="消息通知">
|
||||
<span>消息通知</span>
|
||||
</div>
|
||||
<div class="module">
|
||||
<img src="https://via.placeholder.com/36" alt="数据导入">
|
||||
<span>数据导入</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据统计卡片 -->
|
||||
<div class="cards">
|
||||
<div class="card">
|
||||
<h3>102</h3>
|
||||
<p>今日新增用户</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>56</h3>
|
||||
<p>待处理订单</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>78</h3>
|
||||
<p>本周报表</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>12</h3>
|
||||
<p>系统警告</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 简单轮播
|
||||
const carousel = document.getElementById('carousel');
|
||||
const imgs = carousel.getElementsByTagName('img');
|
||||
let current = 0;
|
||||
setInterval(() => {
|
||||
imgs[current].style.display = 'none';
|
||||
current = (current + 1) % imgs.length;
|
||||
imgs[current].style.display = 'block';
|
||||
}, 3000);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -40,5 +40,5 @@
|
||||
"src/**/*.vue",
|
||||
"src/**/*.json"
|
||||
],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -7,6 +7,7 @@ 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'
|
||||
@@ -15,7 +16,6 @@ import openDevTools from './scripts/open-dev-tools'
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
const { UNI_PLATFORM } = process.env
|
||||
console.log('UNI_PLATFORM -> ', UNI_PLATFORM) // 得到 mp-weixin, h5, app 等
|
||||
|
||||
const env = loadEnv(mode, path.resolve(process.cwd(), 'env'))
|
||||
const {
|
||||
@@ -24,31 +24,41 @@ export default defineConfig(({ command, mode }) => {
|
||||
VITE_APP_PUBLIC_BASE,
|
||||
VITE_APP_PROXY_ENABLE,
|
||||
} = env
|
||||
console.log('环境变量 env -> ', env)
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log('当前是开发模式')
|
||||
}
|
||||
else {
|
||||
console.log('当前是生产/打包模式')
|
||||
}
|
||||
|
||||
return defineConfig({
|
||||
envDir: './env', // 自定义env目录
|
||||
base: VITE_APP_PUBLIC_BASE,
|
||||
plugins: [
|
||||
legacy({
|
||||
targets: ['defaults', 'Chrome >= 56'],
|
||||
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
|
||||
renderLegacyChunks: true,
|
||||
polyfills: [
|
||||
'es.symbol',
|
||||
'es.array.filter',
|
||||
'es.promise',
|
||||
'es.promise.finally',
|
||||
'es.object.assign',
|
||||
'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',
|
||||
'es.array.iterator',
|
||||
'es.string.includes',
|
||||
'es.string.starts-with',
|
||||
'es.object.values',
|
||||
],
|
||||
}),
|
||||
UniLayouts(),
|
||||
UniPlatform(),
|
||||
// Optimization 插件需要 page.json 文件,故应在 UniPages 插件之后执行
|
||||
Optimization({
|
||||
enable: {
|
||||
'optimization': true,
|
||||
'async-import': true,
|
||||
'async-component': true,
|
||||
},
|
||||
dts: {
|
||||
base: 'src/types',
|
||||
},
|
||||
logger: false,
|
||||
}),
|
||||
|
||||
// UniXXX 需要在 Uni 之前引入
|
||||
{
|
||||
// 临时解决 dcloudio 官方的 @dcloudio/uni-mp-compiler 出现的编译 BUG
|
||||
@@ -68,6 +78,18 @@ export default defineConfig(({ command, mode }) => {
|
||||
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'
|
||||
@@ -87,7 +109,7 @@ export default defineConfig(({ command, mode }) => {
|
||||
}),
|
||||
Uni(),
|
||||
// 自动打开开发者工具插件 (必须修改 .env 文件中的 VITE_WX_APPID)
|
||||
openDevTools(),
|
||||
// openDevTools(),
|
||||
],
|
||||
define: {
|
||||
__UNI_PLATFORM__: JSON.stringify(UNI_PLATFORM),
|
||||
@@ -114,16 +136,21 @@ export default defineConfig(({ command, mode }) => {
|
||||
hmr: true,
|
||||
port: Number.parseInt(VITE_APP_PORT, 10),
|
||||
},
|
||||
esbuild: {
|
||||
drop: VITE_DELETE_CONSOLE === 'true' ? ['console', 'debugger'] : ['debugger'],
|
||||
},
|
||||
// esbuild: {
|
||||
// drop: VITE_DELETE_CONSOLE === 'true' ? ['console', 'debugger'] : ['debugger'],
|
||||
// },
|
||||
build: {
|
||||
sourcemap: false,
|
||||
// 方便非h5端调试
|
||||
// sourcemap: VITE_SHOW_SOURCEMAP === 'true', // 默认是false
|
||||
target: 'es6',
|
||||
// 开发环境不用压缩
|
||||
minify: mode === 'development' ? false : 'esbuild',
|
||||
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'],
|
||||
|
||||
Reference in new issue
Block a user