新建单位页面

main
GaoF 2024-07-24 10:48:33 +08:00
parent a9ecf25877
commit 0b32cab220
9 changed files with 656 additions and 58 deletions

View File

@ -0,0 +1,28 @@
import { baseRequest } from '@/utils/request'
const request = (url, ...arg) => baseRequest(`/base/sysunit/` + url, ...arg)
/**
* 单位Api接口管理器
*
* @author Luck
* @date 2024/07/23 11:36
**/
export default {
// 获取单位分页
sysUnitPage(data) {
return request('page', data, 'get')
},
// 提交单位表单 edit为true时为编辑默认为新增
sysUnitSubmitForm(data, edit = false) {
return request(edit ? 'edit' : 'add', data)
},
// 删除单位
sysUnitDelete(data) {
return request('delete', data)
},
// 获取单位详情
sysUnitDetail(data) {
return request('detail', data, 'get')
}
}

View File

@ -0,0 +1,49 @@
<template>
<xn-form-container
:title="formData.id ? '编辑单位组' : '增加单位组'"
:width="700"
:visible="visible"
:destroy-on-close="true"
@close="onClose"
>
<dynamic-form></dynamic-form>
<template #footer>
<a-button style="margin-right: 8px" @click="onClose"></a-button>
<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
</template>
</xn-form-container>
</template>
<script setup>
// const props = defineProps({})
// const emit = defineEmits()
const submitLoading = ref(false)
//
const onClose = () => {}
//
const onSubmit = () => {}
//
onMounted(() => {
console.log('Component mounted')
// TODO: Add your onMounted code here
})
onUpdated(() => {
console.log('Component updated')
// TODO: Add your onUpdated code here
})
onUnmounted(() => {
console.log('Component unmounted')
// TODO: Add your onUnmounted code here
})
// watch(() => {}, () => {})
</script>
<style scoped></style>

View File

@ -0,0 +1,76 @@
<template>
<a-form ref="formRef" :model="formData" :rules="formRules" layout="horizontal">
<a-row :gutter="16">
<a-col v-for="field in fields" :key="field.name" :span="12" v-show="!field.advanced || advanced">
<a-form-item :label="field.label" :name="field.name">
<component
:is="getComponent(field.type)"
v-model:value="formData[field.name]"
v-bind="field.options"
:placeholder="field.placeholder"
:allow-clear="field.allowClear"
/>
</a-form-item>
</a-col>
</a-row>
</a-form>
</template>
<script setup>
//
const props = defineProps({
fields: {
type: Array,
required: true
},
formData: {
type: Object,
required: true
},
formRules: {
type: Object,
default: () => ({})
}
})
const emit = defineEmits(['submit', 'reset'])
//
const formRef = ref(null)
//
const advanced = ref(false)
//
const toggleAdvanced = () => {
advanced.value = !advanced.value
}
//
const onSubmit = () => {
formRef.value.validate((valid) => {
if (valid) {
emit('submit', formData)
} else {
console.log('表单验证失败')
}
})
}
//
const onReset = () => {
formRef.value.resetFields()
emit('reset')
}
//
const getComponent = (type) => {
const componentMap = {
input: 'a-input',
select: 'a-select',
radio: 'a-radio-group',
switch: 'a-switch'
}
return componentMap[type] || 'a-input'
}
</script>

View File

@ -0,0 +1,98 @@
<!-- DynamicForm.vue -->
<template>
<a-card :bordered="false">
<a-form ref="searchFormRef" name="advanced_search" :model="formState" class="ant-advanced-search-form">
<a-row :gutter="24">
<a-col v-for="(field, index) in fields" :key="index" :span="6" v-show="!field.advanced || advanced">
<a-form-item :label="field.label" :name="field.name">
<component
:is="getComponent(field)"
v-model:value="formState[field.name]"
:placeholder="field.placeholder"
:options="field.options"
/>
</a-form-item>
</a-col>
<a-col :span="6">
<a-button type="primary" @click="onSearch"></a-button>
<a-button style="margin: 0 8px" @click="reset"></a-button>
<a @click="toggleAdvanced" style="margin-left: 8px">
{{ advanced ? '收起' : '展开' }}
<component :is="advanced ? 'up-outlined' : 'down-outlined'" />
</a>
</a-col>
</a-row>
</a-form>
</a-card>
</template>
<script setup>
import { ref, defineProps, defineEmits, onMounted, onUpdated, onUnmounted, watch } from 'vue'
const props = defineProps({
fields: {
type: Array,
required: true,
default: () => []
}
})
const emit = defineEmits(['update:modelValue', 'search'])
const searchFormRef = ref(null)
const formState = ref({})
const advanced = ref(false)
const reset = () => {
formState.value = { ...props.modelValue }
emit('update:modelValue', formState.value)
}
const onSearch = () => {
emit('search', formState.value)
}
const toggleAdvanced = () => {
advanced.value = !advanced.value
}
const getComponent = (field) => {
switch (field.type) {
case 'input':
return 'a-input'
case 'select':
return 'a-select'
default:
return 'a-input'
}
}
//
onMounted(() => {
console.log('Component mounted')
})
onUpdated(() => {
console.log('Component updated')
})
onUnmounted(() => {
console.log('Component unmounted')
})
const extractNamesAsObject = (fields) => {
return fields.reduce((acc, field) => {
acc[field.name] = field // field.name field
return acc
}, {})
}
watch(
() => props.fields,
(newVal) => {
formState.value = { ...extractNamesAsObject(newVal) }
}
)
</script>
<style scoped></style>

View File

@ -11,6 +11,45 @@
<a-checkbox :checked="data.localSettings.rowClassNameSwitch" @change="changeRowClass"> </a-checkbox>
</div>
<span v-for="item in tool" :key="item.name">
<!-- 新增 -->
<a-tooltip
v-if="item.name === 'plus' && props.toolConfig.plus"
:title="item.title"
class="s-tool-item"
@click="
() => {
emit('plusRowData')
}
"
>
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 修改 -->
<a-tooltip
v-if="item.name === 'edit' && props.toolConfig.edit"
:title="item.title"
class="s-tool-item"
@click="
() => {
emit('editRowData')
}
"
>
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 删除 -->
<a-tooltip
v-if="item.name === 'delete' && props.toolConfig.delete"
:title="item.title"
class="s-tool-item"
@click="
() => {
emit('deleteRowData')
}
"
>
<component class="icons" :is="item.icon"></component>
</a-tooltip>
<!-- 刷新 -->
<a-tooltip
v-if="item.name === 'refresh' && props.toolConfig.refresh"
@ -124,7 +163,7 @@
import { get } from 'lodash-es'
const slots = useSlots()
const route = useRoute()
const emit = defineEmits(['expand'])
const emit = defineEmits(['expand', 'plusRowData', 'editRowData', 'deleteRowData'])
const renderSlots = Object.keys(slots)
const props = defineProps(
@ -134,7 +173,7 @@
default: 'key'
},
data: {
type: Function,
type: [Function, Array],
required: true
},
pageNum: {
@ -189,6 +228,9 @@
toolConfig: {
type: Object,
default: () => ({
plus: false,
edit: false,
delete: false,
refresh: false,
height: false,
columnSetting: false,
@ -245,6 +287,21 @@
const renderTableProps = ref([])
//
const tool = [
{
name: 'plus',
icon: 'plus-outlined',
title: '新增'
},
{
name: 'edit',
icon: 'edit-outlined',
title: '编辑'
},
{
name: 'delete',
icon: 'delete-outlined',
title: '删除'
},
{
name: 'refresh',
icon: 'sync-outlined',
@ -365,9 +422,17 @@
}
)
//
console.log(typeof props.data, 'typeof props.data')
if (typeof props.data !== 'function') {
data.localLoading = false
data.localDataSource = props.data
getTableProps()
} else {
const result = props.data(parameter)
if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') {
result.then((r) => {
result
.then((r) => {
if (r == null) {
data.localLoading = false
return
@ -423,6 +488,7 @@
})
}
}
}
// tableprops
const getTableProps = () => {
@ -502,7 +568,8 @@
...renderProps,
size: data.customSize, // sizea-tablecompSize
columns: data.columnsSetting.filter((value) => value.checked === undefined || value.checked),
...data.localSettings
...data.localSettings,
scroll: {x: 100, y: 1000}
}
// undefined null tableprops
renderTableProps.value = Object.entries(renderProps).reduce((x, [y, z]) => (z == null ? x : ((x[y] = z), x)), {})
@ -571,7 +638,20 @@
})
onMounted(() => {
init()
window.addEventListener('resize', () => {
console.log('屏幕发生变换')
})
})
onBeforeUnmount(() => {
window.removeEventListener('resize', () => {
console.log('屏幕发生变换')
});
});
</script>
<style lang="less" scoped>
.s-table-tool {

View File

@ -0,0 +1,10 @@
export const unitGroupColumns = [
{
title: '名称',
dataIndex: 'name'
},
{
title: '状态',
dataIndex: 'state'
},
]

View File

@ -0,0 +1,29 @@
<template>
<div></div>
</template>
<script setup>
// const props = defineProps({})
// const emit = defineEmits()
//
onMounted(() => {
console.log('Component mounted')
// TODO: Add your onMounted code here
})
onUpdated(() => {
console.log('Component updated')
// TODO: Add your onUpdated code here
})
onUnmounted(() => {
console.log('Component unmounted')
// TODO: Add your onUnmounted code here
})
// watch(() => {}, () => {})
</script>
<style scoped></style>

View File

@ -0,0 +1,26 @@
export const SearchFields = [
{ label: '名称', name: 'name', type: 'input', placeholder: '请输入名称' },
{
label: '状态',
name: 'state',
type: 'select',
placeholder: '请选择状态',
options: [
{ label: 'Active', value: 'active' },
{ label: 'Inactive', value: 'inactive' }
]
},
{ label: '编码', name: 'number', type: 'input', placeholder: '请输入编码' },
{
label: '是否基本单位',
name: 'isBase',
type: 'select',
placeholder: '请选择是否基本单位',
options: [
{ label: '是', value: true },
{ label: '否', value: false }
],
advanced: true
},
{ label: '单位组id', name: 'unitGroupId', type: 'input', placeholder: '请输入单位组id', advanced: true }
]

View File

@ -0,0 +1,202 @@
<template>
<search-form :fields="SearchFields" @search="handleSearch" @rest="reset"></search-form>
<a-card class="mt-4">
<a-row :gutter="20">
<a-col :span="8">
<s-table
:alert="false"
:columns="unitGroupColumns"
:data="loadData"
bordered
:row-key="(record) => record.id"
:tool-config="{
plus: true,
edit: true,
delete: true,
refresh: true,
height: true,
columnSetting: true,
striped: false
}"
:row-selection="options.rowSelection"
@plusRowData="handlePlusRowData"
@editRowData="handleEditRowData"
@deleteRowData="handleDeleteRowData"
>
<template #operator class="table-operator">
<a-space>
<span>单位组</span>
</a-space>
</template>
</s-table>
</a-col>
<a-col :span="16">
<s-table
ref="tableRef"
:columns="columns"
:data="loadData"
:alert="options.alert.show"
bordered
:row-key="(record) => record.id"
:tool-config="toolConfig"
:row-selection="options.rowSelection"
>
<template #operator class="table-operator">
<a-space>
<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('sysUnitAdd')">
<template #icon><plus-outlined /></template>
新增
</a-button>
<xn-batch-delete
v-if="hasPerm('sysUnitBatchDelete')"
:selectedRowKeys="selectedRowKeys"
@batchDelete="deleteBatchSysUnit"
/>
</a-space>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'state'">
{{ $TOOL.dictTypeData('COMMON_STATUS', record.state) }}
</template>
<template v-if="column.dataIndex === 'isBase'">
{{ $TOOL.dictTypeData('YES_NO', record.isBase) }}
</template>
<template v-if="column.dataIndex === 'action'">
<a-space>
<a @click="formRef.onOpen(record)" v-if="hasPerm('sysUnitEdit')"></a>
<a-divider type="vertical" v-if="hasPerm(['sysUnitEdit', 'sysUnitDelete'], 'and')" />
<a-popconfirm title="确定要删除吗?" @confirm="deleteSysUnit(record)">
<a-button type="link" danger size="small" v-if="hasPerm('sysUnitDelete')"></a-button>
</a-popconfirm>
</a-space>
</template>
</template>
</s-table>
</a-col>
</a-row>
</a-card>
</template>
<script setup name="sysunit">
import tool from '@/utils/tool'
import { cloneDeep } from 'lodash-es'
import sysUnitApi from '@/api/baseData/unit/unitApi'
import { unitGroupColumns } from '@/views/basicData/unit/columns/unitGroupColumns'
import { SearchFields } from '@/views/basicData/unit/formData/SearchForm'
const searchFormState = ref({})
const searchFormRef = ref()
const tableRef = ref()
const formRef = ref()
const toolConfig = {
refresh: true,
height: true,
columnSetting: true,
striped: false
}
//
const advanced = ref(false)
const toggleAdvanced = () => {
advanced.value = !advanced.value
}
const columns = [
{
title: '名称',
dataIndex: 'name'
},
{
title: '状态',
dataIndex: 'state'
},
{
title: '编码',
dataIndex: 'number'
},
{
title: '换算率',
dataIndex: 'rate'
},
{
title: '是否基本单位',
dataIndex: 'isBase'
},
{
title: '精度',
dataIndex: 'precision'
},
{
title: '单位组id',
dataIndex: 'unitGroupId'
}
]
//
if (hasPerm(['sysUnitEdit', 'sysUnitDelete'])) {
columns.push({
title: '操作',
dataIndex: 'action',
align: 'center',
width: 150
})
}
const selectedRowKeys = ref([])
//
const options = {
// columns needTotal: true
alert: {
show: true,
clear: () => {
selectedRowKeys.value = ref([])
}
},
rowSelection: {
onChange: (selectedRowKey, selectedRows) => {
selectedRowKeys.value = selectedRowKey
}
}
}
const loadData = (parameter) => {
const searchFormParam = cloneDeep(searchFormState.value)
return sysUnitApi.sysUnitPage(Object.assign(parameter, searchFormParam)).then((data) => {
return data
})
}
//
const handleSearch = () => {}
//
const reset = () => {
searchFormRef.value.resetFields()
tableRef.value.refresh(true)
}
//
const deleteSysUnit = (record) => {
let params = [
{
id: record.id
}
]
sysUnitApi.sysUnitDelete(params).then(() => {
tableRef.value.refresh(true)
})
}
//
const deleteBatchSysUnit = (params) => {
sysUnitApi.sysUnitDelete(params).then(() => {
tableRef.value.clearRefreshSelected()
})
}
const stateOptions = tool.dictList('COMMON_STATUS')
const isBaseOptions = tool.dictList('YES_NO')
// //
const handlePlusRowData = () => {
formRef.value.onOpen()
}
const handleEditRowData = () => {
formRef.value.onOpen()
}
const handleDeleteRowData = () => {}
</script>