项目初始化

This commit is contained in:
2026-03-18 15:54:43 +08:00
commit dfcd762e23
601 changed files with 57883 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
<template>
<div class="default-main ba-table-box">
<el-alert class="ba-table-alert" v-if="baTable.table.remark" :title="baTable.table.remark" type="info" show-icon />
<!-- 表格顶部菜单 -->
<TableHeader
:buttons="['refresh', 'add', 'edit', 'delete', 'comSearch', 'quickSearch', 'columnDisplay']"
:quick-search-placeholder="t('Quick search placeholder', { fields: t('user.group.GroupName') })"
/>
<!-- 表格 -->
<!-- 要使用`el-table`组件原有的属性直接加在Table标签上即可 -->
<Table ref="tableRef" />
<!-- 表单 -->
<PopupForm ref="formRef" />
</div>
</template>
<script setup lang="ts">
import { onMounted, provide, useTemplateRef } from 'vue'
import { useI18n } from 'vue-i18n'
import PopupForm from './popupForm.vue'
import { getUserRules } from '/@/api/backend/user/group'
import { baTableApi } from '/@/api/common'
import { defaultOptButtons } from '/@/components/table'
import TableHeader from '/@/components/table/header/index.vue'
import Table from '/@/components/table/index.vue'
import baTableClass from '/@/utils/baTable'
import { uuid } from '/@/utils/random'
defineOptions({
name: 'user/group',
})
const { t } = useI18n()
const formRef = useTemplateRef('formRef')
const tableRef = useTemplateRef('tableRef')
const baTable = new baTableClass(
new baTableApi('/admin/user.Group/'),
{
column: [
{ type: 'selection', align: 'center', operator: false },
{ label: t('Id'), prop: 'id', align: 'center', operator: '=', operatorPlaceholder: t('Id'), width: 70 },
{ label: t('user.group.Group name'), prop: 'name', align: 'center', operator: 'LIKE', operatorPlaceholder: t('Fuzzy query') },
{
label: t('State'),
prop: 'status',
align: 'center',
render: 'tag',
custom: { 0: 'danger', 1: 'success' },
replaceValue: { 0: t('Disable'), 1: t('Enable') },
},
{ label: t('Update time'), prop: 'update_time', align: 'center', render: 'datetime', sortable: 'custom', operator: 'RANGE', width: 160 },
{ label: t('Create time'), prop: 'create_time', align: 'center', render: 'datetime', sortable: 'custom', operator: 'RANGE', width: 160 },
{
label: t('Operate'),
align: 'center',
width: '130',
render: 'buttons',
buttons: defaultOptButtons(['edit', 'delete']),
operator: false,
},
],
dblClickNotEditColumn: [undefined],
},
{
defaultItems: {
status: 1,
},
}
)
// 利用提交前钩子重写提交操作
baTable.before.onSubmit = ({ formEl, operate, items }) => {
let submitCallback = () => {
baTable.form.submitLoading = true
baTable.api
.postData(operate, {
...items,
rules: formRef.value?.getCheckeds(),
})
.then((res) => {
baTable.onTableHeaderAction('refresh', {})
baTable.form.submitLoading = false
baTable.form.operateIds?.shift()
if (baTable.form.operateIds!.length > 0) {
baTable.toggleForm('Edit', baTable.form.operateIds)
} else {
baTable.toggleForm()
}
baTable.runAfter('onSubmit', { res })
})
.catch(() => {
baTable.form.submitLoading = false
})
}
if (formEl) {
baTable.form.ref = formEl
formEl.validate((valid) => {
if (valid) {
submitCallback()
}
})
} else {
submitCallback()
}
return false
}
// 打开表单后
baTable.after.toggleForm = ({ operate }) => {
if (operate == 'Add') {
menuRuleTreeUpdate()
}
}
// 获取到编辑数据后
baTable.after.getEditData = () => {
menuRuleTreeUpdate()
}
const menuRuleTreeUpdate = () => {
getUserRules().then((res) => {
baTable.form.extend!.menuRules = res.data.list
if (baTable.form.items!.rules && baTable.form.items!.rules.length) {
if (baTable.form.items!.rules.includes('*')) {
let arr: number[] = []
for (const key in baTable.form.extend!.menuRules) {
arr.push(baTable.form.extend!.menuRules[key].id)
}
baTable.form.extend!.defaultCheckedKeys = arr
} else {
baTable.form.extend!.defaultCheckedKeys = baTable.form.items!.rules
}
} else {
baTable.form.extend!.defaultCheckedKeys = []
}
baTable.form.extend!.treeKey = uuid()
})
}
provide('baTable', baTable)
onMounted(() => {
baTable.table.ref = tableRef.value
baTable.mount()
baTable.getData()
})
</script>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,145 @@
<template>
<!-- 对话框表单 -->
<el-dialog
class="ba-operate-dialog"
top="10vh"
:close-on-click-modal="false"
:model-value="['Add', 'Edit'].includes(baTable.form.operate!)"
@close="baTable.toggleForm"
:destroy-on-close="true"
>
<template #header>
<div class="title" v-drag="['.ba-operate-dialog', '.el-dialog__header']" v-zoom="'.ba-operate-dialog'">
{{ baTable.form.operate ? t(baTable.form.operate) : '' }}
</div>
</template>
<el-scrollbar v-loading="baTable.form.loading" class="ba-table-form-scrollbar">
<div
class="ba-operate-form"
:class="'ba-' + baTable.form.operate + '-form'"
:style="config.layout.shrink ? '' : 'width: calc(100% - ' + baTable.form.labelWidth! / 2 + 'px)'"
>
<el-form
ref="formRef"
@submit.prevent=""
@keyup.enter="baTable.onSubmit(formRef)"
:model="baTable.form.items"
:label-position="config.layout.shrink ? 'top' : 'right'"
:label-width="baTable.form.labelWidth + 'px'"
:rules="rules"
>
<el-form-item prop="name" :label="t('user.group.Group name')">
<el-input
v-model="baTable.form.items!.name"
type="string"
:placeholder="t('Please input field', { field: t('user.group.Group name') })"
></el-input>
</el-form-item>
<el-form-item prop="auth" :label="t('user.group.jurisdiction')">
<el-tree
ref="treeRef"
:key="baTable.form.extend!.treeKey"
:default-checked-keys="baTable.form.extend!.defaultCheckedKeys"
:default-expand-all="true"
show-checkbox
node-key="id"
:props="{ children: 'children', label: 'title', class: treeNodeClass }"
:data="baTable.form.extend!.menuRules"
class="w100"
/>
</el-form-item>
<FormItem
:label="t('State')"
v-model="baTable.form.items!.status"
type="radio"
:input-attr="{
border: true,
content: { 0: t('Disable'), 1: t('Enable') },
}"
/>
</el-form>
</div>
</el-scrollbar>
<template #footer>
<div :style="'width: calc(100% - ' + baTable.form.labelWidth! / 1.8 + 'px)'">
<el-button @click="baTable.toggleForm('')">{{ t('Cancel') }}</el-button>
<el-button v-blur :loading="baTable.form.submitLoading" @click="baTable.onSubmit(formRef)" type="primary">
{{ baTable.form.operateIds && baTable.form.operateIds.length > 1 ? t('Save and edit next item') : t('Save') }}
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { reactive, inject, useTemplateRef } from 'vue'
import { useI18n } from 'vue-i18n'
import type baTableClass from '/@/utils/baTable'
import type { ElTree, FormItemRule } from 'element-plus'
import FormItem from '/@/components/formItem/index.vue'
import type Node from 'element-plus/es/components/tree/src/model/node'
import { buildValidatorData } from '/@/utils/validate'
import { useConfig } from '/@/stores/config'
const config = useConfig()
const formRef = useTemplateRef('formRef')
const treeRef = useTemplateRef('treeRef')
const baTable = inject('baTable') as baTableClass
const { t } = useI18n()
const rules: Partial<Record<string, FormItemRule[]>> = reactive({
name: [buildValidatorData({ name: 'required', title: t('user.group.Group name') })],
auth: [
{
required: true,
validator: (rule: any, val: string, callback: Function) => {
let ids = getCheckeds()
if (ids.length <= 0) {
return callback(new Error(t('Please select field', { field: t('user.group.jurisdiction') })))
}
return callback()
},
},
],
})
const getCheckeds = () => {
return treeRef.value!.getCheckedKeys().concat(treeRef.value!.getHalfCheckedKeys())
}
const treeNodeClass = (data: anyObj, node: Node) => {
if (node.isLeaf) return ''
let addClass = true
for (const key in node.childNodes) {
if (!node.childNodes[key].isLeaf) {
addClass = false
}
}
return addClass ? 'penultimate-node' : ''
}
defineExpose({
getCheckeds,
})
</script>
<style scoped lang="scss">
:deep(.penultimate-node) {
.el-tree-node__children {
padding-left: 60px;
white-space: pre-wrap;
line-height: 12px;
.el-tree-node {
display: inline-block;
}
.el-tree-node__content {
padding-left: 5px !important;
padding-right: 5px;
.el-tree-node__expand-icon {
display: none;
}
}
}
}
</style>