mirror of
https://gitee.com/ssssssss-team/magic-boot.git
synced 2026-07-09 00:00:04 +08:00
mb-list mb-form mb-xxx等 统一请求方法 列表(post) 保存(post) 删除(delete) 详情(get) 等
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
|
||||
const components = import.meta.glob('./*/*.vue')
|
||||
const components = import.meta.glob('./**/*.vue')
|
||||
export default function install (app) {
|
||||
for (const [key, value] of Object.entries(components)) {
|
||||
const name = key.substring(key.lastIndexOf('/') + 1, key.lastIndexOf('.'))
|
||||
app.component(name, defineAsyncComponent(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<el-form
|
||||
ref="dataForm"
|
||||
:rules="rules"
|
||||
:model="formData"
|
||||
v-bind="form.props"
|
||||
>
|
||||
<el-row v-for="(row,i) in form.rows" :key="i" :gutter="row.gutter">
|
||||
<el-col v-for="(col,j) in row.cols" :key="j" :span="col.span" v-bind="col.colProps">
|
||||
<el-form-item :label="col.label" :label-width="col.labelWidth" :prop="col.name" v-bind="col.formItemProps">
|
||||
<component
|
||||
:is="!col.component ? 'mb-input' : col.component.startsWith('el-') ? col.component : 'mb-' + col.component"
|
||||
v-model="formData[col.name]"
|
||||
:label="col.label"
|
||||
v-bind="col.props"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, reactive, getCurrentInstance, defineExpose } from 'vue'
|
||||
const { proxy } = getCurrentInstance()
|
||||
const rules = reactive(getRules())
|
||||
const formData = ref(getFormData())
|
||||
const dataForm = ref()
|
||||
const props = defineProps({
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
detail: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['reload-table'])
|
||||
|
||||
props.form.props = props.form.props || {}
|
||||
proxy.$common.setDefaultValue(props.form.props, 'labelPosition', 'right')
|
||||
proxy.$common.setDefaultValue(props.form.props, 'labelWidth', '120px')
|
||||
|
||||
if(props.detail.formData){
|
||||
if(props.detail.handlerFormData){
|
||||
props.detail.handlerFormData(props.detail.formData)
|
||||
}
|
||||
formData.value = props.detail.formData
|
||||
}
|
||||
|
||||
if(props.detail.request){
|
||||
|
||||
}
|
||||
|
||||
function getRules(){
|
||||
var _rules = {}
|
||||
props.form.rows.forEach(row => {
|
||||
row.cols.forEach(col => {
|
||||
if (col.rules) {
|
||||
_rules[col.name] = col.rules
|
||||
}
|
||||
})
|
||||
})
|
||||
return _rules
|
||||
}
|
||||
|
||||
function getFormData() {
|
||||
var data = {}
|
||||
props.form.rows.forEach(row => {
|
||||
row.cols.forEach(col => {
|
||||
data[col.name] = col.defaultValue === null ? col.defaultValue : col.defaultValue || ''
|
||||
})
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
function save(d) {
|
||||
dataForm.value.validate((valid) => {
|
||||
if (valid) {
|
||||
d.loading()
|
||||
proxy.$post(props.form.request.url, formData.value).then(res => {
|
||||
d.hideLoading()
|
||||
proxy.$notify({
|
||||
title: '成功',
|
||||
message: (!formData.value.id ? '创建' : '修改') + '成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
if(props.detail.formData){
|
||||
props.detail.formData = {}
|
||||
}
|
||||
d.hide()
|
||||
emit('reload-table')
|
||||
}).catch(() => d.hideLoading())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getDetail(id) {
|
||||
formData.value.id = id
|
||||
proxy.$get(props.detail.request.url, { id: id }).then(res => {
|
||||
const { data } = res
|
||||
for (var t in formData.value) {
|
||||
if (data[t] && (!props.detail.excludeAssign || props.detail.excludeAssign.indexOf(t) === -1)) {
|
||||
formData.value[t] = data[t]
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ save, getDetail })
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<mb-search v-if="table.where" :where="table.where" :no-reset="search.noReset" @search="reload" />
|
||||
|
||||
<el-row class="toolbar-container">
|
||||
<div v-for="(it, i) in tools" :key="i">
|
||||
<el-button v-if="it.type == 'add'" v-permission="it.permission" class="filter-item" type="primary" icon="ElPlus" @click="it.click">
|
||||
{{ it.label || '添加' }}
|
||||
</el-button>
|
||||
<mb-button v-if="it.type == 'delete'" v-permission="it.permission" :el="{ plain: true }" :request-url="it.url" :btn-type="'delete'" :request-data="{ id: ids }" :after-handler="reload" />
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<mb-table ref="tableRef" v-bind="table" @selection-change="selectionChange" />
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, defineExpose } from 'vue'
|
||||
const tableRef = ref()
|
||||
const ids = ref([])
|
||||
|
||||
const props = defineProps({
|
||||
search: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
tools: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
table: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
})
|
||||
|
||||
props.tools.forEach(it => {
|
||||
if(it.type == 'delete'){
|
||||
props.table.selection = true
|
||||
}
|
||||
})
|
||||
|
||||
function reload(){
|
||||
tableRef.value.reloadList()
|
||||
}
|
||||
|
||||
function selectionChange(columns) {
|
||||
ids.value = columns.map(it => it['id']).join(',')
|
||||
}
|
||||
|
||||
defineExpose({ reload })
|
||||
|
||||
</script>
|
||||
+22
-29
@@ -9,6 +9,7 @@
|
||||
|
||||
<script>
|
||||
import { getToken } from '@/scripts/auth'
|
||||
import {ElNotification} from "element-plus";
|
||||
|
||||
export default {
|
||||
name: 'MbButton',
|
||||
@@ -70,11 +71,11 @@ export default {
|
||||
created() {
|
||||
if (this.btnType) {
|
||||
if (this.btnType === 'delete') {
|
||||
this.requestMethod_ = 'post'
|
||||
this.requestMethod_ = 'delete'
|
||||
this.el_.type = 'danger'
|
||||
this.el_.text = '删除'
|
||||
this.el_.icon = 'ElDelete'
|
||||
this.beforeConfirm_ = '确定删除吗?'
|
||||
this.beforeConfirm_ = '此操作将永久删除该数据, 是否继续?'
|
||||
this.successTips_ = '删除成功!'
|
||||
this.failTips_ = '删除失败!'
|
||||
}
|
||||
@@ -109,33 +110,25 @@ export default {
|
||||
})
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.requestMethod_ === 'get') {
|
||||
this.$get(this.requestUrl, this.requestData).then(res => {
|
||||
const { data } = res
|
||||
if (data) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: this.successTips_
|
||||
})
|
||||
} else {
|
||||
this.$message.error(this.failTips_)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
} else {
|
||||
this.$post(this.requestUrl, this.requestData).then(res => {
|
||||
const { data } = res
|
||||
if (data) {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: this.successTips_
|
||||
})
|
||||
} else {
|
||||
this.$message.error(this.failTips_)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
this.$request({
|
||||
url: this.requestUrl,
|
||||
method: this.requestMethod_,
|
||||
params: this.requestData,
|
||||
data: this.requestData
|
||||
}).then(res => {
|
||||
const { data } = res
|
||||
if (data) {
|
||||
ElNotification({
|
||||
title: '成功',
|
||||
message: this.successTips_,
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
} else {
|
||||
this.$message.error(this.failTips_)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<el-date-picker
|
||||
v-model="modelValue"
|
||||
:type="type"
|
||||
:format="format"
|
||||
:value-format="valueFormat"
|
||||
:placeholder="placeholder"
|
||||
:start-placeholder="startPlaceholder"
|
||||
:end-placeholder="endPlaceholder"
|
||||
v-bind="props.props"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { watch } from 'vue'
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const props = defineProps({
|
||||
modelValue: String,
|
||||
type: String,
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择时间'
|
||||
},
|
||||
format: {
|
||||
type: String,
|
||||
default: 'yyyy-MM-dd'
|
||||
},
|
||||
valueFormat: {
|
||||
type: String,
|
||||
default: 'yyyy-MM-dd'
|
||||
},
|
||||
startPlaceholder: {
|
||||
type: String,
|
||||
default: '开始时间'
|
||||
},
|
||||
endPlaceholder: {
|
||||
type: String,
|
||||
default: '结束时间'
|
||||
},
|
||||
props: Object
|
||||
})
|
||||
watch(() => props.modelValue, (value) => {
|
||||
emit('update:modelValue', value)
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<el-input v-model="modelValue" :type="type" :value="value" :placeholder="placeholder || (label && '请输入' + label)" v-bind="props.props" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { watch } from 'vue'
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const props = defineProps({
|
||||
modelValue: String,
|
||||
label: String,
|
||||
placeholder: String,
|
||||
value: String,
|
||||
type: String,
|
||||
props: Object
|
||||
})
|
||||
watch(() => props.modelValue, (value) => {
|
||||
emit('update:modelValue', value)
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<el-radio-group v-model="modelValue" v-bind="props.props">
|
||||
<el-radio-button v-for="it in options" :label="it.value" :disabled="it.disabled" :name="it.disabled">{{ it.label }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { watch } from 'vue'
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const props = defineProps({
|
||||
modelValue: String,
|
||||
options: Array
|
||||
})
|
||||
watch(() => props.modelValue, (value) => {
|
||||
emit('update:modelValue', value)
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
|
||||
</template>
|
||||
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div class="filter-container">
|
||||
<el-form :inline="true" @keyup.enter="search">
|
||||
<span v-for="(it, i) in where">
|
||||
<el-form-item v-if="it && it.label" :label="it.label" :key="i">
|
||||
<el-input v-if="!it.type || it.type == 'input'" @input="input(it.input)" v-model="it.value" :placeholder="it.placeholder || ('请输入' + it.label)" style="width: 200px;" class="filter-item" />
|
||||
<mb-select v-else-if="it.type == 'select'" v-model="it.value" :placeholder="'请选择' + it.label" v-bind="it.properties" />
|
||||
<el-date-picker
|
||||
v-else-if="it.type == 'date' || it.type == 'datetime' || it.type == 'daterange' || it.type == 'datetimerange'"
|
||||
v-model="it.value"
|
||||
align="right"
|
||||
:format="it.type.startsWith('datetime') ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'"
|
||||
:value-format="it.type.startsWith('datetime') ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'"
|
||||
:type="it.type"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
:placeholder="it.type.startsWith('datetime') ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'"
|
||||
>
|
||||
</el-date-picker>
|
||||
<component v-else :is="it.type" v-model="it.value" v-bind="it.properties" />
|
||||
</el-form-item>
|
||||
</span>
|
||||
<el-form-item>
|
||||
<el-button class="filter-item" type="primary" icon="ElSearch" @click="search">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button class="filter-item" icon="ElDelete" @click="reset">
|
||||
清空
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<slot name="btns" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { nextTick, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
where: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
notReset: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
for(var key in props.where){
|
||||
if(props.where[key] instanceof Object && props.where[key].value == undefined){
|
||||
props.where[key].value = null
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => props.where,() => {
|
||||
console.log(props.where)
|
||||
})
|
||||
|
||||
const emit = defineEmits(['search'])
|
||||
|
||||
function input(input){
|
||||
if(input){
|
||||
emit('search')
|
||||
}
|
||||
}
|
||||
|
||||
function search(){
|
||||
for(var key in props.where){
|
||||
if(props.where[key] instanceof Object){
|
||||
if(props.where[key].type && props.where[key].type.startsWith('date') && props.where[key].value instanceof Array){
|
||||
props.where[key].value = props.where[key].value.join(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
emit('search')
|
||||
for(var key in props.where){
|
||||
if(props.where[key] instanceof Object){
|
||||
if(props.where[key].type && props.where[key].type.startsWith('date')){
|
||||
props.where[key].value = props.where[key].value.split(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function reset() {
|
||||
for(var key in props.where){
|
||||
if(props.notReset.indexOf(key) == -1){
|
||||
if(props.where[key] instanceof Object){
|
||||
props.where[key].value = null
|
||||
}else{
|
||||
props.where[key] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
nextTick(() => emit('search'))
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<el-switch
|
||||
v-model="modelValue"
|
||||
:active-value="activeValue"
|
||||
:inactive-value="inactiveValue"
|
||||
v-bind="props.props"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { watch } from 'vue'
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const props = defineProps({
|
||||
modelValue: String,
|
||||
activeValue: String,
|
||||
inactiveValue: String,
|
||||
props: Object
|
||||
})
|
||||
watch(() => props.modelValue, (value) => {
|
||||
emit('update:modelValue', value)
|
||||
})
|
||||
</script>
|
||||
+3
-2
@@ -83,7 +83,7 @@ const props = defineProps({
|
||||
},
|
||||
method: {
|
||||
type: String,
|
||||
default: 'get'
|
||||
default: 'post'
|
||||
},
|
||||
cols: {
|
||||
type: Array,
|
||||
@@ -121,7 +121,8 @@ function getList() {
|
||||
request({
|
||||
url: props.url,
|
||||
method: props.method,
|
||||
params: newWhere
|
||||
params: newWhere,
|
||||
data: newWhere
|
||||
}).then(res => {
|
||||
const { data } = res
|
||||
total.value = data.total
|
||||
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<treeselect v-model="modelValue" :options="options" :key="modelValue" :placeholder="placeholder || (label && '请选择' + label)" :show-count="true" v-bind="props.props" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, getCurrentInstance } from "vue";
|
||||
const { proxy } = getCurrentInstance()
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
url: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
},
|
||||
label: String,
|
||||
placeholder: String,
|
||||
props: Object
|
||||
})
|
||||
|
||||
const options = ref([])
|
||||
|
||||
proxy.$get(props.url).then(res => {
|
||||
options.value = res.data.list
|
||||
proxy.$treeTable.deleteEmptyChildren(options.value)
|
||||
})
|
||||
|
||||
</script>
|
||||
+1
-1
@@ -137,7 +137,7 @@ export default {
|
||||
this.$emit('update:modelValue', '')
|
||||
this.$emit('change', '')
|
||||
}
|
||||
this.$get('file/delete', { url: encodeURI(url) })
|
||||
this.$delete('file/delete', { url: encodeURI(url) })
|
||||
},
|
||||
handlePreview(file) {
|
||||
window.open(this.$global.filePrefix + file.response.data.url)
|
||||
+1
-1
@@ -179,7 +179,7 @@ export default {
|
||||
this.fileList.splice(i, 1)
|
||||
}
|
||||
})
|
||||
this.$get('file/delete', { url: encodeURI(url) })
|
||||
this.$delete('file/delete', { url: encodeURI(url) })
|
||||
if (this.multiple) {
|
||||
this.$emit('update:modelValue', this.urls)
|
||||
this.$emit('change', this.urls)
|
||||
@@ -1,100 +0,0 @@
|
||||
<template>
|
||||
<div class="filter-container">
|
||||
<el-form :inline="true" @keyup.enter="search">
|
||||
<el-form-item :label="it.label" v-for="(it, i) in where" :key="i">
|
||||
<el-input v-if="it.type == 'input'" @input="input(it.input)" v-model="it.value" :placeholder="it.placeholder || ('请输入' + it.label)" style="width: 200px;" class="filter-item" />
|
||||
<mb-select v-else-if="it.type == 'select'" v-model="it.value" :placeholder="'请输入' + it.label" v-bind="it.properties" />
|
||||
<el-date-picker
|
||||
v-else-if="it.type == 'date' || it.type == 'datetime' || it.type == 'daterange' || it.type == 'datetimerange'"
|
||||
v-model="it.value"
|
||||
align="right"
|
||||
:format="it.type.startsWith('datetime') ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'"
|
||||
:value-format="it.type.startsWith('datetime') ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'"
|
||||
:type="it.type"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
:placeholder="it.type.startsWith('datetime') ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'"
|
||||
>
|
||||
</el-date-picker>
|
||||
<component v-else :is="it.type" v-model="it.value" v-bind="it.properties" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="filter-item" type="primary" icon="ElSearch" @click="search">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button class="filter-item" icon="ElDelete" @click="reset">
|
||||
清空
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<slot name="btns" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
import { nextTick, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
where: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
notReset: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.where,() => {
|
||||
console.log(props.where)
|
||||
})
|
||||
|
||||
const emit = defineEmits(['search'])
|
||||
|
||||
function input(input){
|
||||
if(input){
|
||||
emit('search')
|
||||
}
|
||||
}
|
||||
|
||||
function search(){
|
||||
for(var key in props.where){
|
||||
if(props.where[key] instanceof Object){
|
||||
if(props.where[key].type.startsWith('date') && props.where[key].value instanceof Array){
|
||||
props.where[key].value = props.where[key].value.join(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
emit('search')
|
||||
for(var key in props.where){
|
||||
if(props.where[key] instanceof Object){
|
||||
if(props.where[key].type.startsWith('date')){
|
||||
props.where[key].value = props.where[key].value.split(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function reset() {
|
||||
for(var key in props.where){
|
||||
if(props.notReset.indexOf(key) == -1){
|
||||
if(props.where[key] instanceof Object){
|
||||
props.where[key].value = null
|
||||
}else{
|
||||
props.where[key] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
nextTick(() => emit('search'))
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user