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, "Id": 485278637670422,
"Name": "sys", "Name": "sys",
"Path": "/sys", "Path": "/sys",
@ -151,7 +151,7 @@
}, },
{ {
"Component": "sys/job", "Component": "sys/job",
"Icon": "sc-icon-ScheduledJob", "Icon": "sc-icon-scheduled-job",
"Id": 510067557638158, "Id": 510067557638158,
"Name": "sys/job", "Name": "sys/job",
"ParentId": 485278637670422, "ParentId": 485278637670422,
@ -206,7 +206,7 @@
}, },
// ------------------------------ 档案管理 ------------------------------ // ------------------------------ 档案管理 ------------------------------
{ {
"Icon": "sc-icon-Archive", "Icon": "sc-icon-archive",
"Id": 616214756757512, "Id": 616214756757512,
"Name": "archive", "Name": "archive",
"Path": "/archive", "Path": "/archive",
@ -248,7 +248,7 @@
}, },
{ {
"Component": "sys/log/login", "Component": "sys/log/login",
"Icon": "sc-icon-OpenDoor", "Icon": "sc-icon-open-door",
"Id": 485285246504970, "Id": 485285246504970,
"Name": "sys/log/login", "Name": "sys/log/login",
"ParentId": 374792687640581, "ParentId": 374792687640581,
@ -291,7 +291,7 @@
{ {
"Id": 560217289232398, "Id": 560217289232398,
"ParentId": 373838105399301, "ParentId": 373838105399301,
"Icon": "sc-icon-FreeSql", "Icon": "sc-icon-free-sql",
"Name": "dev/freesql", "Name": "dev/freesql",
"Path": "https://freesql.net/guide", "Path": "https://freesql.net/guide",
"Sort": 99, "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)) indexJsFile, Environment.NewLine + tplExport.Replace("$iconName$", req.IconName).Replace(_REPLACE_TO_EMPTY, string.Empty))
.ConfigureAwait(false); .ConfigureAwait(false);
// 修改iconSelect.js // 修改icon-select.js
var iconSelectFile = Path.Combine(_clientProjectPath, "src", "config", "iconSelect.js"); var iconSelectFile = Path.Combine(_clientProjectPath, "src", "config", "icon-select.js");
var iconSelectContent = await File.ReadAllTextAsync(iconSelectFile).ConfigureAwait(false); var iconSelectContent = await File.ReadAllTextAsync(iconSelectFile).ConfigureAwait(false);
iconSelectContent = iconSelectContent.Replace("export default", "exportDefault:").Replace("'", "\""); iconSelectContent = iconSelectContent.Replace("export default", "exportDefault:").Replace("'", "\"");
iconSelectContent = _regex2.Replace(iconSelectContent, "\"$1\":"); iconSelectContent = _regex2.Replace(iconSelectContent, "\"$1\":");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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