feat:组织机构-添加API授权相关

feature-JimuReport-1106-yjl
yujinlong 4 weeks ago
parent fbfe6d1cd4
commit a3d315ec86

@ -12,6 +12,10 @@ enum Api {
GetBankList = '/mainApi/Bank/GetBankList', GetBankList = '/mainApi/Bank/GetBankList',
EditBank = '/mainApi/Bank/EditBank', EditBank = '/mainApi/Bank/EditBank',
GetBankInfo = '/mainApi/Bank/GetBankInfo', GetBankInfo = '/mainApi/Bank/GetBankInfo',
OrgAuthList = '/mainApi/OrgAuth/GetOrgAuthList',
GetOrgAuthInfo = '/mainApi/OrgAuth/GetOrgAuthInfo',
EditOrgAuth = '/mainApi/OrgAuth/EditOrgAuth',
DelOrgAuth = '/mainApi/OrgAuth/BatchDelOrgAuth'
} }
export function getOrgList(data: PageRequest) { export function getOrgList(data: PageRequest) {
return request<DataResult>({ return request<DataResult>({
@ -35,7 +39,7 @@ export function getOrgInfo(query: { id: string }) {
params: query, params: query,
}) })
} }
export function getOrgTree(query: { id: string }) { export function getOrgTree(query: { id?: string }) {
return request<DataResult>({ return request<DataResult>({
url: Api.GetOrgTree, url: Api.GetOrgTree,
method: 'get', method: 'get',
@ -80,3 +84,39 @@ export function BatchDelOrg(data: any) {
data, data,
}) })
} }
// 组织机构授权列表
export function getOrgAuthList(data: any) {
return request<DataResult>({
url: Api.OrgAuthList,
method: 'post',
data,
})
}
// 组织机构授权编辑
export function editOrgAuth(data: any) {
return request<DataResult>({
url: Api.EditOrgAuth,
method: 'post',
data,
})
}
// 组织机构授权详情
export function getOrgAuthInfo(query: { id: string }) {
return request<DataResult>({
url: Api.GetOrgAuthInfo,
method: 'get',
params: query,
})
}
// 组织机构授权删除
export function BatchDelOrgAuth(data: any) {
return request<DataResult>({
url: Api.DelOrgAuth,
method: 'post',
data,
})
}

@ -26,7 +26,7 @@ declare namespace API {
/** 全局通用表格分页请求参数 */ /** 全局通用表格分页请求参数 */
type PageRequest = { type PageRequest = {
queryCondition: string; queryCondition: string;
otherQueryCondition:string; otherQueryCondition: string;
pageCondition: PageCondition; pageCondition: PageCondition;
}; };
type PageCondition = { type PageCondition = {

@ -11,7 +11,7 @@
:full-screen="fullScreenRef" :full-screen="fullScreenRef"
:form-schema="getProps.formSchema" :form-schema="getProps.formSchema"
@cancel="handleCancel" @cancel="handleCancel"
@fullscreen="handleFullScreen" @fullscreen="handleFullScreenHandle"
/> />
</template> </template>
<template v-if="!$slots.title" #title> <template v-if="!$slots.title" #title>
@ -84,7 +84,15 @@
components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader }, components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader },
inheritAttrs: false, inheritAttrs: false,
props: basicProps, props: basicProps,
emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register', 'update:visible'], emits: [
'visible-change',
'height-change',
'cancel',
'ok',
'register',
'update:visible',
'fullscreenChange',
],
setup(props, { emit, attrs }) { setup(props, { emit, attrs }) {
const visibleRef = ref(false) const visibleRef = ref(false)
const propsRef = ref<Partial<ModalProps> | null>(null) const propsRef = ref<Partial<ModalProps> | null>(null)
@ -225,11 +233,16 @@
handleFullScreen(e) handleFullScreen(e)
} }
function handleFullScreenHandle(e) {
handleFullScreen(e)
emit('fullscreenChange', fullScreenRef.value)
}
return { return {
handleCancel, handleCancel,
getBindValue, getBindValue,
getProps, getProps,
handleFullScreen, handleFullScreenHandle,
fullScreenRef, fullScreenRef,
getMergeProps, getMergeProps,
handleOk, handleOk,

@ -39,7 +39,7 @@
FullscreenOutlined, FullscreenOutlined,
CloseOutlined, CloseOutlined,
DiffOutlined, DiffOutlined,
CopyrightOutlined CopyrightOutlined,
} from '@ant-design/icons-vue' } from '@ant-design/icons-vue'
import { useDesign } from '/@/hooks/web/useDesign' import { useDesign } from '/@/hooks/web/useDesign'
import { Tooltip } from 'ant-design-vue' import { Tooltip } from 'ant-design-vue'
@ -58,7 +58,7 @@
FullscreenOutlined, FullscreenOutlined,
CloseOutlined, CloseOutlined,
DiffOutlined, DiffOutlined,
CopyrightOutlined CopyrightOutlined,
}, },
props: { props: {
canFullscreen: { type: Boolean, default: true }, canFullscreen: { type: Boolean, default: true },
@ -67,8 +67,8 @@
type: Array, type: Array,
default: () => { default: () => {
return [] return []
} },
} },
}, },
emits: ['cancel', 'fullscreen'], emits: ['cancel', 'fullscreen'],
setup(props, { emit }) { setup(props, { emit }) {
@ -91,7 +91,7 @@
function handleFullScreen(e: Event) { function handleFullScreen(e: Event) {
e?.stopPropagation() e?.stopPropagation()
e?.preventDefault() e?.preventDefault()
emit('fullscreen') emit('fullscreen', e)
} }
// //
const copyFormToSet = () => { const copyFormToSet = () => {
@ -99,7 +99,7 @@
const res = { const res = {
field: item.field || '', field: item.field || '',
label: item.label || '', label: item.label || '',
enLabel: item.enLabel || '' enLabel: item.enLabel || '',
} }
return res return res
}) })
@ -110,10 +110,10 @@
permissionName: permissionsInfo().permissionName, permissionName: permissionsInfo().permissionName,
copyFields: '', copyFields: '',
content: JSON.stringify({ content: JSON.stringify({
columns: columns columns: columns,
}) }),
} }
EditFormCopy(Apidata).then(res => { EditFormCopy(Apidata).then((res) => {
if (res.succeeded) { if (res.succeeded) {
createMessage.success('添加成功!') createMessage.success('添加成功!')
} }
@ -128,7 +128,7 @@
label: item.label || null, label: item.label || null,
required: item.required || false, required: item.required || false,
colProps: item.colProps || { span: 24 }, colProps: item.colProps || { span: 24 },
component: item.component component: item.component,
} }
// //
if (item.show !== false) { if (item.show !== false) {
@ -146,10 +146,10 @@
templateName: permissionsInfo().permissionName, templateName: permissionsInfo().permissionName,
permissionName: permissionsInfo().permissionName, permissionName: permissionsInfo().permissionName,
content: JSON.stringify({ content: JSON.stringify({
columns: columns columns: columns,
}) }),
} }
editCodeGoodsType(Apidata).then(res => { editCodeGoodsType(Apidata).then((res) => {
if (res.succeeded) { if (res.succeeded) {
createMessage.success('添加成功!') createMessage.success('添加成功!')
} }

@ -0,0 +1,113 @@
<template>
<BasicModal
v-bind="$attrs"
:use-wrapper="true"
:title="getTitle"
width="50%"
@register="registerModal"
@ok="handleSave"
>
<BasicForm @register="registerForm">
<template #status="item">
<a-switch @change="changeStatus" v-model:checked="item.values.status" />
<span class="s-txt" :class="{ 's-active': item.values.status }">
{{ item.values.status ? '启用' : '禁用' }}
</span>
</template>
</BasicForm>
<!--右下角按钮-->
<template #footer>
<a-button type="default" :loading="loading" @click="closeModal"></a-button>
<a-button type="primary" :loading="loading" @click="handleSave(true)"></a-button>
</template>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue'
import { BasicModal, useModalInner } from '/@/components/Modal'
import { BasicForm, useForm } from '/@/components/Form/index'
import { APIformSchema } from './columns'
import { editOrgAuth, getOrgAuthInfo } from '/@/api/system/org'
import { useMessage } from '/@/hooks/web/useMessage'
// Emits
const emit = defineEmits(['success', 'register'])
const isUpdate = ref(true)
const loading = ref(false)
const rowId = ref('')
const linkId = ref('')
const { createMessage } = useMessage()
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 100,
schemas: APIformSchema,
showActionButtonGroup: false,
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields()
setModalProps({ confirmLoading: false, loading: true })
isUpdate.value = !!data?.isUpdate
linkId.value = data.linkId ? data.linkId : ''
if (unref(isUpdate)) {
rowId.value = data.record.id ? data.record.id : data.record.value
const res: API.DataResult = await getOrgAuthInfo({ id: unref(rowId) })
if (res.data.status == 1) {
res.data.status = false
} else {
res.data.status = true
}
if (res.succeeded) {
setFieldsValue({
...res.data,
})
}
} else {
setFieldsValue({ permissionIdentity: unref(2) })
console.log(data.orgFullName)
if (data.orgFullName) setFieldsValue({ accountName: data.orgFullName })
}
setModalProps({ loading: false })
})
const getTitle = computed(() => (!unref(isUpdate) ? '新增API授权' : '编辑API授权'))
const changeStatus = (v) => {
setFieldsValue({ status: v })
}
async function handleSave(exit) {
try {
const values = await validate()
setModalProps({ confirmLoading: true, loading: true })
values.linkId = values.linkId ? values.linkId : linkId.value
if (values.status) {
values.status = 0
} else {
values.status = 1
}
const res: API.DataResult = await editOrgAuth(values)
if (res.succeeded) {
createMessage.success(res.message)
emit('success')
} else {
createMessage.error(res.message)
}
exit && closeModal()
} finally {
setModalProps({ confirmLoading: false, loading: false })
}
}
</script>
<style lang="less" scoped>
.s-txt {
font-size: 12px;
margin-left: 10px;
color: #7a8798;
position: relative;
top: 1px;
}
.s-active {
color: #257afa;
}
</style>

@ -5,6 +5,7 @@
width="60%" width="60%"
@register="registerModal" @register="registerModal"
@ok="handleSave" @ok="handleSave"
@fullscreenChange="handleFullscreen"
> >
<a-tabs @change="tabChange" v-model:activeKey="activeKey"> <a-tabs @change="tabChange" v-model:activeKey="activeKey">
<a-tab-pane key="0" tab="机构信息"> <a-tab-pane key="0" tab="机构信息">
@ -60,8 +61,33 @@
</template> </template>
</BasicTable> </BasicTable>
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="API授权" force-render>
<BasicTable @register="registerAPITable">
<template #tableTitle>
<h4 class="mr15" style="margin-bottom: 0">API授权</h4>
<a-button type="link" @click="AddAPIAuth">
<span class="iconfont icon-new_document"></span>
新增
</a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
icon: 'clarity:note-edit-line',
tooltip: '编辑',
onClick: EditAPIAuth.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
</a-tab-pane>
</a-tabs> </a-tabs>
<BankModal @register="registerBankModal" @success="handleSuccess" /> <BankModal @register="registerBankModal" @success="handleSuccess" />
<APIAuthModal @register="registerAPIModal" @success="handleSuccess" />
<!--右下角按钮--> <!--右下角按钮-->
<template #footer> <template #footer>
<a-button :loading="loading" @click="closeModal"></a-button> <a-button :loading="loading" @click="closeModal"></a-button>
@ -70,19 +96,19 @@
</BasicModal> </BasicModal>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, unref, h } from 'vue' import { ref, computed, unref, h, Ref, PropType } from 'vue'
import { BasicModal, useModalInner, useModal } from '/@/components/Modal' import { BasicModal, useModalInner, useModal } from '/@/components/Modal'
import { BasicForm, useForm } from '/@/components/Form/index' import { BasicForm, useForm } from '/@/components/Form/index'
import { BasicTable, useTable, TableAction } from '/@/components/Table' import { BasicTable, useTable, TableAction } from '/@/components/Table'
import { formSchema, BankColumns } from './columns' import { formSchema, BankColumns, APIColumns } from './columns'
import BankModal from './BankModal.vue' import BankModal from './BankModal.vue'
import { editOrg, getOrgInfo, getOrgTree, getBankList } from '/@/api/system/org' import APIAuthModal from './APIAuthModal.vue'
import { useUserStore } from '/@/store/modules/user' import { editOrg, getOrgInfo, getOrgTree, getBankList, getOrgAuthList } from '/@/api/system/org'
import { useMessage } from '/@/hooks/web/useMessage' import { useMessage } from '/@/hooks/web/useMessage'
import DsFile from '/@/components/File/index.vue' import DsFile from '/@/components/File/index.vue'
import { propTypes } from '/@/utils/propTypes' import { formatParams } from '/@/hooks/web/common'
const props = defineProps({ const props = defineProps({
ParentId: propTypes.object, ParentId: [Object, String] as PropType<Recordable | string>,
}) })
// Emits // Emits
const emit = defineEmits(['success', 'register']) const emit = defineEmits(['success', 'register'])
@ -106,6 +132,7 @@
rowId.value = '' rowId.value = ''
resetFields() resetFields()
reload() reload()
APIReload()
initData().then(async () => { initData().then(async () => {
setModalProps({ confirmLoading: false, loading: true }) setModalProps({ confirmLoading: false, loading: true })
isUpdate.value = !!data?.isUpdate isUpdate.value = !!data?.isUpdate
@ -123,6 +150,7 @@
...res.data, ...res.data,
}) })
reload() reload()
APIReload()
} }
} else { } else {
// //
@ -138,7 +166,7 @@
}) })
}) })
async function initData() { async function initData() {
const res: API.DataResult = await getOrgTree() const res: API.DataResult = await getOrgTree({})
if (res.succeeded) { if (res.succeeded) {
res.data.unshift({ res.data.unshift({
title: '最外层机构', title: '最外层机构',
@ -211,7 +239,12 @@
}) })
} }
} }
const [registerBankTable, { reload, getPaginationRef }] = useTable({
const handleFullscreen = (fullFlag) => {
setProps({ maxHeight: fullFlag ? undefined : 400 })
setAPIProps({ maxHeight: fullFlag ? undefined : 400 })
}
const [registerBankTable, { reload, getPaginationRef, setProps }] = useTable({
immediate: false, immediate: false,
api: async (p) => { api: async (p) => {
const res: API.DataResult = await getBankList(p) const res: API.DataResult = await getBankList(p)
@ -228,6 +261,7 @@
pageSize: currentPageInfo.pageSize, pageSize: currentPageInfo.pageSize,
sortConditions: [], sortConditions: [],
}, },
otherQueryCondition: '',
} }
let condition: API.ConditionItem[] = [] let condition: API.ConditionItem[] = []
condition.push({ condition.push({
@ -239,6 +273,7 @@
return postParam return postParam
}, },
maxHeight: 400,
pagination: true, pagination: true,
canResize: true, canResize: true,
resizeHeightOffset: 100, resizeHeightOffset: 100,
@ -260,9 +295,9 @@
}) })
} }
// //
const dsFileRef = ref(null) const dsFileRef = ref<Ref | null>(null)
function addFile() { function addFile() {
dsFileRef.value.init() dsFileRef.value?.init()
} }
function EditBank(record: Recordable) { function EditBank(record: Recordable) {
openModal(true, { openModal(true, {
@ -274,6 +309,7 @@
// ParentId.value = 0 // ParentId.value = 0
initData() initData()
reload() reload()
APIReload()
} }
// Switch // Switch
const changeIsDepartment = (v) => { const changeIsDepartment = (v) => {
@ -285,11 +321,49 @@
setFieldsValue({ status: v }) setFieldsValue({ status: v })
} }
function tabChange(e) { function tabChange(e) {
if (e == 1 && !rowId.value) { if (['1', '2'].includes(e) && !rowId.value) {
createMessage.warning('请先保存基础信息') createMessage.warning('请先保存基础信息')
activeKey.value = '0' activeKey.value = '0'
} }
} }
const [registerAPITable, { reload: APIReload, setProps: setAPIProps }] = useTable({
api: async (p) => {
const res: API.DataResult = await getOrgAuthList(p)
return new Promise((resolve) => {
resolve({ data: [...res.data], total: res.count })
})
},
beforeFetch: (p) => {
return formatParams(p)
},
maxHeight: 400,
columns: APIColumns,
immediate: false,
pagination: true,
canResize: true,
resizeHeightOffset: 100,
actionColumn: {
width: 60,
title: '操作',
dataIndex: 'action',
fixed: 'right',
},
})
const [registerAPIModal, { openModal: openAPIModal }] = useModal()
function AddAPIAuth() {
openAPIModal(true, {
isParent: false,
isUpdate: false,
orgFullName: getFieldsValue().orgFullName,
linkId: linkId.value,
})
}
function EditAPIAuth(record: Recordable) {
openAPIModal(true, {
record,
isUpdate: true,
})
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

@ -1,8 +1,18 @@
import { BasicColumn, FormSchema } from '/@/components/Table' import { BasicColumn, FormSchema } from '/@/components/Table'
import { Tag } from 'ant-design-vue' import { Tag } from 'ant-design-vue'
import { GetUserList } from '/@/api/common' import { getDictDropDown, GetUserList } from '/@/api/common'
import { useOptionsStore } from '/@/store/modules/options' import { useOptionsStore } from '/@/store/modules/options'
const optionsStore = useOptionsStore() const optionsStore = useOptionsStore()
let orgAuthTypeList: LabelValueOptions = []
const res2: API.DataResult = await getDictDropDown({ code: 'sys_org_Auth' })
if (res2.succeeded) {
orgAuthTypeList = []
res2.data.forEach((e) => {
orgAuthTypeList.push({ label: e.name, value: e.value })
})
}
export const columns: BasicColumn[] = [ export const columns: BasicColumn[] = [
{ {
title: '机构名称', title: '机构名称',
@ -693,3 +703,151 @@ export const BankformSchema: FormSchema[] = [
}, },
}, },
] ]
// API授权table列
export const APIColumns: BasicColumn[] = [
{
title: '类型',
dataIndex: 'type',
width: 230,
align: 'left',
customRender: ({ text }) => {
return orgAuthTypeList.find((el) => el.value === text)?.label || ''
},
},
{
title: 'KEY',
dataIndex: 'key',
width: 230,
align: 'left',
customRender: ({ text }) => {
return text ?? '-'
},
},
{
title: '密钥',
dataIndex: 'secret',
width: 230,
align: 'left',
customRender: ({ text }) => {
return text ?? '-'
},
},
{
title: '描述',
dataIndex: 'describe',
width: 230,
align: 'left',
customRender: ({ text }) => {
return text ?? '-'
},
},
{
title: '状态',
dataIndex: 'status',
width: 100,
customRender: ({ text }) => {
if (text === '0') {
return <Tag color="success"></Tag>
} else if (text === '1') {
return <Tag color="red"></Tag>
}
return text
},
},
{
title: '备注',
dataIndex: 'remark',
width: 180,
customRender: ({ text }) => {
return text ?? '-'
},
},
]
// API授权form
export const APIformSchema: FormSchema[] = [
{
label: '',
field: 'id',
component: 'Input',
defaultValue: '',
show: false,
},
{
label: '',
field: 'linkId',
component: 'Input',
defaultValue: '',
show: false,
},
{
field: 'type',
label: '类型',
component: 'Select',
required: true,
colProps: { span: 6 },
componentProps: ({ formModel }) => {
return {
allowClear: true,
showSearch: true,
options: orgAuthTypeList,
getPopupContainer: () => document.body,
}
},
},
{
label: 'KEY',
field: 'key',
component: 'Input',
required: true,
defaultValue: '',
colProps: {
span: 6,
},
},
{
label: '密钥',
field: 'secret',
component: 'Input',
required: true,
defaultValue: '',
colProps: {
span: 6,
},
},
{
field: 'status',
component: 'Switch',
slot: 'status',
label: '状态',
required: true,
componentProps: {
options: [
{ label: '启用', value: '0' },
{ label: '禁用', value: '1' },
],
},
defaultValue: true,
colProps: {
span: 6,
},
},
{
label: '描述',
field: 'describe',
component: 'Input',
required: true,
defaultValue: '',
colProps: {
span: 12,
},
},
{
field: 'remark',
label: '备注',
component: 'InputTextArea',
colProps: { span: 24 },
componentProps: { rows: 3 },
},
]

Loading…
Cancel
Save