feat: 文档管理 (#221)

Co-authored-by: tk <fiyne1a@dingtalk.com>
This commit is contained in:
2024-11-27 15:52:23 +08:00
committed by GitHub
parent 71bfdaafa8
commit 7ed30406c9
89 changed files with 2748 additions and 141 deletions

View File

@ -12,7 +12,7 @@
"@element-plus/icons-vue": "2.3.1",
"ace-builds": "1.36.5",
"aieditor": "1.2.7",
"axios": "1.7.7",
"axios": "1.7.8",
"crypto-js": "4.2.0",
"echarts": "5.5.1",
"element-plus": "2.8.8",
@ -20,11 +20,11 @@
"markdown-it": "14.1.0",
"markdown-it-emoji": "3.0.0",
"nprogress": "0.2.0",
"sortablejs": "1.15.3",
"sortablejs": "1.15.4",
"vkbeautify": "0.99.3",
"vue": "3.5.13",
"vue-i18n": "10.0.4",
"vue-router": "4.4.5",
"vue-router": "4.5.0",
"vue3-ace-editor": "2.2.4",
"vue3-json-viewer": "2.2.2",
"vuedraggable": "4.0.3",
@ -32,7 +32,7 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "5.2.0",
"prettier": "3.3.3",
"prettier": "3.4.0",
"prettier-plugin-organize-attributes": "1.0.0",
"sass": "1.81.0",
"terser": "5.36.0",

View File

@ -0,0 +1,194 @@
/**
* 文档服务
* @module @/api/sys/doc
*/
import config from '@/config'
import http from '@/utils/request'
export default {
/**
* 批量删除文档分类
*/
bulkDeleteCatalog: {
url: `${config.API_URL}/api/sys/doc/bulk.delete.catalog`,
name: `批量删除文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 批量删除文档内容
*/
bulkDeleteContent: {
url: `${config.API_URL}/api/sys/doc/bulk.delete.content`,
name: `批量删除文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 创建文档分类
*/
createCatalog: {
url: `${config.API_URL}/api/sys/doc/create.catalog`,
name: `创建文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 创建文档内容
*/
createContent: {
url: `${config.API_URL}/api/sys/doc/create.content`,
name: `创建文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 删除文档分类
*/
deleteCatalog: {
url: `${config.API_URL}/api/sys/doc/delete.catalog`,
name: `删除文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 删除文档内容
*/
deleteContent: {
url: `${config.API_URL}/api/sys/doc/delete.content`,
name: `删除文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 编辑文档分类
*/
editCatalog: {
url: `${config.API_URL}/api/sys/doc/edit.catalog`,
name: `编辑文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 编辑文档内容
*/
editContent: {
url: `${config.API_URL}/api/sys/doc/edit.content`,
name: `编辑文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 导出文档内容
*/
exportContent: {
url: `${config.API_URL}/api/sys/doc/export.content`,
name: `导出文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 获取单个文档分类
*/
getCatalog: {
url: `${config.API_URL}/api/sys/doc/get.catalog`,
name: `获取单个文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 获取单个文档内容
*/
getContent: {
url: `${config.API_URL}/api/sys/doc/get.content`,
name: `获取单个文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 分页查询文档分类
*/
pagedQueryCatalog: {
url: `${config.API_URL}/api/sys/doc/paged.query.catalog`,
name: `分页查询文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 分页查询文档内容
*/
pagedQueryContent: {
url: `${config.API_URL}/api/sys/doc/paged.query.content`,
name: `分页查询文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 查询文档分类
*/
queryCatalog: {
url: `${config.API_URL}/api/sys/doc/query.catalog`,
name: `查询文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 查询文档内容
*/
queryContent: {
url: `${config.API_URL}/api/sys/doc/query.content`,
name: `查询文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 启用/禁用文档内容
*/
setEnabled: {
url: `${config.API_URL}/api/sys/doc/set.enabled`,
name: `启用/禁用文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 浏览文档内容
*/
viewContent: {
url: `${config.API_URL}/api/sys/doc/view.content`,
name: `浏览文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
}

View File

@ -0,0 +1,73 @@
/**
* 文档分类服务
* @module @/api/sys/doc.catalog
*/
import config from '@/config'
import http from '@/utils/request'
export default {
/**
* 批量删除文档分类
*/
bulkDelete: {
url: `${config.API_URL}/api/sys/doc.catalog/bulk.delete`,
name: `批量删除文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 文档分类计数
*/
count: {
url: `${config.API_URL}/api/sys/doc.catalog/count`,
name: `文档分类计数`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 创建文档分类
*/
create: {
url: `${config.API_URL}/api/sys/doc.catalog/create`,
name: `创建文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 删除文档分类
*/
delete: {
url: `${config.API_URL}/api/sys/doc.catalog/delete`,
name: `删除文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 获取单个文档分类
*/
get: {
url: `${config.API_URL}/api/sys/doc.catalog/get`,
name: `获取单个文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 分页查询文档分类
*/
pagedQuery: {
url: `${config.API_URL}/api/sys/doc.catalog/paged.query`,
name: `分页查询文档分类`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
}

View File

@ -0,0 +1,84 @@
/**
* 文档内容服务
* @module @/api/sys/doc.content
*/
import config from '@/config'
import http from '@/utils/request'
export default {
/**
* 批量删除文档内容
*/
bulkDelete: {
url: `${config.API_URL}/api/sys/doc.content/bulk.delete`,
name: `批量删除文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 文档内容计数
*/
count: {
url: `${config.API_URL}/api/sys/doc.content/count`,
name: `文档内容计数`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 创建文档内容
*/
create: {
url: `${config.API_URL}/api/sys/doc.content/create`,
name: `创建文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 删除文档内容
*/
delete: {
url: `${config.API_URL}/api/sys/doc.content/delete`,
name: `删除文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 获取单个文档内容
*/
get: {
url: `${config.API_URL}/api/sys/doc.content/get`,
name: `获取单个文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 分页查询文档内容
*/
pagedQuery: {
url: `${config.API_URL}/api/sys/doc.content/paged.query`,
name: `分页查询文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
/**
* 启用/禁用文档内容
*/
setEnabled: {
url: `${config.API_URL}/api/sys/doc.content/set.enabled`,
name: `启用/禁用文档内容`,
post: async function (data = {}, config = {}) {
return await http.post(this.url, data, config)
},
},
}

View File

@ -11,7 +11,7 @@
<p v-if="$attrs.nestProp2">{{ $TOOL.getNestedProperty(row, $attrs.nestProp2) }}</p>
</div>
</div>
<save-dialog v-if="dialog.save" @closed="dialog.save = false" ref="saveDialog"></save-dialog>
<save-dialog v-if="dialog.save" @closed="(dialog.save = false)" ref="saveDialog"></save-dialog>
</template>
</el-table-column>
</template>

View File

@ -293,7 +293,7 @@
</div>
<template #footer>
<el-button @click="dialogVisible = false">{{ $t('取消') }}</el-button>
<el-button @click="(dialogVisible = false)">{{ $t('取消') }}</el-button>
<el-button @click="submit()" type="primary">{{ $t('确认') }}</el-button>
</template>
</el-dialog>

View File

@ -49,7 +49,7 @@
</div>
<template #footer>
<el-button @click="clear" text>{{ $t('清除') }}</el-button>
<el-button @click="dialogVisible = false">{{ $t('取消') }}</el-button>
<el-button @click="(dialogVisible = false)">{{ $t('取消') }}</el-button>
</template>
</el-dialog>
</div>

View File

@ -13,7 +13,7 @@
</el-form>
<template #footer>
<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>
</template>
</sc-dialog>

View File

@ -90,8 +90,8 @@
:hide-after="0"
:title="$t('列设置')"
:width="500"
@after-leave="customColumnShow = false"
@show="customColumnShow = true"
@after-leave="(customColumnShow = false)"
@show="(customColumnShow = true)"
placement="top"
trigger="click">
<template #reference>

View File

@ -51,7 +51,7 @@
<el-dialog v-model="cropperDialogVisible" :title="$t('剪裁')" :width="580" @closed="cropperClosed" destroy-on-close draggable>
<sc-cropper :aspectRatio="aspectRatio" :compress="compress" :src="cropperFile.tempCropperFile" ref="cropper"></sc-cropper>
<template #footer>
<el-button @click="cropperDialogVisible = false">{{ $t('取消') }}</el-button>
<el-button @click="(cropperDialogVisible = false)">{{ $t('取消') }}</el-button>
<el-button @click="cropperSave" type="primary">{{ $t('确定') }}</el-button>
</template>
</el-dialog>

View File

@ -55,7 +55,6 @@ 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 naDicCatalog from '@/components/naDicCatalog/index.vue'
import naFormEmail from '@/components/naFormEmail/index.vue'
import naSearch from '@/components/naSearch'
import naUserSelect from '@/components/naUserSelect/index.vue'
@ -98,7 +97,6 @@ export default {
app.component('naColTime', naColTime)
app.component('naColUser', naColUser)
app.component('naDept', naDept)
app.component('naDicCatalog', naDicCatalog)
app.component('naFormEmail', naFormEmail)
app.component('naSearch', naSearch)
app.component('naUserSelect', naUserSelect)

View File

@ -53,7 +53,7 @@
</el-footer>
</el-container>
<save-dialog v-if="dialog.save" @closed="dialog.save = null" @mounted="$refs.saveDialog.open(dialog.save)" ref="saveDialog"></save-dialog>
<save-dialog v-if="dialog.save" @closed="(dialog.save = null)" @mounted="$refs.saveDialog.open(dialog.save)" ref="saveDialog"></save-dialog>
</template>
<script>

View File

@ -71,11 +71,11 @@
</div>
<el-dialog v-model="searchVisible" :title="$t('搜索')" :width="700" center destroy-on-close>
<search @success="searchVisible = false"></search>
<search @success="(searchVisible = false)"></search>
</el-dialog>
<el-drawer v-model="tasksVisible" :size="450" :title="$t('作业中心')" destroy-on-close>
<tasks :fail="failJobCnt" @closed="tasksVisible = false"></tasks>
<tasks :fail="failJobCnt" @closed="(tasksVisible = false)"></tasks>
</el-drawer>
</template>

View File

@ -84,7 +84,7 @@ export default {
失败: 'Failed',
头像: 'Avatar',
婚姻状况: 'Marital status',
字典分类: 'Dictionary Classification',
字典目录: 'Dictionary catalog',
客户端IP: 'Client IP',
密码: 'Password',
: 'Small',
@ -380,7 +380,7 @@ export default {
响应体: 'Response body',
响应头: 'Response header',
执行时间编号: 'Execution time ID',
新增字典: 'Add dictionary',
新增字典目录: 'Add dictionary catalog',
字典名称: 'Dictionary name',
字典编码: 'Dictionary code',
父路径: 'Parent path',

View File

@ -84,7 +84,7 @@ export default {
失败: '失败',
头像: '头像',
婚姻状况: '婚姻状况',
字典分类: '字典分类',
字典目录: '字典目录',
客户端IP: '客户端IP',
密码: '密码',
: '小',
@ -379,7 +379,7 @@ export default {
响应体: '响应体',
响应头: '响应头',
执行时间编号: '执行时间编号',
新增字典: '新增字典',
新增字典目录: '新增字典目录',
字典名称: '字典名称',
字典编码: '字典编码',
父路径: '父路径',

View File

@ -68,6 +68,13 @@ const routes = [
title: '重置密码',
},
},
{
path: '/guest/view-doc/:id',
component: () => import(/* webpackChunkName: "view-doc" */ '@/views/guest/view-doc'),
meta: {
title: '查看文档',
},
},
]
export default routes

View File

@ -31,7 +31,7 @@
</el-form-item>
<el-form-item label="" prop="agree">
<el-checkbox v-model="form.agree" label="">{{ $t('我已阅读并同意') }}</el-checkbox>
<span @click="showAgree = true" class="link">{{ $t('平台服务协议') }}</span>
<span @click="(showAgree = true)" class="link">{{ $t('平台服务协议') }}</span>
</el-form-item>
</el-form>
<el-form v-if="stepActive === 1" :model="form" :rules="rules" ref="stepForm_1" size="large">
@ -57,7 +57,7 @@
</el-form>
<el-dialog v-model="showAgree" :title="$t('平台服务协议')" destroy-on-close>
<template #footer>
<el-button @click="showAgree = false">{{ $t('取消') }}</el-button>
<el-button @click="(showAgree = false)">{{ $t('取消') }}</el-button>
<el-button
@click="
() => {

View File

@ -0,0 +1,61 @@
<template>
<article v-if="doc" v-loading="loading" class="article">
<h1>{{ doc.title }}</h1>
<section
:class="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'aie-theme-dark' : 'aie-theme-light'"
ref="editor"></section>
</article>
<not-found v-else></not-found>
</template>
<script>
import { AiEditor } from 'aieditor'
import 'aieditor/dist/style.css'
import { defineAsyncComponent } from 'vue'
const notFound = defineAsyncComponent(() => import('@/layout/other/404.vue'))
import sysConfig from '@/config'
import tool from '@/utils/tool'
export default {
components: { notFound },
data() {
return {
loading: true,
doc: { title: '' },
}
},
async created() {
const res = await this.$API.sys_doc.viewContent.post({ id: this.$route.params.id })
this.doc = res.data
this.loading = false
if (this.doc) {
document.title = this.doc.title
const aiEditor = new AiEditor({
element: this.$refs.editor,
content: this.doc.body,
onChange: (body) => {
this.doc.body = body.getHtml()
},
})
aiEditor.changeLang(this.$TOOL.data.get('APP_SET_LANG') || sysConfig.APP_SET_LANG)
} else {
await tool.data.set('LOGIN_REDIRECT', window.location.href)
}
},
methods: {},
}
</script>
<style scoped>
.article {
display: flex;
height: 100%;
flex-direction: column;
> h1 {
padding: 1rem;
}
> section {
flex: 1;
}
}
</style>

View File

@ -77,7 +77,7 @@
</div>
</el-header>
<el-header style="height: auto">
<el-button @click="this.dialog.customLayout = { title: '添加自定义布局' }" style="margin: 0 auto">添加自定义布局</el-button>
<el-button @click="(this.dialog.customLayout = { title: '添加自定义布局' })" style="margin: 0 auto">添加自定义布局</el-button>
</el-header>
<el-main class="nopadding">
<div class="widgets-list">
@ -115,7 +115,7 @@
<custom-layout-dialog
v-if="dialog.customLayout"
@closed="dialog.customLayout = null"
@closed="(dialog.customLayout = null)"
@mounted="$refs.customLayoutDialog.open(dialog.customLayout)"
@onCustomLayout="(l) => (customLayouts = [l])"
ref="customLayoutDialog"></custom-layout-dialog>

View File

@ -52,7 +52,7 @@
</draggable>
</div>
<template #footer>
<el-button @click="modsDrawer = false">{{ $t('取消') }}</el-button>
<el-button @click="(modsDrawer = false)">{{ $t('取消') }}</el-button>
<el-button @click="saveMods" type="primary">{{ $t('保存') }}</el-button>
</template>
</el-drawer>

View File

@ -36,18 +36,18 @@
<set-mobile-dialog
v-if="dialog.setMobile"
@closed="dialog.setMobile = null"
@closed="(dialog.setMobile = null)"
@mounted="$refs.setMobileDialog.open(dialog.setMobile)"
@success="setSuccess"
ref="setMobileDialog"></set-mobile-dialog>
<set-password-dialog
v-if="dialog.setPassword"
@closed="dialog.setPassword = null"
@closed="(dialog.setPassword = null)"
@mounted="$refs.setPasswordDialog.open(dialog.setPassword)"
ref="setPasswordDialog"></set-password-dialog>
<set-email-dialog
v-if="dialog.setEmail"
@closed="dialog.setEmail = null"
@closed="(dialog.setEmail = null)"
@mounted="$refs.setEmailDialog.open(dialog.setEmail)"
@success="setSuccess"
ref="setEmailDialog"></set-email-dialog>

View File

@ -28,7 +28,7 @@
</el-form>
<template #footer>
<el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button @click="(visible = false)">{{ $t('取消') }}</el-button>
<el-button :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template>
</el-dialog>

View File

@ -33,7 +33,7 @@
</el-form>
<template #footer>
<el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button @click="(visible = false)">{{ $t('取消') }}</el-button>
<el-button :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template>
</el-dialog>

View File

@ -34,7 +34,7 @@
</el-form>
<template #footer>
<el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button @click="(visible = false)">{{ $t('取消') }}</el-button>
<el-button :disabled="loading" :loading="loading" @click="submit" type="primary">{{ $t('保存') }}</el-button>
</template>
</el-dialog>

View File

@ -39,7 +39,7 @@
ref="search" />
</div>
<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" />
<el-dropdown v-show="this.selection.length > 0">
<el-button type="primary">
@ -106,7 +106,7 @@
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => $refs.table.upData()"
ref="saveDialog"></save-dialog>

View File

@ -44,7 +44,7 @@
</el-tabs>
</div>
<template #footer>
<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>
</template>
</sc-dialog>

View File

@ -46,7 +46,7 @@
ref="search" />
</div>
<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" />
<el-dropdown v-show="this.selection.length > 0">
<el-button type="primary">
@ -113,7 +113,7 @@
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="saveDialog"></save-dialog>

View File

@ -42,7 +42,7 @@
</el-tabs>
</div>
<template #footer>
<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>
</template>
</sc-dialog>

View File

@ -38,7 +38,7 @@
</el-main>
<el-footer>
<el-button @click="add(form.catalogId)" icon="el-icon-plus" size="small" style="width: 100%" type="primary">{{
$t('字典分类')
$t('字典目录')
}}</el-button>
</el-footer>
</el-container>
@ -48,7 +48,7 @@
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => getData()"
ref="saveDialog"></save-dialog>
@ -106,7 +106,7 @@ export default {
},
//字典目录增加
async add(id, code) {
this.dialog.save = { mode: 'add', data: { catalogId: id, code: code + '>' } }
this.dialog.save = { mode: 'add', data: { catalogId: id, code: code ? code + '>' : '' } }
},
//字典目录编辑
async edit(data) {

View File

@ -23,8 +23,8 @@
:controls="[
{
type: 'input',
field: ['dy', 'keywords'],
placeholder: $t('项名 / 项值'),
field: ['root', 'keywords'],
placeholder: $t('项名 / 项值 / 备注'),
style: 'width:20rem',
},
]"
@ -38,7 +38,7 @@
</div>
<div class="right-panel">
<el-button
@click="this.dialog.save = { mode: 'add', data: { catalogId: this.catalogId } }"
@click="(this.dialog.save = { mode: 'add', data: { catalogId: this.catalogId } })"
icon="el-icon-plus"
type="primary"></el-button>
<na-button-bulk-del :api="$API.sys_dic.bulkDeleteContent" :vue="this" />
@ -53,7 +53,7 @@
<el-dropdown-menu>
<el-dropdown-item @click="setEnabled(true)">{{ $t('启用') }}</el-dropdown-item>
<el-dropdown-item @click="setEnabled(false)">{{ $t('禁用') }}</el-dropdown-item>
<el-dropdown-item @click="this.dialog.savebatch = { mode: 'batchedit', data: { catalogId: this.catalogId } }">{{
<el-dropdown-item @click="(this.dialog.savebatch = { mode: 'batchedit', data: { catalogId: this.catalogId } })">{{
$t('设置项值')
}}</el-dropdown-item>
</el-dropdown-menu>
@ -64,7 +64,7 @@
<el-main class="nopadding">
<sc-table
:before-post="(data) => data.dynamicFilter.filters.length > 0"
:context-menus="['key', 'value', 'enabled', 'createdTime']"
:context-menus="['key', 'value', 'enabled', 'createdTime', 'id', 'summary']"
:default-sort="{ prop: 'createdTime', order: 'descending' }"
:export-api="$API.sys_dic.exportContent"
:params="query"
@ -80,6 +80,7 @@
row-key="id"
stripe>
<el-table-column type="selection" width="50" />
<na-col-id :label="$t('唯一编码')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('项名')" prop="key" sortable="custom" />
<el-table-column :label="$t('项值')" prop="value" sortable="custom" />
<el-table-column :label="$t('备注')" prop="summary" sortable="custom" />
@ -88,7 +89,6 @@
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
</template>
</el-table-column>
<el-table-column :label="$t('创建时间')" align="right" prop="createdTime" sortable="custom" width="170" />
<na-col-operation
:buttons="
naColOperation.buttons.concat({
@ -107,14 +107,14 @@
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="saveDialog"></save-dialog>
<savebatch-dialog
v-if="dialog.savebatch"
@closed="dialog.savebatch = null"
@closed="(dialog.savebatch = null)"
@mounted="$refs.savebatchDialog.open(dialog.savebatch)"
@success="(data, mode) => batchsuccess(data, mode)"
ref="savebatchDialog"></savebatch-dialog>
@ -222,25 +222,7 @@ export default {
this.query.dynamicFilter.filters.push({
field: 'createdTime',
operator: 'dateRange',
value: form.dy.createdTime,
})
}
if (form.dy.keywords) {
this.query.dynamicFilter.filters.push({
logic: 'or',
filters: [
{
field: 'key',
operator: 'contains',
value: form.dy.keywords,
},
{
field: 'value',
operator: 'contains',
value: form.dy.keywords,
},
],
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
})
}

View File

@ -4,8 +4,8 @@
<el-tabs tab-position="top">
<el-tab-pane :label="$t('基本信息')">
<el-form :disabled="mode === 'view'" :model="form" :rules="rules" label-width="10rem" ref="dialogForm">
<el-form-item :label="$t('所属字典')" prop="catalogId">
<na-dic-catalog v-model="form.catalogId" class="w100p" />
<el-form-item :label="$t('所属字典目录')" prop="catalogId">
<catalog-select v-model="form.catalogId" class="w100p" />
</el-form-item>
<el-form-item :label="$t('项名')" prop="key">
<el-input v-model="form.key" clearable></el-input>
@ -30,15 +30,17 @@
</el-tabs>
</div>
<template #footer>
<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>
</template>
</sc-dialog>
</template>
<script>
import { defineAsyncComponent } from 'vue'
const catalogSelect = defineAsyncComponent(() => import('../components/catalog-select.vue'))
export default {
components: {},
components: { catalogSelect },
data() {
return {
//表单数据
@ -47,7 +49,7 @@ export default {
mode: 'add',
//验证规则
rules: {
catalogId: [{ required: true, message: '请选择所属字典' }],
catalogId: [{ required: true, message: '请选择所属字典目录' }],
key: [{ required: true, message: '请输入项名' }],
value: [{ required: true, message: '请输入项值' }],
},

View File

@ -21,7 +21,7 @@
</el-tabs>
</div>
<template #footer>
<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>
</template>
</sc-dialog>

View File

@ -1,25 +1,28 @@
<template>
<sc-dialog 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-item :label="$t('字典名称')" prop="name">
<el-input v-model="form.name" :placeholder="$t('字典名称')" clearable></el-input>
<el-form-item :label="$t('字典目录名称')" prop="name">
<el-input v-model="form.name" :placeholder="$t('字典目录名称')" clearable></el-input>
</el-form-item>
<el-form-item :label="$t('字典编码')" prop="code">
<el-input v-model="form.code" :placeholder="$t('字典编码')" clearable></el-input>
<el-form-item :label="$t('字典目录编码')" prop="code">
<el-input v-model="form.code" :placeholder="$t('字典目录编码')" clearable></el-input>
</el-form-item>
<el-form-item :label="$t('父路径')" prop="parentId">
<na-dic-catalog v-model="form.parentId" class="w100p" />
<catalog-select v-model="form.parentId" class="w100p" />
</el-form-item>
</el-form>
<template #footer>
<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>
</template>
</sc-dialog>
</template>
<script>
import { defineAsyncComponent } from 'vue'
const catalogSelect = defineAsyncComponent(() => import('./components/catalog-select.vue'))
export default {
components: { catalogSelect },
data() {
return {
//表单数据
@ -28,12 +31,12 @@ export default {
mode: 'add',
//验证规则
rules: {
code: [{ required: true, message: '请输入编码' }],
name: [{ required: true, message: '请输入字典名称' }],
code: [{ required: true, message: '请输入字典目录编码' }],
name: [{ required: true, message: '请输入字典目录名称' }],
},
titleMap: {
add: this.$t('新增字典'),
edit: this.$t('编辑字典'),
add: this.$t('新增字典目录'),
edit: this.$t('编辑字典目录'),
},
visible: false,
}

View File

@ -0,0 +1,52 @@
<template>
<el-cascader
v-bind="$attrs"
v-model="data"
:options="options"
:placeholder="placeholder"
:props="{
value: 'id',
label: 'name',
emitPath: false,
checkStrictly: true,
expandTrigger: 'hover',
}"
clearable></el-cascader>
</template>
<style scoped></style>
<script>
export default {
props: {
modelValue: { type: Object },
placeholder: { type: String },
},
data() {
return {
loaded: false,
data: null,
options: [],
}
},
watch: {
data(n) {
this.$emit('update:modelValue', n)
},
modelValue: {
immediate: true,
deep: true,
handler(n) {
this.data = n ?? null
},
},
},
mounted() {},
async created() {
const res = await this.$API.sys_doc.queryCatalog.post()
this.options = res.data
},
components: {},
computed: {},
methods: {},
}
</script>

View File

@ -0,0 +1,167 @@
<template>
<el-container>
<el-aside v-loading="loading" width="40rem">
<el-container>
<el-header>
<el-input v-model="filterText" :placeholder="$t('输入关键字进行过滤')" clearable></el-input>
</el-header>
<el-main class="nopadding">
<el-tree
:data="data"
:expand-on-click-node="false"
:filter-node-method="filterNode"
:highlight-current="true"
:props="{
label: 'name',
}"
@node-click="click"
default-expand-all
node-key="id"
ref="doc">
<template #default="{ _, data }">
<div class="custom-tree-node">
<span>{{ data.name }} {{ data.code }}</span>
<span class="btn">
<el-button-group size="small">
<el-button @click.stop="add(data.id, data.code)" icon="el-icon-plus"></el-button>
<el-button @click.stop="edit(data)" icon="el-icon-edit"></el-button>
<el-popconfirm :title="$t('确定删除 {item} 吗?', { item: data.name })" @confirm="del(data)" width="20rem">
<template #reference>
<el-button @click.stop="() => {}" icon="el-icon-delete"></el-button>
</template>
</el-popconfirm>
</el-button-group>
</span>
</div>
</template>
</el-tree>
</el-main>
<el-footer>
<el-button @click="add(form.catalogId)" icon="el-icon-plus" size="small" style="width: 100%" type="primary">{{
$t('文档分类')
}}</el-button>
</el-footer>
</el-container>
</el-aside>
<list :catalogId="form.catalogId" />
</el-container>
<save-dialog
v-if="dialog.save"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => getData()"
ref="saveDialog"></save-dialog>
</template>
<script>
import { defineAsyncComponent } from 'vue'
import list from './list'
const saveDialog = defineAsyncComponent(() => import('./save.vue'))
export default {
components: {
list,
saveDialog,
},
computed: {},
created() {},
data() {
return {
data: [],
dialog: {},
filterText: '',
form: {},
loading: false,
query: {
dynamicFilter: {
filters: [],
},
filter: {},
keywords: this.keywords,
},
}
},
inject: ['reload'],
methods: {
// 获取文档分类
async getData() {
this.loading = true
const res = await this.$API.sys_doc.queryCatalog.post({ prop: 'name', order: 'ascending' })
this.loading = false
this.data = res.data
//获取第一个节点,设置选中 & 加载明细列表
if (this.data.length > 0) {
await this.$nextTick()
this.$refs.doc.setCurrentKey(this.data[0].id)
this.form.catalogId = this.data[0].id
}
},
//文档分类过滤
filterNode(value, data) {
if (!value) return true
const targetText = data.name + data.code
return targetText.indexOf(value) !== -1
},
//文档分类增加
async add(id, code) {
this.dialog.save = { mode: 'add', data: { catalogId: id, code: code ? code + '>' : '' } }
},
//文档分类编辑
async edit(data) {
this.dialog.save = { mode: 'edit', row: data }
},
//文档分类点击
click(data) {
this.form.catalogId = data.id
},
//文档分类删除
async del(data) {
this.loading = true
try {
await this.$API.sys_doc.deleteCatalog.post({
id: data.id,
})
this.$message.success(this.$t('操作成功'))
} catch {
//
}
this.loading = false
await this.getData()
},
},
mounted() {
this.getData()
},
props: ['keywords'],
watch: {
filterText(val) {
this.$refs.doc.filter(val)
},
},
}
</script>
<style lang="scss" scoped>
.custom-tree-node {
display: flex;
flex-grow: 1;
align-items: center;
justify-content: space-between;
margin-right: 2rem;
.btn {
display: none;
gap: 1rem;
}
&:hover .btn {
display: flex;
}
}
::v-deep .el-tree-node__content {
height: 3rem;
}
</style>

View File

@ -0,0 +1,266 @@
<template>
<el-container>
<el-header style="height: auto; padding: 0 1rem">
<sc-select-filter
:data="[
{
title: $t('启用状态'),
key: 'enabled',
options: [
{ label: $t('全部'), value: '' },
{ label: $t('启用'), value: true },
{ label: $t('禁用'), value: false },
],
},
{
title: $t('档案可见性'),
key: 'visibility',
options: [
{ label: $t('全部'), value: '' },
...Object.entries(this.$GLOBAL.enums.archiveVisibilities).map((x) => {
return { value: x[0], label: x[1][1] }
}),
],
},
]"
:label-width="6"
@on-change="filterChange"
ref="selectFilter"></sc-select-filter>
</el-header>
<el-header>
<div class="left-panel">
<na-search
:controls="[
{
type: 'input',
field: ['root', 'keywords'],
placeholder: $t('文档标题'),
style: 'width:20rem',
},
]"
:vue="this"
@reset="onReset"
@search="onSearch"
dateFormat="YYYY-MM-DD HH:mm:ss"
dateType="datetimerange"
dateValueFormat="YYYY-MM-DD HH:mm:ss"
ref="search" />
</div>
<div class="right-panel">
<el-button
@click="(this.dialog.save = { mode: 'add', data: { catalogId: this.catalogId } })"
icon="el-icon-plus"
type="primary"></el-button>
<na-button-bulk-del :api="$API.sys_doc.bulkDeleteContent" :vue="this" />
<el-dropdown v-show="this.selection.length > 0">
<el-button type="primary">
{{ $t('批量操作') }}
<el-icon>
<el-icon-arrow-down />
</el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="setEnabled(true)">{{ $t('启用') }}</el-dropdown-item>
<el-dropdown-item @click="setEnabled(false)">{{ $t('禁用') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</el-header>
<el-main class="nopadding">
<sc-table
:before-post="(data) => data.dynamicFilter.filters.length > 0"
:context-menus="['title', 'enabled', 'createdTime', 'id', 'visibility']"
:default-sort="{ prop: 'createdTime', order: 'descending' }"
:export-api="$API.sys_doc.exportContent"
:params="query"
:query-api="$API.sys_doc.pagedQueryContent"
:vue="this"
@selection-change="
(items) => {
selection = items
}
"
ref="table"
remote-sort
row-key="id"
stripe>
<el-table-column type="selection" width="50" />
<na-col-id :label="$t('唯一编码')" prop="id" sortable="custom" width="170" />
<el-table-column :label="$t('文档标题')" prop="title" sortable="custom" />
<na-col-indicator
:label="$t('档案可见性')"
:options="
Object.entries(this.$GLOBAL.enums.archiveVisibilities).map((x) => {
return { value: x[0], text: x[1][1], type: x[1][2] }
})
"
align="center"
prop="visibility"
sortable="custom"
width="150" />
<el-table-column :label="$t('启用')" align="center" prop="enabled" sortable="custom" width="100">
<template #default="{ row }">
<el-switch v-model="row.enabled" @change="changeSwitch($event, row)"></el-switch>
</template>
</el-table-column>
<na-col-operation
:buttons="
naColOperation.buttons.concat({
icon: 'el-icon-delete',
confirm: true,
title: '删除文档',
click: rowDel,
type: 'danger',
})
"
:vue="this"
width="150" />
</sc-table>
</el-main>
</el-container>
<save-dialog
v-if="dialog.save"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="saveDialog"></save-dialog>
</template>
<script>
import { defineAsyncComponent } from 'vue'
import table from '@/config/table'
import naColOperation from '@/config/naColOperation'
const saveDialog = defineAsyncComponent(() => import('./save.vue'))
export default {
components: {
saveDialog,
},
computed: {
naColOperation() {
return naColOperation
},
table() {
return table
},
},
created() {},
data() {
return {
dialog: {},
loading: false,
query: {
dynamicFilter: {
filters: [],
},
filter: {},
keywords: this.keywords,
},
selection: [],
}
},
inject: ['reload'],
methods: {
filterChange(data) {
Object.entries(data).forEach(([key, value]) => {
this.$refs.search.form.dy[key] = value === 'true' ? true : value === 'false' ? false : value
})
this.$refs.search.search()
},
//表格内开关事件
async changeSwitch(event, row) {
try {
await this.$API.sys_doc.setEnabled.post(row)
this.$message.success(`操作成功`)
} catch {
//
}
this.$refs.table.refresh()
},
async setEnabled(enabled) {
let loading
try {
await this.$confirm(`确定${enabled ? '启用' : '禁用'}选中的 ${this.selection.length} 项吗?`, '提示', {
type: 'warning',
})
loading = this.$loading()
const res = await Promise.all(this.selection.map((x) => this.$API.sys_doc.setEnabled.post(Object.assign(x, { enabled: enabled }))))
this.$message.success(`操作成功 ${res.map((x) => x.data ?? 0).reduce((a, b) => a + b, 0)}/${this.selection.length}`)
} catch {
//
}
this.$refs.table.refresh()
loading?.close()
},
onReset() {
Object.entries(this.$refs.selectFilter.selected).forEach(([key, _]) => (this.$refs.selectFilter.selected[key] = ['']))
},
//搜索
onSearch(form) {
this.query.dynamicFilter.filters.push({
field: 'catalogId',
value: this.catalogId,
operator: 'eq',
})
if (Array.isArray(form.dy.createdTime)) {
this.query.dynamicFilter.filters.push({
field: 'createdTime',
operator: 'dateRange',
value: form.dy.createdTime.map((x) => x.replace(/ 00:00:00$/, '')),
})
}
if (typeof form.dy.enabled === 'boolean') {
this.query.dynamicFilter.filters.push({
field: 'enabled',
operator: 'eq',
value: form.dy.enabled,
})
}
if (typeof form.dy.visibility === 'string' && form.dy.visibility.trim() !== '') {
this.query.dynamicFilter.filters.push({
field: 'visibility',
operator: 'eq',
value: form.dy.visibility,
})
}
this.$refs.table.upData()
},
//删除
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() {
if (this.keywords) {
this.$refs.search.form.root.keywords = this.keywords
this.$refs.search.keeps.push({
field: 'keywords',
value: this.keywords,
type: 'root',
})
}
},
props: { catalogId: Number, keywords: String },
watch: {
catalogId() {
this.$refs.search.reset()
},
},
}
</script>
<style scoped></style>

View File

@ -0,0 +1,133 @@
<template>
<sc-dialog v-model="visible" :title="`${titleMap[mode]}${form?.id ?? '...'}`" @closed="$emit('closed')" destroy-on-close full-screen>
<div v-loading="loading">
<el-tabs tab-position="top">
<el-tab-pane :label="$t('基本信息')">
<el-form :disabled="mode === 'view'" :model="form" :rules="rules" label-width="10rem" ref="dialogForm">
<el-form-item :label="$t('所属文档分类')" prop="catalogId">
<catalog-select v-model="form.catalogId" class="w100p" />
</el-form-item>
<el-form-item :label="$t('文档标题')" prop="title">
<el-input v-model="form.title" clearable></el-input>
</el-form-item>
<el-form-item :label="$t('档案可见性')" prop="visibility">
<el-select v-model="form.visibility" clearable filterable>
<el-option v-for="(item, i) in $GLOBAL.enums.archiveVisibilities" :key="i" :label="item[1]" :value="i" />
</el-select>
</el-form-item>
<el-form-item :label="$t('文档内容')" prop="body">
<div
:class="
this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK
? 'aie-theme-dark editor'
: 'aie-theme-light editor'
"
ref="editor"></div>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane v-if="mode === 'view'" :label="$t('原始数据')">
<json-viewer
:expand-depth="5"
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'dark' : 'light'"
:value="form"
copyable
expanded
sort></json-viewer>
</el-tab-pane>
</el-tabs>
</div>
<template #footer>
<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>
</template>
</sc-dialog>
</template>
<script>
import { defineAsyncComponent } from 'vue'
import { AiEditor } from 'aieditor'
import 'aieditor/dist/style.css'
import sysConfig from '@/config'
const catalogSelect = defineAsyncComponent(() => import('../components/catalog-select.vue'))
export default {
components: { catalogSelect },
data() {
return {
//表单数据
form: {},
loading: true,
mode: 'add',
//验证规则
rules: {
catalogId: [{ required: true, message: '请选择所属文档分类' }],
title: [{ required: true, message: '请输入文档标题' }],
body: [{ required: true, message: '请输入文档内容' }],
visibility: [{ required: true, message: '请选择档案可见性' }],
},
titleMap: {
add: this.$t('新增文档'),
edit: this.$t('编辑文档'),
view: this.$t('查看文档'),
},
visible: false,
}
},
emits: ['success', 'closed', 'mounted'],
methods: {
//显示
async open(data) {
this.visible = true
this.loading = true
this.mode = data.mode
this.form.catalogId = data.data?.catalogId
if (data.row?.id) {
const res = await this.$API.sys_doc.getContent.post({ id: data.row.id })
Object.assign(this.form, res.data)
}
this.loading = false
await this.$nextTick()
const aiEditor = new AiEditor({
element: this.$refs.editor,
placeholder: this.$t('请输入消息内容...'),
content: this.form.body,
onChange: (body) => {
this.form.body = body.getHtml()
},
})
aiEditor.changeLang(this.$TOOL.data.get('APP_SET_LANG') || sysConfig.APP_SET_LANG)
return this
},
//表单提交方法
async submit() {
const valid = await this.$refs.dialogForm.validate().catch(() => {})
if (!valid) {
return false
}
this.loading = true
const method = this.mode === 'add' ? this.$API.sys_doc.createContent : this.$API.sys_doc.editContent
try {
const res = await method.post(this.form)
this.$emit('success', res.data, this.mode)
this.visible = false
this.$message.success(this.$t('操作成功'))
} catch {}
this.loading = false
},
},
mounted() {
this.$emit('mounted')
},
}
</script>
<style scoped>
.editor {
width: 100%;
height: 50rem;
}
</style>

View File

@ -0,0 +1,84 @@
<template>
<sc-dialog 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-item :label="$t('文档分类名称')" prop="name">
<el-input v-model="form.name" :placeholder="$t('文档分类名称')" clearable></el-input>
</el-form-item>
<el-form-item :label="$t('文档分类编码')" prop="code">
<el-input v-model="form.code" :placeholder="$t('文档分类编码')" clearable></el-input>
</el-form-item>
<el-form-item :label="$t('父路径')" prop="parentId">
<catalog-select v-model="form.parentId" class="w100p" />
</el-form-item>
</el-form>
<template #footer>
<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>
</template>
</sc-dialog>
</template>
<script>
import { defineAsyncComponent } from 'vue'
const catalogSelect = defineAsyncComponent(() => import('./components/catalog-select.vue'))
export default {
components: { catalogSelect },
data() {
return {
//表单数据
form: {},
loading: true,
mode: 'add',
//验证规则
rules: {
code: [{ required: true, message: '请输入文档分类编码' }],
name: [{ required: true, message: '请输入文档分类名称' }],
},
titleMap: {
add: this.$t('新增文档分类'),
edit: this.$t('编辑文档分类'),
},
visible: false,
}
},
emits: ['success', 'closed', 'mounted'],
methods: {
//显示
async open(data) {
this.visible = true
this.loading = true
this.mode = data.mode
this.form.parentId = data.data?.catalogId
this.form.code = data.data?.code
if (data.row?.id) {
const res = await this.$API.sys_doc.getCatalog.post({ id: data.row.id })
Object.assign(this.form, res.data)
}
this.loading = false
return this
},
//表单提交方法
async submit() {
const valid = await this.$refs.dialogForm.validate().catch(() => {})
if (!valid) {
return false
}
this.loading = true
const method = this.mode === 'add' ? this.$API.sys_doc.createCatalog : this.$API.sys_doc.editCatalog
try {
const res = await method.post(this.form)
this.$emit('success', res.data, this.mode)
this.visible = false
this.$message.success(this.$t('操作成功'))
} catch {}
this.loading = false
},
},
mounted() {
this.$emit('mounted')
},
}
</script>
<style scoped></style>

View File

@ -70,7 +70,7 @@
ref="search" />
</div>
<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" />
<el-dropdown v-show="this.selection.length > 0">
<el-button type="primary">
@ -223,7 +223,7 @@
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="saveDialog"></save-dialog>

View File

@ -45,7 +45,7 @@
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'"
lang="json"
style="height: 10rem; width: 100%" />
<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 :label="$t('请求体')" prop="requestBody">
<v-ace-editor
@ -53,7 +53,7 @@
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'"
lang="json"
style="height: 15rem; width: 100%" />
<el-button @click="form.requestBody = jsonFormat(form.requestBody)" type="text">{{ $t('JSON 格式化') }}</el-button>
<el-button @click="(form.requestBody = jsonFormat(form.requestBody))" type="text">{{ $t('JSON 格式化') }}</el-button>
</el-form-item>
<el-form-item :label="$t('请求的网络地址')" prop="requestUrl">
<el-input v-model="form.requestUrl" clearable />
@ -121,7 +121,7 @@
</el-tabs>
<template #footer>
<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>
</template>
</sc-dialog>

View File

@ -135,14 +135,14 @@
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="saveDialog"></save-dialog>
<job-dialog
v-if="dialog.job"
@closed="dialog.job = null"
@closed="(dialog.job = null)"
@mounted="$refs.jobDialog.open(dialog.job)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="jobDialog"></job-dialog>

View File

@ -39,7 +39,7 @@
</el-tabs>
</el-form>
<template #footer>
<el-button @click="visible = false">{{ $t('取消') }}</el-button>
<el-button @click="(visible = false)">{{ $t('取消') }}</el-button>
</template>
</sc-dialog>
</template>

View File

@ -182,7 +182,7 @@
<na-info v-if="dialog.info" ref="info"></na-info>
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="saveDialog"></save-dialog>

View File

@ -47,7 +47,7 @@
ref="search" />
</div>
<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" />
</div>
</el-header>
@ -105,7 +105,7 @@
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="saveDialog"></save-dialog>

View File

@ -65,7 +65,7 @@
</el-tabs>
</el-form>
<template #footer>
<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>
</template>
</sc-dialog>

View File

@ -64,7 +64,7 @@
ref="search" />
</div>
<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" />
<el-dropdown v-show="this.selection.length > 0">
<el-button type="primary">
@ -159,7 +159,7 @@
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="saveDialog"></save-dialog>

View File

@ -80,7 +80,7 @@
:theme="this.$TOOL.data.get('APP_SET_DARK') || this.$CONFIG.APP_SET_DARK ? 'github_dark' : 'github'"
lang="json"
style="height: 30rem; width: 100%" />
<el-button @click="form.dashboardLayout = jsonFormat(form.dashboardLayout)" type="text">{{
<el-button @click="(form.dashboardLayout = jsonFormat(form.dashboardLayout))" type="text">{{
$t('JSON 格式化')
}}</el-button>
</el-form-item>
@ -101,7 +101,7 @@
</el-tabs>
</div>
<template #footer>
<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>
</template>
</sc-dialog>

View File

@ -62,7 +62,7 @@
ref="search" />
</div>
<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>
<el-dropdown v-show="this.selection.length > 0">
<el-button type="primary">
{{ $t('批量操作') }}
@ -132,18 +132,18 @@
<save-dialog
v-if="dialog.save"
@closed="dialog.save = null"
@closed="(dialog.save = null)"
@mounted="$refs.saveDialog.open(dialog.save)"
@success="(data, mode) => table.handleUpdate($refs.table, data, mode)"
ref="saveDialog"></save-dialog>
<role-save-dialog
v-if="dialog.roleSave"
@closed="dialog.roleSave = null"
@closed="(dialog.roleSave = null)"
@mounted="$refs.roleSaveDialog.open(dialog.roleSave)"
ref="roleSaveDialog"></role-save-dialog>
<dept-save-dialog
v-if="dialog.deptSave"
@closed="dialog.deptSave = null"
@closed="(dialog.deptSave = null)"
@mounted="$refs.deptSaveDialog.open(dialog.deptSave)"
ref="deptSaveDialog"></dept-save-dialog>
</template>

View File

@ -46,7 +46,7 @@
maxlength="16"
oninput="value=value.replace(/[^\w]/g,'')"
placeholder="8位以上数字字母组合"></el-input>
<el-button @click="form.passwordText = '1234qwer'">{{ $t('初始密码') }}</el-button>
<el-button @click="(form.passwordText = '1234qwer')">{{ $t('初始密码') }}</el-button>
</div>
</el-form-item>
@ -249,7 +249,7 @@
</el-tabs>
</el-form>
<template #footer>
<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>
</template>
</sc-dialog>