refactor: ♻️ 前端文件组织重构

This commit is contained in:
tk
2025-07-02 17:14:03 +08:00
committed by nsnail
parent e5a0f925a0
commit 257ef9245c
248 changed files with 1185 additions and 1286 deletions

View File

@ -130,7 +130,7 @@
},
// ------------------------------ 系统管理 ------------------------------
{
"Icon": "sc-icon-App",
"Icon": "sc-icon-app",
"Id": 485278637670422,
"Name": "sys",
"Path": "/sys",
@ -151,7 +151,7 @@
},
{
"Component": "sys/job",
"Icon": "sc-icon-ScheduledJob",
"Icon": "sc-icon-scheduled-job",
"Id": 510067557638158,
"Name": "sys/job",
"ParentId": 485278637670422,
@ -206,7 +206,7 @@
},
// ------------------------------ 档案管理 ------------------------------
{
"Icon": "sc-icon-Archive",
"Icon": "sc-icon-archive",
"Id": 616214756757512,
"Name": "archive",
"Path": "/archive",
@ -248,7 +248,7 @@
},
{
"Component": "sys/log/login",
"Icon": "sc-icon-OpenDoor",
"Icon": "sc-icon-open-door",
"Id": 485285246504970,
"Name": "sys/log/login",
"ParentId": 374792687640581,
@ -291,7 +291,7 @@
{
"Id": 560217289232398,
"ParentId": 373838105399301,
"Icon": "sc-icon-FreeSql",
"Icon": "sc-icon-free-sql",
"Name": "dev/freesql",
"Path": "https://freesql.net/guide",
"Sort": 99,

View File

@ -141,8 +141,8 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
indexJsFile, Environment.NewLine + tplExport.Replace("$iconName$", req.IconName).Replace(_REPLACE_TO_EMPTY, string.Empty))
.ConfigureAwait(false);
// 修改iconSelect.js
var iconSelectFile = Path.Combine(_clientProjectPath, "src", "config", "iconSelect.js");
// 修改icon-select.js
var iconSelectFile = Path.Combine(_clientProjectPath, "src", "config", "icon-select.js");
var iconSelectContent = await File.ReadAllTextAsync(iconSelectFile).ConfigureAwait(false);
iconSelectContent = iconSelectContent.Replace("export default", "exportDefault:").Replace("'", "\"");
iconSelectContent = _regex2.Replace(iconSelectContent, "\"$1\":");

View File

@ -1,4 +1,4 @@
# 忽略格式化文件 (根据项目需要自行添加)
node_modules
dist
iconSelect.js
icon-select.js

View File

@ -100,7 +100,7 @@
<noscript>
<strong>We're sorry but NetAdmin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div class="aminui" id="app">
<div class="admin-ui" id="app">
<div class="app-loading">
<div class="app-loading__logo">
<img alt="" src="/src/assets/img/logo.svg" />

View File

@ -28,13 +28,13 @@
"vue-i18n": "11.1.7",
"vue-router": "4.5.1",
"vue3-ace-editor": "2.2.4",
"vue3-json-viewer": "2.4.0",
"vue3-json-viewer": "2.4.1",
"vuedraggable": "4.0.3",
"vuex": "4.1.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "6.0.0",
"prettier": "3.6.1",
"prettier": "3.6.2",
"prettier-plugin-organize-attributes": "1.0.0",
"sass": "1.89.2",
"terser": "5.43.1",

View File

@ -1,14 +1,14 @@
<template>
<el-config-provider :button="config.button" :locale="locale" :size="config.size" :zIndex="config.zIndex">
<router-view v-if="isRouterAlive"></router-view>
<router-view v-if="isRouterAlive" />
<na-version-updater />
</el-config-provider>
</template>
<script>
import colorTool from '@/utils/color'
import naVersionUpdater from '@/components/naVersionUpdater'
import UseTabs from '@/utils/useTabs'
import naVersionUpdater from '@/components/na-version-updater'
import UseTabs from '@/utils/use-tabs'
export default {
name: 'App',
@ -126,7 +126,7 @@ export default {
UseTabs.close()
}
} else if (e.keyCode === 65) {
document.getElementsByClassName('userbar-btn-search')[0]?.dispatchEvent(
document.getElementsByClassName('user-bar-btn-search')[0]?.dispatchEvent(
new MouseEvent('click', {
view: window,
bubbles: true,

View File

@ -1,78 +1,78 @@
export { default as Alert } from './Alert.vue'
export { default as Api } from './Api.vue'
export { default as App } from './App.vue'
export { default as App2 } from './App2.vue'
export { default as BugFill } from './BugFill.vue'
export { default as BugLine } from './BugLine.vue'
export { default as Business } from './Business.vue'
export { default as Code } from './Code.vue'
export { default as Code2 } from './Code2.vue'
export { default as Csharp } from './Csharp.vue'
export { default as Dashboard } from './Dashboard.vue'
export { default as Demo } from './Demo.vue'
export { default as Dept } from './Dept.vue'
export { default as Device } from './Device.vue'
export { default as Dic } from './Dic.vue'
export { default as Docker } from './Docker.vue'
export { default as Download } from './Download.vue'
export { default as Drone } from './Drone.vue'
export { default as Elastic } from './Elastic.vue'
export { default as Error } from './Error.vue'
export { default as ExLog } from './ExLog.vue'
export { default as FileExcel } from './FileExcel.vue'
export { default as FilePpt } from './FilePpt.vue'
export { default as FileWord } from './FileWord.vue'
export { default as Gitea } from './Gitea.vue'
export { default as Grafana } from './Grafana.vue'
export { default as Js } from './Js.vue'
export { default as Kafka } from './Kafka.vue'
export { default as Key } from './Key.vue'
export { default as Kibana } from './Kibana.vue'
export { default as Link } from './Link.vue'
export { default as Log } from './Log.vue'
export { default as LoginLog } from './LoginLog.vue'
export { default as Memory } from './Memory.vue'
export { default as Meter } from './Meter.vue'
export { default as OpenDoor } from './OpenDoor.vue'
export { default as OperLog } from './OperLog.vue'
export { default as Organization } from './Organization.vue'
export { default as Position } from './Position.vue'
export { default as Product } from './Product.vue'
export { default as ProductCategory } from './ProductCategory.vue'
export { default as Resource } from './Resource.vue'
export { default as Robot } from './Robot.vue'
export { default as Role } from './Role.vue'
export { default as ScheduledJob } from './ScheduledJob.vue'
export { default as Send } from './Send.vue'
export { default as Stats } from './Stats.vue'
export { default as Sync } from './Sync.vue'
export { default as Task } from './Task.vue'
export { default as Tpl } from './Tpl.vue'
export { default as Unlink } from './Unlink.vue'
export { default as Upload } from './Upload.vue'
export { default as Vue } from './Vue.vue'
export { default as Warning } from './Warning.vue'
export { default as Wechat } from './Wechat.vue'
export { default as Report } from './Report.vue'
export { default as Daily } from './Daily.vue'
export { default as AccountReport } from './AccountReport.vue'
export { default as Element } from './Element.vue'
export { default as ApiDoc } from './ApiDoc.vue'
export { default as Help } from './Help.vue'
export { default as Version } from './Version.vue'
export { default as Home } from './Home.vue'
export { default as Exception } from './Exception.vue'
export { default as Collect } from './Collect.vue'
export { default as FreeSql } from './FreeSql.vue'
export { default as Performance } from './Performance.vue'
export { default as Proxy } from './Proxy.vue'
export { default as ECharts } from './ECharts.vue'
export { default as Mobile } from './Mobile.vue'
export { default as Email } from './Email.vue'
export { default as SmsCode } from './SmsCode.vue'
export { default as MailCode } from './MailCode.vue'
export { default as Archive } from './Archive.vue'
export { default as DeviceLog } from './DeviceLog.vue'
export { default as NickName } from './NickName.vue'
export { default as Telegram } from './Telegram.vue'
export { default as Country } from './Country.vue'
export { default as alert } from './alert'
export { default as api } from './api'
export { default as app } from './app'
export { default as app2 } from './app2'
export { default as 'bug-fill' } from './bug-fill'
export { default as 'bug-line' } from './bug-line'
export { default as business } from './business'
export { default as code } from './code'
export { default as code2 } from './code2'
export { default as csharp } from './csharp'
export { default as dashboard } from './dashboard'
export { default as demo } from './demo'
export { default as dept } from './dept'
export { default as device } from './device'
export { default as dic } from './dic'
export { default as docker } from './docker'
export { default as download } from './download'
export { default as drone } from './drone'
export { default as elastic } from './elastic'
export { default as error } from './error'
export { default as 'ex-log' } from './ex-log'
export { default as 'file-excel' } from './file-excel'
export { default as 'file-ppt' } from './file-ppt'
export { default as 'file-word' } from './file-word'
export { default as gitea } from './gitea'
export { default as grafana } from './grafana'
export { default as js } from './js'
export { default as kafka } from './kafka'
export { default as key } from './key'
export { default as kibana } from './kibana'
export { default as link } from './link'
export { default as log } from './log'
export { default as 'login-log' } from './login-log'
export { default as memory } from './memory'
export { default as meter } from './meter'
export { default as 'open-door' } from './open-door'
export { default as 'oper-log' } from './oper-log'
export { default as organization } from './organization'
export { default as position } from './position'
export { default as product } from './product'
export { default as 'product-category' } from './product-category'
export { default as resource } from './resource'
export { default as robot } from './robot'
export { default as role } from './role'
export { default as 'scheduled-job' } from './scheduled-job'
export { default as send } from './send'
export { default as stats } from './stats'
export { default as sync } from './sync'
export { default as task } from './task'
export { default as tpl } from './tpl'
export { default as unlink } from './unlink'
export { default as upload } from './upload'
export { default as vue } from './vue'
export { default as warning } from './warning'
export { default as wechat } from './wechat'
export { default as report } from './report'
export { default as daily } from './daily'
export { default as 'account-report' } from './account-report'
export { default as element } from './element'
export { default as 'api-doc' } from './api-doc'
export { default as help } from './help'
export { default as version } from './version'
export { default as home } from './home'
export { default as exception } from './exception'
export { default as collect } from './collect'
export { default as 'free-sql' } from './free-sql'
export { default as performance } from './performance'
export { default as proxy } from './proxy'
export { default as 'echarts' } from './echarts'
export { default as mobile } from './mobile'
export { default as email } from './email'
export { default as 'sms-code' } from './sms-code'
export { default as 'mail-code' } from './mail-code'
export { default as archive } from './archive'
export { default as 'device-log' } from './device-log'
export { default as 'nick-name' } from './nick-name'
export { default as telegram } from './telegram'
export { default as country } from './country'

View File

@ -1,5 +1,5 @@
<template>
<scTableSelect
<sc-table-select
v-model="area"
:params="form"
:props="{ label: 'key', value: 'value' }"
@ -9,19 +9,19 @@
<template #header>
<el-form :model="form">
<el-form-item>
<el-input v-model="form.keywords" :placeholder="$t('请输入地区或代码')" @input="onInput" clearable></el-input>
<el-input v-model="form.keywords" :placeholder="$t('请输入地区或代码')" @input="onInput" clearable />
</el-form-item>
</el-form>
</template>
<el-table-column :label="$t('地区')" prop="key" width="400" />
<el-table-column :label="$t('代码')" prop="value" />
</scTableSelect>
</sc-table-select>
</template>
<style scoped></style>
<style scoped />
<script>
import { defineAsyncComponent } from 'vue'
const scTableSelect = defineAsyncComponent(() => import('@/components/scTableSelect'))
const scTableSelect = defineAsyncComponent(() => import('@/components/sc-table-select'))
export default {
props: {
modelValue: { type: Object },

View File

@ -1,13 +1,7 @@
<template>
<el-button
:disabled="vue.selection.length === 0 || loading"
:loading="loading"
@click="bulkDel"
icon="el-icon-delete"
plain
type="danger"></el-button>
<el-button :disabled="vue.selection.length === 0 || loading" :loading="loading" @click="bulkDel" icon="el-icon-delete" plain type="danger" />
</template>
<style scoped></style>
<style scoped />
<script>
export default {
emits: [],

View File

@ -2,7 +2,7 @@
<el-table-column :label="label" :prop="prop" sortable="custom">
<template #default="{ row }">
<div class="avatar">
<el-avatar :src="getAvatar(row, prop, avatar)" size="small"></el-avatar>
<el-avatar :src="getAvatar(row, prop, avatar)" size="small" />
<el-link v-if="this.click" @click="this.click(row)"> {{ tool.getNestedProperty(row, prop) }}</el-link>
<span v-else> {{ tool.getNestedProperty(row, prop) }}</span>
</div>

View File

@ -3,7 +3,7 @@
<template #default="{ row }">
<p>{{ row.id }}</p>
<p v-if="showTime" class="color-secondary">{{ row.createdTime }}</p>
<slot :data="row"></slot>
<slot :data="row" />
</template>
</el-table-column>
</template>
@ -26,4 +26,4 @@ export default {
methods: {},
}
</script>
<style scoped></style>
<style scoped />

View File

@ -2,12 +2,12 @@
<el-table-column v-bind:="$attrs">
<template #default="{ row }">
<na-indicator :data="row" :options="options" :prop="$attrs.prop" />
<slot :data="row" name="info"></slot>
<slot :data="row" name="info" />
</template>
</el-table-column>
</template>
<script>
import naIndicator from '@/components/naIndicator'
import naIndicator from '@/components/na-indicator'
export default {
emits: [],
props: {

View File

@ -39,7 +39,7 @@
</el-table-column>
</template>
<script>
import naColOperation from '@/config/naColOperation'
import naColOperation from '@/config/na-col-operation'
export default {
emits: [],
@ -83,4 +83,4 @@ export default {
},
}
</script>
<style scoped></style>
<style scoped />

View File

@ -5,7 +5,7 @@
</template>
</el-table-column>
</template>
<style scoped></style>
<style scoped />
<script>
import tool from '@/utils/tool'

View File

@ -5,18 +5,18 @@
:style="{ display: $TOOL.getNestedProperty(row, $attrs.prop) ? 'flex' : 'none' }"
@click="click($TOOL.getNestedProperty(row, $attrs.prop))"
class="el-table-column-avatar">
<el-avatar v-if="$TOOL.getNestedProperty(row, $attrs.nestProp)" :src="getAvatar(row, $attrs.nestProp)" size="small"></el-avatar>
<el-avatar v-if="$TOOL.getNestedProperty(row, $attrs.nestProp)" :src="getAvatar(row, $attrs.nestProp)" size="small" />
<div>
<p>{{ $TOOL.getNestedProperty(row, $attrs.nestProp) }}</p>
<p v-if="$attrs.nestProp2">{{ $TOOL.getNestedProperty(row, $attrs.nestProp2) }}</p>
</div>
</div>
<save-dialog v-if="dialog.save" @closed="dialog.save = false" ref="saveDialog"></save-dialog>
<save-dialog v-if="dialog.save" @closed="dialog.save = false" ref="saveDialog" />
</template>
</el-table-column>
</template>
<script>
import saveDialog from '@/views/sys/user/save.vue'
import saveDialog from '@/views/sys/user/save'
export default {
components: { saveDialog },
@ -49,4 +49,4 @@ export default {
watch: {},
}
</script>
<style scoped></style>
<style scoped />

View File

@ -4,9 +4,9 @@
:options="options"
:placeholder="placeholder"
:props="{ label: 'name', value: 'id', checkStrictly: true, expandTrigger: 'hover', emitPath: false, multiple: multiple }"
clearable></el-cascader>
clearable />
</template>
<style scoped></style>
<style scoped />
<script>
export default {
props: {

View File

@ -17,7 +17,7 @@
clearable
maxlength="4"
oninput="value=value.replace(/\D/g,'')"
prefix-icon="el-icon-message"></el-input>
prefix-icon="el-icon-message" />
<el-button :disabled="sendDisabled" @click="getYzm"
>{{ $t('获取验证码') }}<span v-if="sendDisabled"> ({{ waitSecs }})</span></el-button
>
@ -29,11 +29,11 @@
@success="captchaSuccess"
captchaType="blockPuzzle"
mode="pop"
ref="verify"></na-verify>
ref="verify" />
</template>
<script>
import naVerify from '@/components/naVerifition'
import naVerify from '@/components/na-verifition'
export default {
emits: [],

View File

@ -18,7 +18,7 @@
clearable
maxlength="4"
oninput="value=value.replace(/\D/g,'')"
prefix-icon="el-icon-message"></el-input>
prefix-icon="el-icon-message" />
<el-button :disabled="sendDisabled" @click="getYzm">
{{ $t('获取验证码') }}
<span v-if="sendDisabled"> ({{ waitSecs }})</span></el-button
@ -31,11 +31,11 @@
@success="captchaSuccess"
captchaType="blockPuzzle"
mode="pop"
ref="verify"></na-verify>
ref="verify" />
</template>
<script>
import naVerify from '@/components/naVerifition'
import naVerify from '@/components/na-verifition'
export default {
emits: [],

View File

@ -1,7 +1,7 @@
<template>
<template v-for="(item, i) in options" :key="i">
<div v-if="this.$TOOL.getNestedProperty(data, this.prop)?.toString().toLowerCase() === item.value?.toString().toLowerCase()">
<scStatusIndicator
<sc-status-indicator
:pulse="item.pulse"
:style="
item.type && item.type !== 'none'
@ -10,7 +10,7 @@
"
:type="item.type" />
<span v-if="!$slots.default">&nbsp;{{ item.text }}</span>
<slot :data="data" :text="item.text"></slot>
<slot :data="data" :text="item.text" />
</div>
</template>
</template>

Some files were not shown because too many files have changed in this diff Show More