perf: 精简全局组件

This commit is contained in:
tk 2024-12-19 17:40:50 +08:00 committed by nsnail
parent ce697588f5
commit f3651f1432
50 changed files with 327 additions and 356 deletions

View File

@ -7,7 +7,7 @@
<script> <script>
import colorTool from '@/utils/color' import colorTool from '@/utils/color'
import naVersionUpdater from '@/components/naVersionUpdater/index.vue' import naVersionUpdater from '@/components/naVersionUpdater'
import UseTabs from '@/utils/useTabs' import UseTabs from '@/utils/useTabs'
export default { export default {

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-table-select <scTableSelect
v-model="area" v-model="area"
:params="form" :params="form"
:props="{ label: 'key', value: 'value' }" :props="{ label: 'key', value: 'value' }"
@ -16,10 +16,13 @@
</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" />
</sc-table-select> </scTableSelect>
</template> </template>
<style scoped></style> <style scoped></style>
<script> <script>
import { defineAsyncComponent } from 'vue'
const scTableSelect = defineAsyncComponent(() => import('@/components/scTableSelect'))
export default { export default {
props: { props: {
modelValue: { type: Object }, modelValue: { type: Object },
@ -31,6 +34,9 @@ export default {
dynamicFilter: { dynamicFilter: {
filters: [], filters: [],
logic: 'or', logic: 'or',
field: 'catalogId',
value: this.$GLOBAL.numbers.ID_DIC_CATALOG_GEO_AREA,
operator: 'eq',
}, },
}, },
} }
@ -50,7 +56,9 @@ export default {
}, },
mounted() {}, mounted() {},
created() {}, created() {},
components: {}, components: {
scTableSelect,
},
computed: {}, computed: {},
methods: { methods: {
onInput() { onInput() {

View File

@ -25,10 +25,12 @@ export default {
// //
async bulkDel() { async bulkDel() {
this.loading = true this.loading = true
let load
try { try {
await this.$confirm(this.$t('确定删除选中的 {count} 项吗?', { count: this.vue.selection.length }), this.$t('提示'), { await this.$confirm(this.$t('确定删除选中的 {count} 项吗?', { count: this.vue.selection.length }), this.$t('提示'), {
type: 'warning', type: 'warning',
}) })
load = this.$loading()
const res = await this.api.post({ const res = await this.api.post({
items: this.vue.selection, items: this.vue.selection,
}) })
@ -37,6 +39,7 @@ export default {
} catch { } catch {
// //
} }
load?.close()
this.loading = false this.loading = false
}, },
}, },

View File

@ -7,7 +7,7 @@
</el-table-column> </el-table-column>
</template> </template>
<script> <script>
import naIndicator from '@/components/naIndicator/index.vue' import naIndicator from '@/components/naIndicator'
export default { export default {
emits: [], emits: [],
props: { props: {

View File

@ -10,7 +10,7 @@
width="20rem"> width="20rem">
<template #reference> <template #reference>
<el-button <el-button
v-loading="loading" :disabled="disabled"
:icon="item.icon" :icon="item.icon"
:title="item.title ? $t(item.title) : ''" :title="item.title ? $t(item.title) : ''"
:type="item.type" :type="item.type"
@ -20,7 +20,7 @@
</el-popconfirm> </el-popconfirm>
<el-button <el-button
v-else v-else
v-loading="loading" :disabled="disabled"
:icon="item.icon" :icon="item.icon"
:title="item.title ? $t(item.title) : ''" :title="item.title ? $t(item.title) : ''"
:type="item.type" :type="item.type"
@ -47,7 +47,7 @@ export default {
}, },
data() { data() {
return { return {
loading: false, disabled: false,
} }
}, },
mounted() {}, mounted() {},
@ -56,9 +56,9 @@ export default {
computed: {}, computed: {},
methods: { methods: {
async click(item, row, vue) { async click(item, row, vue) {
this.loading = true this.disabled = true
await item.click(row, vue) await item.click(row, vue)
this.loading = false this.disabled = false
}, },
}, },
} }

View File

@ -33,7 +33,7 @@
</template> </template>
<script> <script>
import naVerify from '@/components/naVerifition/index.vue' import naVerify from '@/components/naVerifition'
export default { export default {
emits: [], emits: [],

View File

@ -35,7 +35,7 @@
</template> </template>
<script> <script>
import naVerify from '@/components/naVerifition/index.vue' import naVerify from '@/components/naVerifition'
export default { export default {
emits: [], emits: [],

View File

@ -36,7 +36,7 @@
</el-select> </el-select>
</template> </template>
</el-input> </el-input>
<sc-select <scSelect
v-else-if="item.type === 'remote-select' && (!item.condition || item.condition())" v-else-if="item.type === 'remote-select' && (!item.condition || item.condition())"
v-model="form[item.field[0]][item.field[1]]" v-model="form[item.field[0]][item.field[1]]"
v-role="item.role || '*/*/*'" v-role="item.role || '*/*/*'"
@ -71,7 +71,7 @@
:style="item.style" :style="item.style"
clearable clearable
filterable /> filterable />
<na-user-select <naUserSelect
v-else-if="item.type === 'user-select' && (!item.condition || item.condition())" v-else-if="item.type === 'user-select' && (!item.condition || item.condition())"
v-model="form[item.field[0]][item.field[1]]" v-model="form[item.field[0]][item.field[1]]"
v-role="item.role || '*/*/*'" v-role="item.role || '*/*/*'"
@ -89,7 +89,7 @@
<template #reference> <template #reference>
<el-button @click="reset" icon="el-icon-refresh-left">{{ $t('重置') }}</el-button> <el-button @click="reset" icon="el-icon-refresh-left">{{ $t('重置') }}</el-button>
</template> </template>
<v-ace-editor <VAceEditor
v-model:value="aceEditorValue" v-model:value="aceEditorValue"
:theme="$TOOL.data.get('APP_SET_DARK') || $CONFIG.APP_SET_DARK ? 'github_dark' : 'github'" :theme="$TOOL.data.get('APP_SET_DARK') || $CONFIG.APP_SET_DARK ? 'github_dark' : 'github'"
lang="json" lang="json"
@ -148,7 +148,14 @@
import tool from '@/utils/tool' import tool from '@/utils/tool'
import vkbeautify from 'vkbeautify/index' import vkbeautify from 'vkbeautify/index'
import { defineAsyncComponent } from 'vue'
const naUserSelect = defineAsyncComponent(() => import('@/components/naUserSelect'))
const scSelect = defineAsyncComponent(() => import('@/components/scSelect'))
export default { export default {
components: {
naUserSelect,
scSelect,
},
emits: ['search', 'reset', 'reSearch'], emits: ['search', 'reset', 'reSearch'],
props: { props: {
dateField: { type: String, default: 'createdTime' }, dateField: { type: String, default: 'createdTime' },

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-table-select <scTableSelect
v-model="user" v-model="user"
:params="form" :params="form"
:props="{ label: 'userName', value: 'id' }" :props="{ label: 'userName', value: 'id' }"
@ -21,10 +21,13 @@
<el-table-column :label="$t('用户编号')" prop="id" /> <el-table-column :label="$t('用户编号')" prop="id" />
<el-table-column :label="$t('用户名')" prop="userName" /> <el-table-column :label="$t('用户名')" prop="userName" />
<el-table-column :label="$t('手机号')" prop="mobile" /> <el-table-column :label="$t('手机号')" prop="mobile" />
</sc-table-select> </scTableSelect>
</template> </template>
<style scoped></style> <style scoped></style>
<script> <script>
import { defineAsyncComponent } from 'vue'
const scTableSelect = defineAsyncComponent(() => import('@/components/scTableSelect'))
export default { export default {
props: { props: {
modelValue: { type: Object }, modelValue: { type: Object },
@ -52,7 +55,9 @@ export default {
}, },
mounted() {}, mounted() {},
created() {}, created() {},
components: {}, components: {
scTableSelect,
},
computed: {}, computed: {},
methods: { methods: {
onInput() { onInput() {

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="$t('高级筛选')" destroy-on-close> <scDialog v-model="visible" :title="$t('高级筛选')" destroy-on-close>
<el-form :model="form" :rules="rules" label-width="10rem" ref="form"> <el-form :model="form" :rules="rules" label-width="10rem" ref="form">
<el-form-item :label="$t('字段名')" prop="field"> <el-form-item :label="$t('字段名')" prop="field">
<el-input v-model="form.field" :placeholder="$t('字段名')" clearable /> <el-input v-model="form.field" :placeholder="$t('字段名')" clearable />
@ -16,7 +16,7 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button @click="submit" type="primary">{{ $t('确定') }}</el-button> <el-button @click="submit" type="primary">{{ $t('确定') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>
export default { export default {

View File

@ -217,7 +217,7 @@
import config from '@/config/table' import config from '@/config/table'
import columnSetting from './columnSetting' import columnSetting from './columnSetting'
import scContextmenuItem from '@/components/scContextmenu/item.vue' import scContextmenuItem from '@/components/scContextmenu/item.vue'
import scContextmenu from '@/components/scContextmenu/index.vue' import scContextmenu from '@/components/scContextmenu'
import fieldFilter from './fieldFilter.vue' import fieldFilter from './fieldFilter.vue'
import { h } from 'vue' import { h } from 'vue'
import tool from '@/utils/tool' import tool from '@/utils/tool'

View File

@ -15,4 +15,23 @@ export default {
}, },
}, },
], ],
delButton(title, api, idField = 'id', idProc = (id) => id) {
return {
icon: 'el-icon-delete',
type: 'danger',
confirm: true,
title: title,
click: async (row, vue) => {
let loading = vue.$loading()
try {
const res = await api.post({
id: idProc(row[idField]),
})
vue.$message.success(vue.$t('删除 {count} 项', { count: res.data }))
vue.$refs.table.refresh()
} catch {}
loading?.close()
},
}
},
} }

View File

@ -26,38 +26,19 @@ import 'ace-builds/src-noconflict/theme-github_dark' // Load the theme definitio
import { VAceEditor } from 'vue3-ace-editor' import { VAceEditor } from 'vue3-ace-editor'
// sc组件 // sc组件
import scCron from '@/components/scCron/index.vue'
import scDialog from '@/components/scDialog' import scDialog from '@/components/scDialog'
import scFormTable from '@/components/scFormTable'
import scPageHeader from '@/components/scPageHeader'
import scSelect from '@/components/scSelect'
import scSelectFilter from '@/components/scSelectFilter' import scSelectFilter from '@/components/scSelectFilter'
import scStatistic from '@/components/scStatistic/index.vue' import scStatistic from '@/components/scStatistic'
import scStatusIndicator from '@/components/scMini/scStatusIndicator' import scStatusIndicator from '@/components/scMini/scStatusIndicator'
import scTable from '@/components/scTable' import scTable from '@/components/scTable'
import scTableColumn from '@/components/scTable/column.js'
import scTableSelect from '@/components/scTableSelect'
import scTrend from '@/components/scMini/scTrend'
import scUpload from '@/components/scUpload'
import scUploadFile from '@/components/scUpload/file'
import scUploadMultiple from '@/components/scUpload/multiple'
import scWaterMark from '@/components/scWaterMark'
// net-admin组件 // net-admin组件
import naArea from '@/components/naArea/index.vue' import naButtonBulkDel from '@/components/naButtonBulkDel'
import naButtonBulkDel from '@/components/naButtonBulkDel/index.vue' import naColId from '@/components/naColId'
import naColAvatar from '@/components/naColAvatar' import naColIndicator from '@/components/naColIndicator'
import naColId from '@/components/naColId/index.vue'
import naColIndicator from '@/components/naColIndicator/index.vue'
import naColOperation from '@/components/naColOperation' import naColOperation from '@/components/naColOperation'
import naColTag from '@/components/naColTag/index.vue' import naColUser from '@/components/naColUser'
import naColTags from '@/components/naColTags/index.vue'
import naColTime from '@/components/naColTime/index.vue'
import naColUser from '@/components/naColUser/index.vue'
import naDept from '@/components/naDept/index.vue'
import naFormEmail from '@/components/naFormEmail/index.vue'
import naSearch from '@/components/naSearch' import naSearch from '@/components/naSearch'
import naUserSelect from '@/components/naUserSelect/index.vue'
export default { export default {
install(app) { install(app) {
@ -86,38 +67,19 @@ export default {
app.component('VAceEditor', VAceEditor) app.component('VAceEditor', VAceEditor)
// net-admin组件 // net-admin组件
app.component('naArea', naArea)
app.component('naButtonBulkDel', naButtonBulkDel) app.component('naButtonBulkDel', naButtonBulkDel)
app.component('naColAvatar', naColAvatar)
app.component('naColId', naColId) app.component('naColId', naColId)
app.component('naColIndicator', naColIndicator) app.component('naColIndicator', naColIndicator)
app.component('naColOperation', naColOperation) app.component('naColOperation', naColOperation)
app.component('naColTag', naColTag)
app.component('naColTags', naColTags)
app.component('naColTime', naColTime)
app.component('naColUser', naColUser) app.component('naColUser', naColUser)
app.component('naDept', naDept)
app.component('naFormEmail', naFormEmail)
app.component('naSearch', naSearch) app.component('naSearch', naSearch)
app.component('naUserSelect', naUserSelect)
// sc组件 // sc组件
app.component('scCron', scCron)
app.component('scDialog', scDialog) app.component('scDialog', scDialog)
app.component('scFormTable', scFormTable)
app.component('scPageHeader', scPageHeader)
app.component('scSelect', scSelect)
app.component('scSelectFilter', scSelectFilter) app.component('scSelectFilter', scSelectFilter)
app.component('scStatistic', scStatistic) app.component('scStatistic', scStatistic)
app.component('scStatusIndicator', scStatusIndicator) app.component('scStatusIndicator', scStatusIndicator)
app.component('scTable', scTable) app.component('scTable', scTable)
app.component('scTableColumn', scTableColumn)
app.component('scTableSelect', scTableSelect)
app.component('scTrend', scTrend)
app.component('scUpload', scUpload)
app.component('scUploadFile', scUploadFile)
app.component('scUploadMultiple', scUploadMultiple)
app.component('scWaterMark', scWaterMark)
//注册全局指令 //注册全局指令
app.directive('auth', auth) app.directive('auth', auth)

View File

@ -24,21 +24,21 @@ const routes = [
}, },
{ {
path: '/profile/message', path: '/profile/message',
component: () => import(/* webpackChunkName: "userRegister" */ '@/views/profile/message/index.vue'), component: () => import(/* webpackChunkName: "userRegister" */ '@/views/profile/message'),
meta: { meta: {
title: '消息中心', title: '消息中心',
}, },
}, },
{ {
path: '/profile/account', path: '/profile/account',
component: () => import(/* webpackChunkName: "userRegister" */ '@/views/profile/account/index.vue'), component: () => import(/* webpackChunkName: "userRegister" */ '@/views/profile/account'),
meta: { meta: {
title: '基本资料', title: '基本资料',
}, },
}, },
{ {
path: '/profile/token', path: '/profile/token',
component: () => import(/* webpackChunkName: "userRegister" */ '@/views/profile/token/index.vue'), component: () => import(/* webpackChunkName: "userRegister" */ '@/views/profile/token'),
meta: { meta: {
title: '授权信息', title: '授权信息',
}, },

View File

@ -630,3 +630,9 @@ textarea {
height: auto; height: auto;
padding: 0 1rem; padding: 0 1rem;
} }
.children-nopadding {
* {
padding: 0 !important;
}
}

View File

@ -17,7 +17,7 @@
</el-form> </el-form>
</template> </template>
<script> <script>
import naFormPhone from '@/components/naFormPhone/index.vue' import naFormPhone from '@/components/naFormPhone'
import phoneConfig from '@/config/naFormPhone' import phoneConfig from '@/config/naFormPhone'
export default { export default {

View File

@ -75,7 +75,7 @@
<script> <script>
import commonPage from './components/commonPage' import commonPage from './components/commonPage'
import naFormPassword from '@/config/naFormPassword' import naFormPassword from '@/config/naFormPassword'
import naFormPhone from '@/components/naFormPhone/index.vue' import naFormPhone from '@/components/naFormPhone'
import phoneConfig from '@/config/naFormPhone' import phoneConfig from '@/config/naFormPhone'
import scPasswordStrength from '@/components/scPasswordStrength' import scPasswordStrength from '@/components/scPasswordStrength'

View File

@ -37,9 +37,9 @@
<script> <script>
import commonPage from './components/commonPage' import commonPage from './components/commonPage'
import naFormPassword from '@/config/naFormPassword' import naFormPassword from '@/config/naFormPassword'
import naFormPhone from '@/components/naFormPhone/index.vue' import naFormPhone from '@/components/naFormPhone'
import phoneConfig from '@/config/naFormPhone' import phoneConfig from '@/config/naFormPhone'
import scPasswordStrength from '@/components/scPasswordStrength/index.vue' import scPasswordStrength from '@/components/scPasswordStrength'
export default { export default {
components: { components: {

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${title}`" @closed="$emit('closed')" destroy-on-close> <scDialog v-model="visible" :title="`${title}`" @closed="$emit('closed')" destroy-on-close>
<el-form :model="form" ref="form"> <el-form :model="form" ref="form">
<el-form-item <el-form-item
v-for="(row, index) in form.rows" v-for="(row, index) in form.rows"
@ -24,7 +24,7 @@
<el-button @click="this.form.rows.push({ value: '' })">{{ $t('添加一行') }}</el-button> <el-button @click="this.form.rows.push({ value: '' })">{{ $t('添加一行') }}</el-button>
<el-button @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>

View File

@ -2,7 +2,7 @@
<el-card :header="$t('基本资料')" shadow="never"> <el-card :header="$t('基本资料')" shadow="never">
<el-form :model="form" label-width="15rem" ref="form"> <el-form :model="form" label-width="15rem" ref="form">
<el-form-item :label="$t('头像')"> <el-form-item :label="$t('头像')">
<sc-upload v-model="form.avatar" :onSuccess="updateUser" :title="$t('上传头像')"></sc-upload> <scUpload v-model="form.avatar" :onSuccess="updateUser" :title="$t('上传头像')"></scUpload>
</el-form-item> </el-form-item>
<el-form-item :label="$t('用户编号')"> <el-form-item :label="$t('用户编号')">
<el-input v-model="form.id" readonly></el-input> <el-input v-model="form.id" readonly></el-input>
@ -58,9 +58,10 @@ import { defineAsyncComponent } from 'vue'
const setMobileDialog = defineAsyncComponent(() => import('@/views/profile/account/set-mobile.vue')) const setMobileDialog = defineAsyncComponent(() => import('@/views/profile/account/set-mobile.vue'))
const setPasswordDialog = defineAsyncComponent(() => import('@/views/profile/account/set-password.vue')) const setPasswordDialog = defineAsyncComponent(() => import('@/views/profile/account/set-password.vue'))
const setEmailDialog = defineAsyncComponent(() => import('@/views/profile/account/set-email.vue')) const setEmailDialog = defineAsyncComponent(() => import('@/views/profile/account/set-email.vue'))
const scUpload = defineAsyncComponent(() => import('@/components/scUpload'))
export default { export default {
components: { setMobileDialog, setPasswordDialog, setEmailDialog }, components: { setMobileDialog, setPasswordDialog, setEmailDialog, scUpload },
created() { created() {
this.form = this.$GLOBAL.user this.form = this.$GLOBAL.user
}, },

View File

@ -14,7 +14,7 @@
form-name="form" /> form-name="form" />
</el-col> </el-col>
<el-col :lg="10"> <el-col :lg="10">
<na-form-email <naFormEmail
v-model="form" v-model="form"
:code-label="$t('邮箱验证码')" :code-label="$t('邮箱验证码')"
:email-label="$t('邮箱地址')" :email-label="$t('邮箱地址')"
@ -35,13 +35,15 @@
</template> </template>
<script> <script>
import naFormPhone from '@/components/naFormPhone/index.vue' import naFormPhone from '@/components/naFormPhone'
import phoneConfig from '@/config/naFormPhone' import phoneConfig from '@/config/naFormPhone'
import emailConfig from '@/config/naFormEmail' import emailConfig from '@/config/naFormEmail'
import { defineAsyncComponent } from 'vue'
const naFormEmail = defineAsyncComponent(() => import('@/components/naFormEmail'))
export default { export default {
components: { components: {
naFormPhone, naFormPhone,
naFormEmail,
}, },
created() {}, created() {},

View File

@ -40,7 +40,7 @@
</template> </template>
<script> <script>
import naFormPhone from '@/components/naFormPhone/index.vue' import naFormPhone from '@/components/naFormPhone'
import phoneConfig from '@/config/naFormPhone' import phoneConfig from '@/config/naFormPhone'
export default { export default {

View File

@ -41,7 +41,7 @@
</template> </template>
<script> <script>
import scPasswordStrength from '@/components/scPasswordStrength/index.vue' import scPasswordStrength from '@/components/scPasswordStrength'
import naFormPassword from '@/config/naFormPassword' import naFormPassword from '@/config/naFormPassword'
export default { export default {

View File

@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import LoginLog from '@/views/sys/log/login/index.vue' import LoginLog from '@/views/sys/log/login'
export default { export default {
components: { LoginLog }, components: { LoginLog },

View File

@ -19,7 +19,7 @@
stripe> stripe>
<el-table-column :label="$t('接口路径')" min-width="400" prop="id" /> <el-table-column :label="$t('接口路径')" min-width="400" prop="id" />
<el-table-column :label="$t('接口名称')" min-width="200" prop="name" /> <el-table-column :label="$t('接口名称')" min-width="200" prop="name" />
<na-col-indicator <naColIndicator
:label="$t('请求方式')" :label="$t('请求方式')"
:options=" :options="
Object.entries(this.$GLOBAL.enums.httpMethods).map((x) => { Object.entries(this.$GLOBAL.enums.httpMethods).map((x) => {

View File

@ -83,7 +83,7 @@
<el-table-column :label="$t('键名')" min-width="400" prop="key" /> <el-table-column :label="$t('键名')" min-width="400" prop="key" />
<el-table-column :label="$t('数据类型')" align="center" prop="type" width="100" /> <el-table-column :label="$t('数据类型')" align="center" prop="type" width="100" />
<el-table-column :label="$t('过期时间')" align="right" prop="expireTime" width="200" /> <el-table-column :label="$t('过期时间')" align="right" prop="expireTime" width="200" />
<na-col-operation <naColOperation
:buttons="[ :buttons="[
{ {
icon: 'el-icon-view', icon: 'el-icon-view',
@ -108,7 +108,7 @@
</template> </template>
<script> <script>
import naInfo from '@/components/naInfo/index.vue' import naInfo from '@/components/naInfo'
export default { export default {
components: { components: {

View File

@ -40,7 +40,7 @@
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button> <el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button>
<na-button-bulk-del :api="$API.sys_config.bulkDelete" :vue="this" /> <naButtonBulkDel :api="$API.sys_config.bulkDelete" :vue="this" />
<el-dropdown v-show="this.selection.length > 0"> <el-dropdown v-show="this.selection.length > 0">
<el-button type="primary"> <el-button type="primary">
{{ $t('批量操作') }} {{ $t('批量操作') }}
@ -74,7 +74,7 @@
row-key="id" row-key="id"
stripe> stripe>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<na-col-id :label="$t('配置编号')" min-width="170" prop="id" /> <naColId :label="$t('配置编号')" min-width="170" prop="id" />
<el-table-column :label="$t('用户注册')" align="center"> <el-table-column :label="$t('用户注册')" align="center">
<el-table-column :label="$t('默认部门')" align="center" prop="userRegisterDept.name" width="150" /> <el-table-column :label="$t('默认部门')" align="center" prop="userRegisterDept.name" width="150" />
<el-table-column :label="$t('默认角色')" align="center" prop="userRegisterRole.name" width="150" /> <el-table-column :label="$t('默认角色')" align="center" prop="userRegisterRole.name" width="150" />
@ -89,16 +89,8 @@
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch> <el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<na-col-operation <naColOperation
:buttons=" :buttons="naColOperation.buttons.concat(naColOperation.delButton('删除部门', $API.sys_config.delete))"
naColOperation.buttons.concat({
icon: 'el-icon-delete',
confirm: true,
title: '删除部门',
click: this.rowDel,
type: 'danger',
})
"
:vue="this" :vue="this"
width="150" /> width="150" />
</sc-table> </sc-table>
@ -212,15 +204,6 @@ export default {
}) })
this.$refs.search.search() this.$refs.search.search()
}, },
async rowDel(row) {
try {
const res = await this.$API.sys_config.delete.post({ id: row.id })
this.$message.success(this.$t('删除 {count} 项', { count: res.data }))
} catch {
//
}
this.$refs.table.refresh()
},
// //
onReset() { onReset() {
Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = [''])) Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close>
<div v-loading="loading"> <div v-loading="loading">
<el-tabs v-if="!loading" tab-position="top"> <el-tabs v-if="!loading" tab-position="top">
<el-tab-pane :label="$t('基本信息')"> <el-tab-pane :label="$t('基本信息')">
@ -8,7 +8,7 @@
<el-collapse-item :title="$t('用户注册设置')" name="1"> <el-collapse-item :title="$t('用户注册设置')" name="1">
<div style="margin: 1rem"> <div style="margin: 1rem">
<el-form-item :label="$t('默认角色')" prop="userRegisterRoleId"> <el-form-item :label="$t('默认角色')" prop="userRegisterRoleId">
<sc-select <scSelect
v-model="form.userRegisterRoleId" v-model="form.userRegisterRoleId"
:config="{ props: { label: 'name', value: 'id' } }" :config="{ props: { label: 'name', value: 'id' } }"
:export-api="$API.sys_role.export" :export-api="$API.sys_role.export"
@ -18,7 +18,7 @@
style="width: 15rem" /> style="width: 15rem" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('默认部门')" prop="userRegisterDeptId"> <el-form-item :label="$t('默认部门')" prop="userRegisterDeptId">
<na-dept v-model="form.userRegisterDeptId" style="width: 15rem"></na-dept> <naDept v-model="form.userRegisterDeptId" style="width: 15rem"></naDept>
</el-form-item> </el-form-item>
<el-form-item :label="$t('开启人工审核')" prop="userRegisterConfirm"> <el-form-item :label="$t('开启人工审核')" prop="userRegisterConfirm">
<el-switch v-model="form.userRegisterConfirm"></el-switch> <el-switch v-model="form.userRegisterConfirm"></el-switch>
@ -33,13 +33,13 @@
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -47,12 +47,15 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>
import { defineAsyncComponent } from 'vue'
const naDept = defineAsyncComponent(() => import('@/components/naDept'))
const scSelect = defineAsyncComponent(() => import('@/components/scSelect'))
export default { export default {
components: {}, components: { naDept, scSelect },
data() { data() {
return { return {
// //

View File

@ -47,7 +47,7 @@
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button> <el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button>
<na-button-bulk-del :api="$API.sys_dept.bulkDelete" :vue="this" /> <naButtonBulkDel :api="$API.sys_dept.bulkDelete" :vue="this" />
<el-dropdown v-show="this.selection.length > 0"> <el-dropdown v-show="this.selection.length > 0">
<el-button type="primary"> <el-button type="primary">
{{ $t('批量操作') }} {{ $t('批量操作') }}
@ -87,7 +87,7 @@
stripe> stripe>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<el-table-column :label="$t('部门名称')" min-width="150" prop="name" sortable="custom" /> <el-table-column :label="$t('部门名称')" min-width="150" prop="name" sortable="custom" />
<na-col-id :label="$t('部门编号')" prop="id" sortable="custom" width="170" /> <naColId :label="$t('部门编号')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('用户数量')" align="right" width="100"> <el-table-column :label="$t('用户数量')" align="right" width="100">
<template #default="{ row }"> <template #default="{ row }">
<el-link @click.native="dialog.save = { mode: 'view', row, tabId: 'user' }" <el-link @click.native="dialog.save = { mode: 'view', row, tabId: 'user' }"
@ -102,16 +102,8 @@
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch> <el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<na-col-operation <naColOperation
:buttons=" :buttons="naColOperation.buttons.concat(naColOperation.delButton('删除部门', $API.sys_dept.delete))"
naColOperation.buttons.concat({
icon: 'el-icon-delete',
confirm: true,
title: '删除部门',
click: this.rowDel,
type: 'danger',
})
"
:vue="this" :vue="this"
width="120" /> width="120" />
</sc-table> </sc-table>
@ -229,15 +221,6 @@ export default {
}) })
this.$refs.search.search() this.$refs.search.search()
}, },
async rowDel(row) {
try {
const res = await this.$API.sys_dept.delete.post({ id: row.id })
this.$message.success(this.$t('删除 {count} 项', { count: res.data }))
} catch {
//
}
this.$refs.table.refresh()
},
// //
onReset() { onReset() {
Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = [''])) Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen>
<div v-loading="loading"> <div v-loading="loading">
<el-tabs v-model="tabId" tab-position="top"> <el-tabs v-model="tabId" tab-position="top">
<el-tab-pane :label="$t('基本信息')"> <el-tab-pane :label="$t('基本信息')">
@ -31,13 +31,13 @@
<user v-if="tabId === 'user'" :dept-id="form.id"></user> <user v-if="tabId === 'user'" :dept-id="form.id"></user>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -45,13 +45,13 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
const User = defineAsyncComponent(() => import('@/views/sys/user/index.vue')) const User = defineAsyncComponent(() => import('@/views/sys/user'))
export default { export default {
components: { User }, components: { User },
data() { data() {

View File

@ -50,7 +50,7 @@
@click="this.dialog.save = { mode: 'add', data: { catalogId: this.catalogId } }" @click="this.dialog.save = { mode: 'add', data: { catalogId: this.catalogId } }"
icon="el-icon-plus" icon="el-icon-plus"
type="primary"></el-button> type="primary"></el-button>
<na-button-bulk-del :api="$API.sys_dic.bulkDeleteContent" :vue="this" /> <naButtonBulkDel :api="$API.sys_dic.bulkDeleteContent" :vue="this" />
<el-dropdown v-show="this.selection.length > 0"> <el-dropdown v-show="this.selection.length > 0">
<el-button type="primary"> <el-button type="primary">
{{ $t('批量操作') }} {{ $t('批量操作') }}
@ -90,7 +90,7 @@
row-key="id" row-key="id"
stripe> stripe>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<na-col-id :label="$t('唯一编码')" prop="id" sortable="custom" width="170" /> <naColId :label="$t('唯一编码')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('项名')" min-width="150" prop="key" sortable="custom" /> <el-table-column :label="$t('项名')" min-width="150" prop="key" sortable="custom" />
<el-table-column :label="$t('项值')" min-width="150" prop="value" sortable="custom" /> <el-table-column :label="$t('项值')" min-width="150" prop="value" sortable="custom" />
<el-table-column :label="$t('备注')" min-width="150" prop="summary" sortable="custom" /> <el-table-column :label="$t('备注')" min-width="150" prop="summary" sortable="custom" />
@ -99,16 +99,8 @@
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch> <el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<na-col-operation <naColOperation
:buttons=" :buttons="naColOperation.buttons.concat(naColOperation.delButton('删除字典项', $API.sys_dic.deleteContent))"
naColOperation.buttons.concat({
icon: 'el-icon-delete',
confirm: true,
title: '删除字典项',
click: this.rowDel,
type: 'danger',
})
"
:vue="this" :vue="this"
width="120" /> width="120" />
</sc-table> </sc-table>
@ -261,17 +253,6 @@ export default {
await this.$refs.table.upData() await this.$refs.table.upData()
}, },
//
async rowDel(row) {
try {
const res = await this.$API.sys_dic.deleteContent.post({ id: row.id })
this.$message.success(this.$t('删除 {count} 项', { count: res.data }))
} catch {
//
}
this.$refs.table.refresh()
},
}, },
mounted() { mounted() {
if (this.keywords) { if (this.keywords) {

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close>
<div v-loading="loading"> <div v-loading="loading">
<el-tabs tab-position="top"> <el-tabs tab-position="top">
<el-tab-pane :label="$t('基本信息')"> <el-tab-pane :label="$t('基本信息')">
@ -19,13 +19,13 @@
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -33,7 +33,7 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="$t('批量修改')" @closed="$emit('closed')" destroy-on-close> <scDialog v-model="visible" :title="$t('批量修改')" @closed="$emit('closed')" destroy-on-close>
<div v-loading="loading"> <div v-loading="loading">
<el-tabs tab-position="top"> <el-tabs tab-position="top">
<el-tab-pane :label="$t('基本信息')"> <el-tab-pane :label="$t('基本信息')">
@ -10,13 +10,13 @@
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -24,7 +24,7 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close>
<el-form v-loading="loading" :model="form" :rules="rules" label-width="10rem" ref="dialogForm"> <el-form v-loading="loading" :model="form" :rules="rules" label-width="10rem" ref="dialogForm">
<el-form-item :label="$t('字典目录名称')" prop="name"> <el-form-item :label="$t('字典目录名称')" prop="name">
<el-input v-model="form.name" :placeholder="$t('字典目录名称')" clearable></el-input> <el-input v-model="form.name" :placeholder="$t('字典目录名称')" clearable></el-input>
@ -15,7 +15,7 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>

View File

@ -64,7 +64,7 @@
@click="this.dialog.save = { mode: 'add', data: { catalogId: this.catalogId } }" @click="this.dialog.save = { mode: 'add', data: { catalogId: this.catalogId } }"
icon="el-icon-plus" icon="el-icon-plus"
type="primary"></el-button> type="primary"></el-button>
<na-button-bulk-del :api="$API.sys_doc.bulkDeleteContent" :vue="this" /> <naButtonBulkDel :api="$API.sys_doc.bulkDeleteContent" :vue="this" />
<el-dropdown v-show="this.selection.length > 0"> <el-dropdown v-show="this.selection.length > 0">
<el-button type="primary"> <el-button type="primary">
{{ $t('批量操作') }} {{ $t('批量操作') }}
@ -101,9 +101,9 @@
row-key="id" row-key="id"
stripe> stripe>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<na-col-id :label="$t('唯一编码')" prop="id" sortable="custom" width="170" /> <naColId :label="$t('唯一编码')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('文档标题')" min-width="200" prop="title" sortable="custom" /> <el-table-column :label="$t('文档标题')" min-width="200" prop="title" sortable="custom" />
<na-col-indicator <naColIndicator
:label="$t('档案可见性')" :label="$t('档案可见性')"
:options=" :options="
Object.entries(this.$GLOBAL.enums.archiveVisibilities).map((x) => { Object.entries(this.$GLOBAL.enums.archiveVisibilities).map((x) => {
@ -119,7 +119,7 @@
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch> <el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<na-col-operation <naColOperation
:buttons="[ :buttons="[
{ {
icon: 'el-icon-view', icon: 'el-icon-view',
@ -138,13 +138,7 @@
click: share, click: share,
title: '分享文档', title: '分享文档',
}, },
{ naColOperation.delButton('删除文档', $API.sys_doc.deleteContent),
icon: 'el-icon-delete',
confirm: true,
title: '删除文档',
click: this.rowDel,
type: 'danger',
},
]" ]"
:vue="this" :vue="this"
width="180" /> width="180" />
@ -303,16 +297,6 @@ export default {
} }
document.body.removeChild(textarea) document.body.removeChild(textarea)
}, },
//
async rowDel(row) {
try {
const res = await this.$API.sys_doc.deleteContent.post({ id: row.id })
this.$message.success(this.$t('删除 {count} 项', { count: res.data }))
} catch {
//
}
this.$refs.table.refresh()
},
}, },
mounted() { mounted() {
if (this.keywords) { if (this.keywords) {

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen>
<div v-loading="loading"> <div v-loading="loading">
<el-tabs tab-position="top"> <el-tabs tab-position="top">
<el-tab-pane :label="$t('基本信息')"> <el-tab-pane :label="$t('基本信息')">
@ -27,13 +27,13 @@
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -41,7 +41,7 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close>
<el-form v-loading="loading" :model="form" :rules="rules" label-width="10rem" ref="dialogForm"> <el-form v-loading="loading" :model="form" :rules="rules" label-width="10rem" ref="dialogForm">
<el-form-item :label="$t('文档分类名称')" prop="name"> <el-form-item :label="$t('文档分类名称')" prop="name">
<el-input v-model="form.name" :placeholder="$t('文档分类名称')" clearable></el-input> <el-input v-model="form.name" :placeholder="$t('文档分类名称')" clearable></el-input>
@ -15,7 +15,7 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>

View File

@ -84,7 +84,7 @@
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button> <el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button>
<na-button-bulk-del :api="$API.sys_job.bulkDelete" :vue="this" /> <naButtonBulkDel :api="$API.sys_job.bulkDelete" :vue="this" />
<el-dropdown v-show="this.selection.length > 0"> <el-dropdown v-show="this.selection.length > 0">
<el-button type="primary"> <el-button type="primary">
{{ $t('批量操作') }} {{ $t('批量操作') }}
@ -143,7 +143,7 @@
row-key="id" row-key="id"
stripe> stripe>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<na-col-id :label="$t('作业编号')" prop="id" sortable="custom" width="170" /> <naColId :label="$t('作业编号')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('作业名称')" min-width="150" prop="jobName" show-overflow-tooltip sortable="custom" /> <el-table-column :label="$t('作业名称')" min-width="150" prop="jobName" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('执行计划')" align="right" prop="executionCron" sortable="custom" width="150"> <el-table-column :label="$t('执行计划')" align="right" prop="executionCron" sortable="custom" width="150">
<template #default="{ row }"> <template #default="{ row }">
@ -151,7 +151,7 @@
<p>{{ row.executionCron }}</p> <p>{{ row.executionCron }}</p>
</template> </template>
</el-table-column> </el-table-column>
<na-col-indicator <naColIndicator
:label="$t('作业状态')" :label="$t('作业状态')"
:options=" :options="
Object.entries(this.$GLOBAL.enums.jobStatues).map((x) => { Object.entries(this.$GLOBAL.enums.jobStatues).map((x) => {
@ -162,7 +162,7 @@
prop="status" prop="status"
sortable="custom" sortable="custom"
width="100" /> width="100" />
<na-col-indicator <naColIndicator
:label="$t('请求方式')" :label="$t('请求方式')"
:options=" :options="
Object.entries(this.$GLOBAL.enums.httpMethods).map((x) => { Object.entries(this.$GLOBAL.enums.httpMethods).map((x) => {
@ -206,7 +206,7 @@
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch> <el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<na-col-operation <naColOperation
:buttons=" :buttons="
naColOperation.buttons.concat( naColOperation.buttons.concat(
{ {
@ -220,13 +220,7 @@
title: '复制作业', title: '复制作业',
click: copyJob, click: copyJob,
}, },
{ naColOperation.delButton('删除作业', $API.sys_job.delete),
icon: 'el-icon-delete',
confirm: true,
title: '删除作业',
click: this.rowDel,
type: 'danger',
},
) )
" "
:vue="this" :vue="this"
@ -247,7 +241,7 @@
import { defineAsyncComponent, h } from 'vue' import { defineAsyncComponent, h } from 'vue'
import table from '@/config/table' import table from '@/config/table'
import naColOperation from '@/config/naColOperation' import naColOperation from '@/config/naColOperation'
import naIndicator from '@/components/naIndicator/index.vue' import naIndicator from '@/components/naIndicator'
const saveDialog = defineAsyncComponent(() => import('./save.vue')) const saveDialog = defineAsyncComponent(() => import('./save.vue'))
export default { export default {
@ -396,15 +390,6 @@ export default {
} catch {} } catch {}
this.$refs.table.refresh() this.$refs.table.refresh()
}, },
async rowDel(row) {
try {
const res = await this.$API.sys_job.delete.post({ id: row.id })
this.$message.success(this.$t('删除 {count} 项', { count: res.data }))
} catch {
//
}
this.$refs.table.refresh()
},
// //
onReset() { onReset() {
Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = [''])) Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen>
<el-tabs v-model="tabId" tab-position="top"> <el-tabs v-model="tabId" tab-position="top">
<el-tab-pane :label="$t('基本信息')"> <el-tab-pane :label="$t('基本信息')">
<el-form <el-form
@ -14,7 +14,7 @@
<el-input v-model="form.id" clearable /> <el-input v-model="form.id" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="$t('执行计划')" prop="executionCron"> <el-form-item :label="$t('执行计划')" prop="executionCron">
<sc-cron v-model="form.executionCron" class="font-monospace" clearable /> <scCron v-model="form.executionCron" class="font-monospace" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="$t('请求方法')" prop="httpMethod"> <el-form-item :label="$t('请求方法')" prop="httpMethod">
<el-select v-model="form.httpMethod" clearable filterable> <el-select v-model="form.httpMethod" clearable filterable>
@ -40,7 +40,7 @@
<el-input v-model="form.nextTimeId" clearable /> <el-input v-model="form.nextTimeId" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="$t('请求头')" prop="requestHeader"> <el-form-item :label="$t('请求头')" prop="requestHeader">
<v-ace-editor <VAceEditor
v-model:value="form.requestHeader" v-model:value="form.requestHeader"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'"
lang="json" lang="json"
@ -48,7 +48,7 @@
<el-button @click="form.requestHeader = jsonFormat(form.requestHeader)" type="text">{{ $t('JSON 格式化') }}</el-button> <el-button @click="form.requestHeader = jsonFormat(form.requestHeader)" type="text">{{ $t('JSON 格式化') }}</el-button>
</el-form-item> </el-form-item>
<el-form-item :label="$t('请求体')" prop="requestBody"> <el-form-item :label="$t('请求体')" prop="requestBody">
<v-ace-editor <VAceEditor
v-model:value="form.requestBody" v-model:value="form.requestBody"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'"
lang="json" lang="json"
@ -81,7 +81,7 @@
<el-input v-model="form.userId" clearable /> <el-input v-model="form.userId" clearable />
</el-form-item> </el-form-item>
<el-form-item v-else :label="$t('执行用户')" prop="user"> <el-form-item v-else :label="$t('执行用户')" prop="user">
<na-user-select v-model="form.user"></na-user-select> <naUserSelect v-model="form.user"></naUserSelect>
</el-form-item> </el-form-item>
<el-form-item v-if="mode === 'view'" :label="$t('创建时间')" prop="createdTime"> <el-form-item v-if="mode === 'view'" :label="$t('创建时间')" prop="createdTime">
<el-input v-model="form.createdTime" clearable /> <el-input v-model="form.createdTime" clearable />
@ -110,13 +110,13 @@
<record v-if="tabId === 'record'" :job-id="form.id" /> <record v-if="tabId === 'record'" :job-id="form.id" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
@ -124,16 +124,18 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import vkbeautify from 'vkbeautify/index' import vkbeautify from 'vkbeautify/index'
const Record = defineAsyncComponent(() => import('@/views/sys/job/record/index.vue')) const Record = defineAsyncComponent(() => import('@/views/sys/job/record'))
const naUserSelect = defineAsyncComponent(() => import('@/components/naUserSelect'))
const scCron = defineAsyncComponent(() => import('@/components/scCron'))
export default { export default {
components: { Record }, components: { Record, naUserSelect, scCron },
data() { data() {
return { return {
// //

View File

@ -14,8 +14,8 @@
<script> <script>
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
const log = defineAsyncComponent(() => import('@/views/sys/job/record/index.vue')) const log = defineAsyncComponent(() => import('@/views/sys/job/record'))
const all = defineAsyncComponent(() => import('@/views/sys/job/all/index.vue')) const all = defineAsyncComponent(() => import('@/views/sys/job/all'))
export default { export default {
components: { all, log }, components: { all, log },

View File

@ -110,7 +110,7 @@
remote-sort remote-sort
row-key="id" row-key="id"
stripe> stripe>
<na-col-id :label="$t('唯一编码')" prop="id" sortable="custom" width="170" /> <naColId :label="$t('唯一编码')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('响应状态码')" prop="httpStatusCode" sortable="custom" width="200"> <el-table-column :label="$t('响应状态码')" prop="httpStatusCode" sortable="custom" width="200">
<template #default="{ row }"> <template #default="{ row }">
<p> <p>
@ -155,7 +155,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('响应体')" min-width="300" prop="responseBody" show-overflow-tooltip sortable="custom" /> <el-table-column :label="$t('响应体')" min-width="300" prop="responseBody" show-overflow-tooltip sortable="custom" />
<na-col-operation :buttons="[naColOperation.buttons[0]]" :vue="this" width="50" /> <naColOperation :buttons="[naColOperation.buttons[0]]" :vue="this" width="50" />
</sc-table> </sc-table>
</el-main> </el-main>
</el-container> </el-container>
@ -179,7 +179,7 @@
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import table from '@/config/table' import table from '@/config/table'
import naColOperation from '@/config/naColOperation' import naColOperation from '@/config/naColOperation'
import naIndicator from '@/components/naIndicator/index.vue' import naIndicator from '@/components/naIndicator'
const saveDialog = defineAsyncComponent(() => import('./save.vue')) const saveDialog = defineAsyncComponent(() => import('./save.vue'))
const jobDialog = defineAsyncComponent(() => import('@/views/sys/job/all/save.vue')) const jobDialog = defineAsyncComponent(() => import('@/views/sys/job/all/save.vue'))

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen>
<el-form <el-form
v-loading="loading" v-loading="loading"
:disabled="mode === 'view'" :disabled="mode === 'view'"
@ -11,7 +11,7 @@
<el-tabs tab-position="top"> <el-tabs tab-position="top">
<el-tab-pane :label="$t('基本信息')"> <el-tab-pane :label="$t('基本信息')">
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :lg="8"> <el-col :lg="6">
<el-form-item :label="$t('唯一编码')" prop="id"> <el-form-item :label="$t('唯一编码')" prop="id">
<el-input v-model="form.id" clearable /> <el-input v-model="form.id" clearable />
</el-form-item> </el-form-item>
@ -28,7 +28,7 @@
<el-input v-model="form.jobId" clearable /> <el-input v-model="form.jobId" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="$t('请求的网络地址')" prop="requestUrl"> <el-form-item :label="$t('请求的网络地址')" prop="requestUrl">
<el-input v-model="form.requestUrl" clearable /> <el-input v-model="form.requestUrl" clearable type="textarea" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('执行时间编号')" prop="timeId"> <el-form-item :label="$t('执行时间编号')" prop="timeId">
<el-input v-model="form.timeId" clearable /> <el-input v-model="form.timeId" clearable />
@ -37,71 +37,86 @@
<el-input v-model="form.createdTime" clearable /> <el-input v-model="form.createdTime" clearable />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :lg="16"> <el-col :lg="col2Width">
<el-form-item v-if="form.requestHeader" :label="$t('请求头')" prop="requestHeader">
<json-viewer
v-if="mode === 'view'"
:expand-depth="1"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="JSON.parse(form.requestHeader)"
copyable
expanded
sort></json-viewer>
<el-input v-else v-model="form.requestHeader" clearable rows="5" type="textarea" />
</el-form-item>
<el-form-item v-if="form.requestBody" :label="$t('请求体')" prop="requestBody"> <el-form-item v-if="form.requestBody" :label="$t('请求体')" prop="requestBody">
<json-viewer <JsonViewer
v-if="mode === 'view'" v-if="mode === 'view'"
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="JSON.parse(form.requestBody)" :value="JSON.parse(form.requestBody)"
class="w100p children-nopadding"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
<el-input v-else v-model="form.requestBody" clearable rows="5" type="textarea" /> <el-input v-else v-model="form.requestBody" clearable rows="5" type="textarea" />
</el-form-item> </el-form-item>
<el-form-item v-if="form.responseHeader" :label="$t('响应头')" prop="responseHeader">
<json-viewer
v-if="mode === 'view'"
:expand-depth="1"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="JSON.parse(form.responseHeader)"
copyable
expanded
sort></json-viewer>
<el-input v-else v-model="form.responseHeader" clearable rows="5" type="textarea" />
</el-form-item>
<el-form-item v-if="form.responseBody" :label="$t('响应体')" prop="responseBody"> <el-form-item v-if="form.responseBody" :label="$t('响应体')" prop="responseBody">
<json-viewer <JsonViewer
v-if="mode === 'view'" v-if="mode === 'view'"
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="JSON.parse(form.responseBody)" :value="JSON.parse(form.responseBody)"
class="w100p children-nopadding"
copyable copyable
expanded expanded
sort> sort>
</json-viewer> </JsonViewer>
<el-input v-else v-model="form.responseBody" clearable rows="5" type="textarea" /> <el-input v-else v-model="form.responseBody" clearable rows="5" type="textarea" />
</el-form-item> </el-form-item>
<el-form-item v-if="form.requestHeader" :label="$t('请求头')" prop="requestHeader">
<JsonViewer
v-if="mode === 'view'"
:expand-depth="1"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="JSON.parse(form.requestHeader)"
class="w100p children-nopadding"
copyable
expanded
sort></JsonViewer>
<el-input v-else v-model="form.requestHeader" clearable rows="5" type="textarea" />
</el-form-item>
<el-form-item v-if="form.responseHeader" :label="$t('响应头')" prop="responseHeader">
<JsonViewer
v-if="mode === 'view'"
:expand-depth="1"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="JSON.parse(form.responseHeader)"
class="w100p children-nopadding"
copyable
expanded
sort></JsonViewer>
<el-input v-else v-model="form.responseHeader" clearable rows="5" type="textarea" />
</el-form-item>
</el-col>
<el-col v-if="this.esData" :lg="9">
<JsonViewer
v-if="mode === 'view'"
:expand-depth="1"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="this.esData"
class="children-nopadding"
copyable
expanded
sort></JsonViewer>
</el-col> </el-col>
</el-row> </el-row>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>
@ -109,6 +124,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
col2Width: 18,
esData: null,
// //
form: {}, form: {},
loading: true, loading: true,
@ -131,8 +148,45 @@ export default {
this.loading = true this.loading = true
this.mode = data.mode this.mode = data.mode
if (data.row?.id) { if (data.row?.id) {
const res = await this.$API.sys_job.getRecord.post({ id: data.row.id }) let res = await this.$API.sys_job.getRecord.post({ id: data.row.id })
Object.assign(this.form, res.data) Object.assign(this.form, res.data)
const traceId = /"traceId":"(.+?)"/.exec(this.form.responseBody)
if (traceId && traceId[1]) {
res = await this.$API.adm_tools.queryEsLog.post({
query: {
bool: {
must: [
{
range: {
'@timestamp': {
gt: new Date(this.form.createdTime).getTime() - 1000 * 60 * 60,
lt: new Date(this.form.createdTime).getTime() + 1000 * 60 * 60,
},
},
},
{
match_phrase: {
log_source: 'NetAdmin.SysComponent.Host.Utils.RequestLogger',
},
},
{
match_phrase: {
log_message: traceId[1],
},
},
],
},
},
size: 1000,
sort: [
{
'@timestamp': 'desc',
},
],
})
this.esData = res.data.hits.hits[0]._source
this.col2Width = 9
}
} }
this.loading = false this.loading = false
return this return this

View File

@ -105,7 +105,7 @@
remote-sort remote-sort
row-key="id" row-key="id"
stripe> stripe>
<na-col-id label="日志编号" prop="id" sortable="custom" width="170" /> <naColId label="日志编号" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('结果')" align="center" prop="httpStatusCode" sortable="custom" width="100"> <el-table-column :label="$t('结果')" align="center" prop="httpStatusCode" sortable="custom" width="100">
<template #default="{ row }"> <template #default="{ row }">
<sc-status-indicator :type="row.httpStatusCode === 200 ? 'success' : 'danger'" /> <sc-status-indicator :type="row.httpStatusCode === 200 ? 'success' : 'danger'" />
@ -123,7 +123,7 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('操作系统')" align="center" prop="os" width="150" /> <el-table-column :label="$t('操作系统')" align="center" prop="os" width="150" />
<el-table-column :label="$t('用户代理')" min-width="150" prop="createdUserAgent" show-overflow-tooltip sortable="custom" /> <el-table-column :label="$t('用户代理')" min-width="150" prop="createdUserAgent" show-overflow-tooltip sortable="custom" />
<na-col-operation <naColOperation
:buttons="[ :buttons="[
{ {
icon: 'el-icon-view', icon: 'el-icon-view',
@ -141,7 +141,7 @@
</template> </template>
<script> <script>
import naInfo from '@/components/naInfo/index.vue' import naInfo from '@/components/naInfo'
import http from '@/utils/request' import http from '@/utils/request'
export default { export default {

View File

@ -131,7 +131,7 @@
remote-sort remote-sort
row-key="id" row-key="id"
stripe> stripe>
<na-col-id label="日志编号" prop="id" sortable="custom" width="170" /> <naColId label="日志编号" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('响应码')" align="center" prop="httpStatusCode" sortable="custom" width="150"> <el-table-column :label="$t('响应码')" align="center" prop="httpStatusCode" sortable="custom" width="150">
<template #default="{ row }"> <template #default="{ row }">
<sc-status-indicator :type="row.httpStatusCode >= 200 && row.httpStatusCode < 300 ? 'success' : 'danger'" /> <sc-status-indicator :type="row.httpStatusCode >= 200 && row.httpStatusCode < 300 ? 'success' : 'danger'" />
@ -196,7 +196,7 @@
</template> </template>
</template> </template>
</el-table-column> </el-table-column>
<na-col-operation <naColOperation
:buttons="[ :buttons="[
{ {
icon: 'el-icon-view', icon: 'el-icon-view',
@ -223,7 +223,7 @@
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import http from '@/utils/request' import http from '@/utils/request'
const saveDialog = defineAsyncComponent(() => import('@/views/sys/user/save.vue')) const saveDialog = defineAsyncComponent(() => import('@/views/sys/user/save.vue'))
import naInfo from '@/components/naInfo/index.vue' import naInfo from '@/components/naInfo'
export default { export default {
components: { components: {

View File

@ -52,7 +52,7 @@
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button> <el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button>
<na-button-bulk-del :api="$API.sys_sitemsg.bulkDelete" :vue="this" /> <naButtonBulkDel :api="$API.sys_sitemsg.bulkDelete" :vue="this" />
</div> </div>
</el-header> </el-header>
<el-main class="nopadding"> <el-main class="nopadding">
@ -75,9 +75,9 @@
row-key="id" row-key="id"
stripe> stripe>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<na-col-id :label="$t('消息编号')" prop="id" sortable="custom" width="170" /> <naColId :label="$t('消息编号')" prop="id" sortable="custom" width="170" />
<na-col-avatar :label="$t('用户名')" min-width="100" prop="createdUserName" /> <naColAvatar :label="$t('用户名')" min-width="100" prop="createdUserName" />
<na-col-indicator <naColIndicator
:label="$t('消息类型')" :label="$t('消息类型')"
:options=" :options="
Object.entries(this.$GLOBAL.enums.siteMsgTypes).map((x) => { Object.entries(this.$GLOBAL.enums.siteMsgTypes).map((x) => {
@ -91,16 +91,8 @@
<el-table-column :label="$t('消息主题')" min-width="200" prop="title" show-overflow-tooltip sortable="custom" /> <el-table-column :label="$t('消息主题')" min-width="200" prop="title" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('消息摘要')" min-width="400" prop="summary" show-overflow-tooltip sortable="custom" /> <el-table-column :label="$t('消息摘要')" min-width="400" prop="summary" show-overflow-tooltip sortable="custom" />
<na-col-operation <naColOperation
:buttons=" :buttons="naColOperation.buttons.concat(naColOperation.delButton('删除消息', $API.sys_sitemsg.delete))"
naColOperation.buttons.concat({
icon: 'el-icon-delete',
confirm: true,
title: '删除消息',
click: this.rowDel,
type: 'danger',
})
"
:vue="this" :vue="this"
width="120" /> width="120" />
</sc-table> </sc-table>
@ -119,11 +111,12 @@
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
import table from '@/config/table' import table from '@/config/table'
import naColOperation from '@/config/naColOperation' import naColOperation from '@/config/naColOperation'
const naColAvatar = defineAsyncComponent(() => import('@/components/naColAvatar'))
const saveDialog = defineAsyncComponent(() => import('./save.vue')) const saveDialog = defineAsyncComponent(() => import('./save.vue'))
export default { export default {
components: { components: {
saveDialog, saveDialog,
naColAvatar,
}, },
computed: { computed: {
naColOperation() { naColOperation() {
@ -172,15 +165,6 @@ export default {
}) })
this.$refs.search.search() this.$refs.search.search()
}, },
async rowDel(row) {
try {
const res = await this.$API.sys_sitemsg.delete.post({ id: row.id })
this.$message.success(this.$t('删除 {count} 项', { count: res.data }))
} catch {
//
}
this.$refs.table.refresh()
},
async onSearch(form) { async onSearch(form) {
if (Array.isArray(form.dy.createdTime)) { if (Array.isArray(form.dy.createdTime)) {
this.query.dynamicFilter.filters.push({ this.query.dynamicFilter.filters.push({

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen>
<el-form <el-form
v-loading="loading" v-loading="loading"
:disabled="mode === 'view'" :disabled="mode === 'view'"
@ -29,7 +29,7 @@
</el-form-item> </el-form-item>
<el-form-item :label="$t('送至角色')" prop="roleIds"> <el-form-item :label="$t('送至角色')" prop="roleIds">
<sc-select <scSelect
v-if="!this.loading" v-if="!this.loading"
v-model="form.roleIds" v-model="form.roleIds"
:config="{ props: { label: 'name', value: 'id' } }" :config="{ props: { label: 'name', value: 'id' } }"
@ -40,10 +40,10 @@
multiple /> multiple />
</el-form-item> </el-form-item>
<el-form-item :label="$t('送至部门')" prop="deptIds"> <el-form-item :label="$t('送至部门')" prop="deptIds">
<na-dept v-model="form.deptIds" :multiple="true" class="w100p"></na-dept> <naDept v-model="form.deptIds" :multiple="true" class="w100p"></naDept>
</el-form-item> </el-form-item>
<el-form-item :label="$t('送至用户')" prop="userIds"> <el-form-item :label="$t('送至用户')" prop="userIds">
<na-user-select v-model="form.userIds" :multiple="true" class="w100p"></na-user-select> <naUserSelect v-model="form.userIds" :multiple="true" class="w100p"></naUserSelect>
</el-form-item> </el-form-item>
<el-form-item v-if="mode === 'view'" :label="$t('创建时间')" prop="createdTime"> <el-form-item v-if="mode === 'view'" :label="$t('创建时间')" prop="createdTime">
<el-input v-model="form.createdTime" clearable /> <el-input v-model="form.createdTime" clearable />
@ -54,13 +54,13 @@
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-form> </el-form>
@ -68,17 +68,23 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>
import { AiEditor } from 'aieditor' import { AiEditor } from 'aieditor'
import 'aieditor/dist/style.css' import 'aieditor/dist/style.css'
import sysConfig from '../../../config' import sysConfig from '../../../config'
import { defineAsyncComponent } from 'vue'
const naDept = defineAsyncComponent(() => import('@/components/naDept'))
const naUserSelect = defineAsyncComponent(() => import('@/components/naUserSelect'))
const scSelect = defineAsyncComponent(() => import('@/components/scSelect'))
export default { export default {
components: {}, components: {
emits: ['success', 'closed'], naDept,
naUserSelect,
scSelect,
},
data() { data() {
return { return {
// //

View File

@ -95,7 +95,7 @@
</div> </div>
<div class="right-panel"> <div class="right-panel">
<el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button> <el-button @click="this.dialog.save = { mode: 'add' }" icon="el-icon-plus" type="primary"></el-button>
<na-button-bulk-del :api="$API.sys_role.bulkDelete" :vue="this" /> <naButtonBulkDel :api="$API.sys_role.bulkDelete" :vue="this" />
<el-dropdown v-show="this.selection.length > 0"> <el-dropdown v-show="this.selection.length > 0">
<el-button type="primary"> <el-button type="primary">
{{ $t('批量操作') }} {{ $t('批量操作') }}
@ -132,7 +132,7 @@
row-key="id" row-key="id"
stripe> stripe>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<na-col-id :label="$t('角色编号')" prop="id" sortable="custom" width="170" /> <naColId :label="$t('角色编号')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('角色名称')" min-width="150" prop="name" sortable="custom" /> <el-table-column :label="$t('角色名称')" min-width="150" prop="name" sortable="custom" />
<el-table-column :label="$t('用户数量')" align="right" width="100"> <el-table-column :label="$t('用户数量')" align="right" width="100">
<template #default="{ row }"> <template #default="{ row }">
@ -147,7 +147,7 @@
<el-switch v-model="row.ignorePermissionControl" @change="changeIgnorePermissionControl($event, row)"></el-switch> <el-switch v-model="row.ignorePermissionControl" @change="changeIgnorePermissionControl($event, row)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<na-col-indicator <naColIndicator
:label="$t('数据范围')" :label="$t('数据范围')"
:options=" :options="
Object.entries(this.$GLOBAL.enums.dataScopes).map((x) => { Object.entries(this.$GLOBAL.enums.dataScopes).map((x) => {
@ -158,7 +158,7 @@
prop="dataScope" prop="dataScope"
sortable="custom" sortable="custom"
width="120"> width="120">
</na-col-indicator> </naColIndicator>
<el-table-column :label="$t('显示仪表板')" align="center" prop="displayDashboard" sortable="custom" width="120"> <el-table-column :label="$t('显示仪表板')" align="center" prop="displayDashboard" sortable="custom" width="120">
<template #default="{ row }"> <template #default="{ row }">
@ -170,7 +170,7 @@
<el-switch v-model="row.enabled" @change="changeEnabled($event, row)"></el-switch> <el-switch v-model="row.enabled" @change="changeEnabled($event, row)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<na-col-operation <naColOperation
:buttons=" :buttons="
naColOperation.buttons.concat( naColOperation.buttons.concat(
{ {
@ -179,13 +179,7 @@
title: '复制角色', title: '复制角色',
click: copyRole, click: copyRole,
}, },
{ naColOperation.delButton('删除角色', $API.sys_role.delete),
icon: 'el-icon-delete',
confirm: true,
title: '删除角色',
click: this.rowDel,
type: 'danger',
},
) )
" "
:vue="this" :vue="this"
@ -350,15 +344,6 @@ export default {
}) })
this.$refs.search.search() this.$refs.search.search()
}, },
async rowDel(row) {
try {
const res = await this.$API.sys_role.delete.post({ id: row.id })
this.$message.success(this.$t('删除 {count} 项', { count: res.data }))
} catch {
//
}
this.$refs.table.refresh()
},
// //
onReset() { onReset() {
Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = [''])) Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen> <scDialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen>
<div v-loading="loading"> <div v-loading="loading">
<el-tabs v-model="tabId" tab-position="top"> <el-tabs v-model="tabId" tab-position="top">
<el-tab-pane :label="$t('基本信息')"> <el-tab-pane :label="$t('基本信息')">
@ -74,7 +74,7 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item v-if="form.displayDashboard" :label="$t('仪表板布局')"> <el-form-item v-if="form.displayDashboard" :label="$t('仪表板布局')">
<v-ace-editor <VAceEditor
v-model:value="form.dashboardLayout" v-model:value="form.dashboardLayout"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'"
lang="json" lang="json"
@ -89,13 +89,13 @@
<user v-if="tabId === 'user'" :role-id="form.id"></user> <user v-if="tabId === 'user'" :role-id="form.id"></user>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
@ -103,7 +103,7 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>
@ -111,7 +111,7 @@ import { defineAsyncComponent } from 'vue'
import vkbeautify from 'vkbeautify/index' import vkbeautify from 'vkbeautify/index'
import config from '@/config/index' import config from '@/config/index'
const User = defineAsyncComponent(() => import('@/views/sys/user/index.vue')) const User = defineAsyncComponent(() => import('@/views/sys/user'))
export default { export default {
components: { User }, components: { User },
created() {}, created() {},

View File

@ -111,21 +111,21 @@
row-key="id" row-key="id"
stripe> stripe>
<el-table-column type="selection" width="50" /> <el-table-column type="selection" width="50" />
<na-col-id :label="$t('用户编号')" prop="id" sortable="custom" width="170" /> <naColId :label="$t('用户编号')" prop="id" sortable="custom" width="170" />
<na-col-avatar :label="$t('用户名')" prop="userName" width="170" /> <naColAvatar :label="$t('用户名')" prop="userName" width="170" />
<el-table-column :label="$t('手机号 / 邮箱')" align="right" prop="mobile" sortable="custom" width="250"> <el-table-column :label="$t('手机号 / 邮箱')" align="right" prop="mobile" sortable="custom" width="250">
<template #default="{ row }"> <template #default="{ row }">
<p>{{ row.mobile }}</p> <p>{{ row.mobile }}</p>
<p>{{ row.email }}</p> <p>{{ row.email }}</p>
</template> </template>
</el-table-column> </el-table-column>
<na-col-tags <naColTags
:label="$t('所属部门')" :label="$t('所属部门')"
@click="(item) => (this.dialog.deptSave = { row: item, mode: 'view' })" @click="(item) => (this.dialog.deptSave = { row: item, mode: 'view' })"
field="name" field="name"
prop="dept" prop="dept"
width="120" /> width="120" />
<na-col-tags <naColTags
:label="$t('所属角色')" :label="$t('所属角色')"
@click="(item) => (this.dialog.roleSave = { row: item, mode: 'view' })" @click="(item) => (this.dialog.roleSave = { row: item, mode: 'view' })"
field="name" field="name"
@ -141,7 +141,7 @@
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch> <el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<na-col-operation :vue="this" width="120" /> <naColOperation :vue="this" width="120" />
</sc-table> </sc-table>
</el-col> </el-col>
</el-row> </el-row>
@ -173,11 +173,15 @@ import table from '@/config/table'
const roleSaveDialog = defineAsyncComponent(() => import('@/views/sys/role/save.vue')) const roleSaveDialog = defineAsyncComponent(() => import('@/views/sys/role/save.vue'))
const deptSaveDialog = defineAsyncComponent(() => import('@/views/sys/dept/save.vue')) const deptSaveDialog = defineAsyncComponent(() => import('@/views/sys/dept/save.vue'))
const saveDialog = defineAsyncComponent(() => import('./save.vue')) const saveDialog = defineAsyncComponent(() => import('./save.vue'))
const naColAvatar = defineAsyncComponent(() => import('@/components/naColAvatar'))
const naColTags = defineAsyncComponent(() => import('@/components/naColTags'))
export default { export default {
components: { components: {
naColAvatar,
deptSaveDialog, deptSaveDialog,
roleSaveDialog, roleSaveDialog,
saveDialog, saveDialog,
naColTags,
}, },
computed: { computed: {
table() { table() {

View File

@ -1,5 +1,5 @@
<template> <template>
<sc-dialog <scDialog
v-model="visible" v-model="visible"
:title="`${titleMap[mode]}${form?.id ?? '...'}`" :title="`${titleMap[mode]}${form?.id ?? '...'}`"
@closed="$emit('closed')" @closed="$emit('closed')"
@ -17,7 +17,7 @@
<el-tabs v-model="tabId" tab-position="top"> <el-tabs v-model="tabId" tab-position="top">
<el-tab-pane :label="$t('基本信息')"> <el-tab-pane :label="$t('基本信息')">
<el-form-item prop="avatar"> <el-form-item prop="avatar">
<sc-upload v-model="form.avatar" :title="$t('上传头像')"></sc-upload> <scUpload v-model="form.avatar" :title="$t('上传头像')"></scUpload>
</el-form-item> </el-form-item>
<el-form-item v-if="mode === 'view'" :label="$t('唯一编码')" prop="id"> <el-form-item v-if="mode === 'view'" :label="$t('唯一编码')" prop="id">
<el-input v-model="form.id" clearable></el-input> <el-input v-model="form.id" clearable></el-input>
@ -51,7 +51,7 @@
</el-form-item> </el-form-item>
<el-form-item :label="$t('所属角色')" prop="roleIds"> <el-form-item :label="$t('所属角色')" prop="roleIds">
<sc-select <scSelect
v-if="!this.loading" v-if="!this.loading"
v-model="form.roleIds" v-model="form.roleIds"
:config="{ props: { label: 'name', value: 'id' } }" :config="{ props: { label: 'name', value: 'id' } }"
@ -62,7 +62,7 @@
multiple /> multiple />
</el-form-item> </el-form-item>
<el-form-item :label="$t('所属部门')" prop="deptId"> <el-form-item :label="$t('所属部门')" prop="deptId">
<na-dept v-model="form.deptId" class="w100p"></na-dept> <naDept v-model="form.deptId" class="w100p"></naDept>
</el-form-item> </el-form-item>
<template v-if="mode !== 'add'"> <template v-if="mode !== 'add'">
@ -144,7 +144,7 @@
</el-col> </el-col>
<el-col :lg="12"> <el-col :lg="12">
<el-form-item :label="$t('籍贯')" prop="profile.nationArea"> <el-form-item :label="$t('籍贯')" prop="profile.nationArea">
<na-area v-model="form.profile.nationArea"></na-area> <naArea v-model="form.profile.nationArea"></naArea>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -166,7 +166,7 @@
<el-form-item :label="$t('住宅地址')" prop="profile.homeAddress"> <el-form-item :label="$t('住宅地址')" prop="profile.homeAddress">
<el-input v-model="form.profile.homeAddress" clearable> <el-input v-model="form.profile.homeAddress" clearable>
<template v-slot:prepend> <template v-slot:prepend>
<na-area v-model="form.profile.homeArea" style="width: 15rem"></na-area> <naArea v-model="form.profile.homeArea" style="width: 15rem"></naArea>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
@ -187,7 +187,7 @@
<el-form-item :label="$t('工作地址')" prop="profile.companyAddress"> <el-form-item :label="$t('工作地址')" prop="profile.companyAddress">
<el-input v-model="form.profile.companyAddress" clearable> <el-input v-model="form.profile.companyAddress" clearable>
<template v-slot:prepend> <template v-slot:prepend>
<na-area v-model="form.profile.companyArea" style="width: 15rem"></na-area> <naArea v-model="form.profile.companyArea" style="width: 15rem"></naArea>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
@ -218,14 +218,14 @@
<el-form-item :label="$t('联系人地址')" prop="profile.emergencyContactAddress"> <el-form-item :label="$t('联系人地址')" prop="profile.emergencyContactAddress">
<el-input v-model="form.profile.emergencyContactAddress" clearable> <el-input v-model="form.profile.emergencyContactAddress" clearable>
<template v-slot:prepend> <template v-slot:prepend>
<na-area v-model="form.profile.emergencyContactArea" style="width: 15rem"></na-area> <naArea v-model="form.profile.emergencyContactArea" style="width: 15rem"></naArea>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item :label="$t('应用配置')" prop="profile.appConfig"> <el-form-item :label="$t('应用配置')" prop="profile.appConfig">
<v-ace-editor <VAceEditor
v-model:value="form.profile.appConfig" v-model:value="form.profile.appConfig"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'"
lang="json" lang="json"
@ -238,13 +238,13 @@
<log v-if="tabId === 'log'" :owner-id="form.id"></log> <log v-if="tabId === 'log'" :owner-id="form.id"></log>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')"> <el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer <JsonViewer
:expand-depth="5" :expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'" :theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form" :value="form"
copyable copyable
expanded expanded
sort></json-viewer> sort></JsonViewer>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-form> </el-form>
@ -252,15 +252,19 @@
<el-button @click="visible = false">{{ $t('取消') }}</el-button> <el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button> <el-button v-if="mode !== 'view'" :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template> </template>
</sc-dialog> </scDialog>
</template> </template>
<script> <script>
import { defineAsyncComponent } from 'vue' import { defineAsyncComponent } from 'vue'
const log = defineAsyncComponent(() => import('@/views/sys/log/operation/index.vue')) const log = defineAsyncComponent(() => import('@/views/sys/log/operation'))
const naArea = defineAsyncComponent(() => import('@/components/naArea'))
const naDept = defineAsyncComponent(() => import('@/components/naDept'))
const scUpload = defineAsyncComponent(() => import('@/components/scUpload'))
const scSelect = defineAsyncComponent(() => import('@/components/scSelect'))
export default { export default {
components: { log }, components: { log, naArea, naDept, scUpload, scSelect },
data() { data() {
return { return {
// //