25 changed files with 1598 additions and 13 deletions
@ -0,0 +1,47 @@ |
|||
import { defHttp, ApiServiceEnum } from '@/utils/http/axios'; |
|||
|
|||
enum Api { |
|||
listUser = 'sys/user/list', |
|||
listUserById = 'sys/user/listById', |
|||
listSystem = 'sys/system/list', |
|||
listSystemFilterByUser = 'sys/system/listAuthUser', |
|||
} |
|||
|
|||
/** |
|||
* 查询用户列表 |
|||
* @param params 参数 |
|||
* @param useYn |
|||
*/ |
|||
export const listUserApi = (params: Recordable = {}, useYn = true) => { |
|||
let parameter = params.parameter; |
|||
if (useYn) { |
|||
parameter = { |
|||
...parameter, |
|||
'useYn@=': true, |
|||
}; |
|||
} |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: Api.listUser, |
|||
data: { |
|||
...params, |
|||
parameter, |
|||
}, |
|||
}); |
|||
}; |
|||
|
|||
export const listUserByIdApi = (ids: any[]) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: Api.listUserById, |
|||
data: ids, |
|||
}); |
|||
}; |
|||
|
|||
export const listSystemApi = (params, filterByUser = false) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: filterByUser ? Api.listSystemFilterByUser : Api.listSystem, |
|||
data: params, |
|||
}); |
|||
}; |
|||
@ -0,0 +1,21 @@ |
|||
<template> |
|||
<ApiSelect v-bind="$attrs" value-field="dictItemCode" label-field="dictItemName" :api="api" /> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import ApiSelect from '../../components/ApiSelect.vue'; |
|||
import { propTypes } from '@/utils/propTypes'; |
|||
import { ApiServiceEnum, defHttp } from '@/utils/http/axios'; |
|||
|
|||
const props = defineProps({ |
|||
dictCode: propTypes.string.isRequired, |
|||
}); |
|||
|
|||
const api = () => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: 'sys/dict/listItemByCode', |
|||
data: props.dictCode, |
|||
}); |
|||
}; |
|||
</script> |
|||
@ -0,0 +1,47 @@ |
|||
<!-- |
|||
查询表信息 |
|||
--> |
|||
<template> |
|||
<ApiSelect |
|||
v-bind="$attrs" |
|||
:params="getParams" |
|||
value-field="value" |
|||
label-field="label" |
|||
:api="api" |
|||
/> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { propTypes } from '@/utils/propTypes'; |
|||
import { ApiServiceEnum, defHttp } from '@/utils/http/axios'; |
|||
import ApiSelect from '/@/components/Form/src/components/ApiSelect.vue'; |
|||
import { computed } from 'vue'; |
|||
|
|||
const props = defineProps({ |
|||
// 实体类类名 |
|||
modelClassName: propTypes.string.isRequired, |
|||
valueFieldName: propTypes.string.isRequired, |
|||
labelFieldName: propTypes.string.isRequired, |
|||
params: propTypes.object.def({}), |
|||
}); |
|||
|
|||
const getParams = computed(() => { |
|||
const { modelClassName, valueFieldName, labelFieldName, params } = props; |
|||
return { |
|||
modelClassName, |
|||
valueFieldName, |
|||
labelFieldName, |
|||
queryParameter: params, |
|||
}; |
|||
}); |
|||
|
|||
const api = (params) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: 'api/component/smart-form/listTableSelect', |
|||
data: params, |
|||
}); |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped></style> |
|||
@ -0,0 +1,100 @@ |
|||
<!--人员选择弹窗--> |
|||
<template> |
|||
<SmartTableSelectModal |
|||
v-bind="$attrs" |
|||
:table-props="tableProps" |
|||
:select-table-props="commonTableProps" |
|||
@register="registerModal" |
|||
label-field="fullName" |
|||
:list-api="listUserByIdApi" |
|||
@select-data="handleSelectData" |
|||
value-field="userId" |
|||
/> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import type { SmartTableProps } from '@/components/SmartTable'; |
|||
|
|||
import { reactive } from 'vue'; |
|||
import { useI18n } from '@/hooks/web/useI18n'; |
|||
|
|||
import { listUserApi, listUserByIdApi } from '@/api/sys/SystemApi'; |
|||
import { useModal } from '@/components/Modal'; |
|||
|
|||
import SmartTableSelectModal from './base/SmartTableSelectModal'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const emit = defineEmits(['update:selectValues', 'selected']); |
|||
|
|||
const [registerModal] = useModal(); |
|||
|
|||
const handleSelectData = (options: LabelValueOptions) => { |
|||
const userIdList = options.map((item) => item.value); |
|||
emit('update:selectValues', userIdList); |
|||
emit('selected', userIdList); |
|||
}; |
|||
|
|||
const commonTableProps: SmartTableProps = { |
|||
pagerConfig: true, |
|||
columns: [ |
|||
{ |
|||
type: 'checkbox', |
|||
width: 60, |
|||
align: 'center', |
|||
fixed: 'left', |
|||
}, |
|||
{ |
|||
title: '{system.views.user.table.username}', |
|||
field: 'username', |
|||
width: 120, |
|||
fixed: 'left', |
|||
}, |
|||
{ |
|||
title: '{system.views.user.table.fullName}', |
|||
field: 'fullName', |
|||
minWidth: 120, |
|||
fixed: 'left', |
|||
}, |
|||
{ |
|||
title: '{system.views.user.table.userType}', |
|||
field: 'userType', |
|||
width: 120, |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
const tableProps = reactive<SmartTableProps>({ |
|||
useSearchForm: true, |
|||
checkboxConfig: { |
|||
rowTrigger: 'multiple', |
|||
}, |
|||
searchFormConfig: { |
|||
compact: true, |
|||
colon: true, |
|||
searchWithSymbol: true, |
|||
actionColOptions: { |
|||
span: 12, |
|||
}, |
|||
baseColProps: { |
|||
span: 12, |
|||
}, |
|||
schemas: [ |
|||
{ |
|||
label: t('system.views.user.table.fullName'), |
|||
field: 'fullName', |
|||
component: 'Input', |
|||
searchSymbol: 'like', |
|||
}, |
|||
], |
|||
}, |
|||
proxyConfig: { |
|||
ajax: { |
|||
query: (params) => listUserApi(params.ajaxParameter), |
|||
}, |
|||
}, |
|||
...commonTableProps, |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped></style> |
|||
@ -0,0 +1,11 @@ |
|||
.smart-table-select { |
|||
@width: 80px; |
|||
|
|||
.select { |
|||
width: calc(100% - @width - 8px); |
|||
} |
|||
|
|||
.button { |
|||
width: @width; |
|||
} |
|||
} |
|||
@ -0,0 +1,127 @@ |
|||
import type { SmartTableProps } from '@/components/SmartTable'; |
|||
|
|||
import { defineComponent, ref } from 'vue'; |
|||
|
|||
import { propTypes } from '@/utils/propTypes'; |
|||
import { useModal } from '@/components/Modal'; |
|||
|
|||
import SmartTableSelectModal from './SmartTableSelectModal'; |
|||
|
|||
import './SmartTableSelect.less'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'SmartTableSelect', |
|||
props: { |
|||
// 是否支持多选
|
|||
multiple: propTypes.bool.def(true), |
|||
value: propTypes.oneOfType([propTypes.string, propTypes.array]), |
|||
// label字段
|
|||
labelField: propTypes.string.isRequired, |
|||
// value字段
|
|||
valueField: propTypes.string.isRequired, |
|||
tableProps: { |
|||
type: Object as PropType<SmartTableProps>, |
|||
required: true, |
|||
}, |
|||
disabled: propTypes.bool.def(false), |
|||
size: String as PropType<string>, |
|||
}, |
|||
emits: ['update:value', 'change'], |
|||
setup(props, { emit }) { |
|||
const [registerModal, { openModal }] = useModal(); |
|||
const optionsRef = ref<Array<any>>([]); |
|||
|
|||
const handleOptionChange = (options) => { |
|||
optionsRef.value = options; |
|||
}; |
|||
const handleSelectData = (options: any[]) => { |
|||
emit( |
|||
'update:value', |
|||
options.map((item) => item.value), |
|||
); |
|||
emit( |
|||
'change', |
|||
options.map((item) => item.value), |
|||
); |
|||
}; |
|||
const handleDeselect = (value) => { |
|||
const data = (props.value as any[]).filter((item) => item !== value); |
|||
emit('update:value', data); |
|||
emit('change', data); |
|||
}; |
|||
return { |
|||
registerModal, |
|||
openModal, |
|||
handleSelectData, |
|||
optionsRef, |
|||
handleDeselect, |
|||
handleOptionChange, |
|||
}; |
|||
}, |
|||
render() { |
|||
const { |
|||
$attrs, |
|||
multiple, |
|||
tableProps, |
|||
$slots, |
|||
disabled, |
|||
$t, |
|||
openModal, |
|||
registerModal, |
|||
labelField, |
|||
valueField, |
|||
handleSelectData, |
|||
optionsRef, |
|||
value, |
|||
handleDeselect, |
|||
handleOptionChange, |
|||
size, |
|||
} = this; |
|||
const modalSlots: any = { |
|||
table: $slots.table, |
|||
}; |
|||
return ( |
|||
<div class="smart-table-select"> |
|||
<a-row type="flex" gutter={8}> |
|||
<a-col class="select"> |
|||
<a-select |
|||
{...$attrs} |
|||
size={size} |
|||
disabled={disabled} |
|||
style={{ width: '100%' }} |
|||
options={optionsRef} |
|||
open={false} |
|||
value={value} |
|||
onDeselect={handleDeselect} |
|||
mode={multiple ? 'multiple' : 'combobox'} |
|||
></a-select> |
|||
</a-col> |
|||
<a-col class="button"> |
|||
<a-button |
|||
disabled={disabled} |
|||
size={size} |
|||
type="primary" |
|||
onClick={() => openModal(true, value || {})} |
|||
> |
|||
{$t('common.button.choose')} |
|||
</a-button> |
|||
</a-col> |
|||
</a-row> |
|||
<SmartTableSelectModal |
|||
{...$attrs} |
|||
onRegister={registerModal} |
|||
labelField={labelField} |
|||
onOptionChange={handleOptionChange} |
|||
onSelectData={handleSelectData} |
|||
valueField={valueField} |
|||
// @ts-ignore
|
|||
selectValues={value} |
|||
multiple={multiple} |
|||
tableProps={tableProps} |
|||
> |
|||
{modalSlots} |
|||
</SmartTableSelectModal> |
|||
</div> |
|||
); |
|||
}, |
|||
}); |
|||
@ -0,0 +1,205 @@ |
|||
import type { SmartTableProps } from '@/components/SmartTable'; |
|||
|
|||
import { computed, defineComponent, toRefs, unref, watch } from 'vue'; |
|||
import { propTypes } from '@/utils/propTypes'; |
|||
import { Col, Row } from 'ant-design-vue'; |
|||
|
|||
import { BasicModal, useModalInner } from '@/components/Modal'; |
|||
import { SmartTable } from '@/components/SmartTable'; |
|||
|
|||
import { useSmartTableSelect } from '../../hooks/useSmartTableSelect'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'SmartTableSelectModal', |
|||
components: { |
|||
BasicModal, |
|||
}, |
|||
props: { |
|||
tableProps: { |
|||
type: Object as PropType<SmartTableProps>, |
|||
required: true, |
|||
}, |
|||
selectTableProps: { |
|||
type: Object as PropType<Partial<SmartTableProps>>, |
|||
}, |
|||
// 是否多选
|
|||
multiple: propTypes.bool.def(true), |
|||
// 是否显示选中
|
|||
showSelect: propTypes.bool.def(false), |
|||
// label字段
|
|||
labelField: propTypes.string.isRequired, |
|||
// value字段
|
|||
valueField: propTypes.string.isRequired, |
|||
selectValues: propTypes.array.def([]), |
|||
listApi: { |
|||
type: Function as PropType<(data: any) => Promise<any>>, |
|||
required: true, |
|||
}, |
|||
// 是否每次弹窗都加载数据
|
|||
alwaysLoad: propTypes.bool.def(false), |
|||
}, |
|||
emits: ['register', 'select-data', 'option-change'], |
|||
setup(props, { emit, slots }) { |
|||
const { tableProps, selectTableProps, valueField, selectValues, alwaysLoad, multiple } = |
|||
toRefs(props); |
|||
|
|||
const hasTableSlot = computed<boolean>(() => { |
|||
return slots.table !== undefined; |
|||
}); |
|||
|
|||
const emitSelectData = () => { |
|||
const selectOptions = getSelectOptions(); |
|||
closeModal(); |
|||
emit('option-change', selectOptions); |
|||
emit('select-data', selectOptions, unref(selectRowsRef)); |
|||
}; |
|||
|
|||
const getSelectOptions = (): LabelValueOptions => { |
|||
return unref(selectRowsRef).map((item) => { |
|||
return { |
|||
label: item[props.labelField], |
|||
value: item[props.valueField], |
|||
}; |
|||
}); |
|||
}; |
|||
|
|||
const { |
|||
registerTable, |
|||
handleCheckboxChange, |
|||
registerSelectTable, |
|||
selectRowsRef, |
|||
setSelectData, |
|||
addSelectData, |
|||
removeSelectData, |
|||
getSelectData, |
|||
getTableCheckboxConfig, |
|||
handleCheckboxAll, |
|||
getHasSearchForm, |
|||
query, |
|||
getTableRadioConfig, |
|||
handleRadioChange, |
|||
handleSetSelect, |
|||
} = useSmartTableSelect( |
|||
tableProps, |
|||
selectTableProps, |
|||
props.showSelect, |
|||
valueField, |
|||
selectValues, |
|||
hasTableSlot, |
|||
props.listApi, |
|||
alwaysLoad, |
|||
multiple, |
|||
); |
|||
const [registerModal, { closeModal }] = useModalInner(async (_) => { |
|||
if (unref(alwaysLoad)) { |
|||
await query(); |
|||
await handleSetSelect(); |
|||
} |
|||
}); |
|||
|
|||
watch(selectRowsRef, () => { |
|||
const selectOptions = getSelectOptions(); |
|||
emit('option-change', selectOptions); |
|||
}); |
|||
|
|||
const handleOk = () => { |
|||
emitSelectData(); |
|||
}; |
|||
|
|||
return { |
|||
registerModal, |
|||
registerTable, |
|||
setSelectData, |
|||
addSelectData, |
|||
removeSelectData, |
|||
getSelectData, |
|||
handleCheckboxChange, |
|||
registerSelectTable, |
|||
selectRowsRef, |
|||
handleOk, |
|||
getTableCheckboxConfig, |
|||
handleCheckboxAll, |
|||
getHasSearchForm, |
|||
getTableRadioConfig, |
|||
handleRadioChange, |
|||
}; |
|||
}, |
|||
render() { |
|||
const { |
|||
$attrs, |
|||
registerModal, |
|||
$slots, |
|||
setSelectData, |
|||
handleOk, |
|||
addSelectData, |
|||
removeSelectData, |
|||
selectRowsRef, |
|||
} = this; |
|||
return ( |
|||
<BasicModal {...$attrs} onRegister={registerModal} onOk={handleOk}> |
|||
{$slots.table |
|||
? $slots.table({ |
|||
setSelectData, |
|||
addSelectData, |
|||
removeSelectData, |
|||
selectData: selectRowsRef, |
|||
}) |
|||
: renderTable(this)} |
|||
</BasicModal> |
|||
); |
|||
}, |
|||
}); |
|||
|
|||
const renderTable = (instance) => { |
|||
const { |
|||
$attrs, |
|||
showSelect, |
|||
multiple, |
|||
registerTable, |
|||
handleCheckboxChange, |
|||
registerSelectTable, |
|||
selectRowsRef, |
|||
getTableCheckboxConfig, |
|||
handleCheckboxAll, |
|||
getHasSearchForm, |
|||
getTableRadioConfig, |
|||
handleRadioChange, |
|||
} = instance; |
|||
let tableAttrs = { |
|||
...$attrs, |
|||
}; |
|||
if (multiple) { |
|||
tableAttrs = { |
|||
...tableAttrs, |
|||
checkboxConfig: unref(getTableCheckboxConfig), |
|||
onCheckboxChange: handleCheckboxChange, |
|||
onCheckboxAll: handleCheckboxAll, |
|||
}; |
|||
} else { |
|||
tableAttrs = { |
|||
...tableAttrs, |
|||
radioConfig: unref(getTableRadioConfig), |
|||
onRadioChange: handleRadioChange, |
|||
}; |
|||
} |
|||
return ( |
|||
<Row> |
|||
<Col span={showSelect ? 12 : 24}> |
|||
<SmartTable |
|||
onRegister={registerTable} |
|||
checkboxConfig={getTableCheckboxConfig} |
|||
onCheckboxChange={handleCheckboxChange} |
|||
onCheckboxAll={handleCheckboxAll} |
|||
{...tableAttrs} |
|||
/> |
|||
</Col> |
|||
{showSelect ? ( |
|||
<Col style={getHasSearchForm ? { marginTop: '58px' } : ''} span={12}> |
|||
<SmartTable data={selectRowsRef} onRegister={registerSelectTable} /> |
|||
</Col> |
|||
) : ( |
|||
'' |
|||
)} |
|||
</Row> |
|||
); |
|||
}; |
|||
@ -0,0 +1,103 @@ |
|||
<template> |
|||
<SmartTableSelect v-bind="computedProps" /> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import type { SmartTableProps } from '@/components/SmartTable'; |
|||
|
|||
import { computed, useAttrs } from 'vue'; |
|||
|
|||
import SmartTableSelect from '../base/SmartTableSelect'; |
|||
import { ApiServiceEnum, defHttp } from '@/utils/http/axios'; |
|||
import { useI18n } from '@/hooks/web/useI18n'; |
|||
import { listUserApi } from '@/api/sys/SystemApi'; |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const listUserById = (ids) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: 'sys/user/listById', |
|||
data: ids, |
|||
}); |
|||
}; |
|||
|
|||
const tableProps: SmartTableProps = { |
|||
pagerConfig: true, |
|||
useSearchForm: true, |
|||
proxyConfig: { |
|||
ajax: { |
|||
query: ({ ajaxParameter }) => listUserApi(ajaxParameter), |
|||
}, |
|||
}, |
|||
checkboxConfig: { |
|||
rowTrigger: 'multiple', |
|||
highlight: true, |
|||
}, |
|||
rowConfig: { |
|||
isHover: true, |
|||
}, |
|||
searchFormConfig: { |
|||
compact: true, |
|||
colon: true, |
|||
layout: 'inline', |
|||
searchWithSymbol: true, |
|||
actionColOptions: { span: undefined }, |
|||
baseColProps: { |
|||
span: 12, |
|||
}, |
|||
schemas: [ |
|||
{ |
|||
label: t('system.views.user.table.fullName'), |
|||
field: 'fullName', |
|||
component: 'Input', |
|||
searchSymbol: 'like', |
|||
}, |
|||
], |
|||
}, |
|||
columns: [ |
|||
{ |
|||
type: 'checkbox', |
|||
width: 60, |
|||
align: 'center', |
|||
fixed: 'left', |
|||
}, |
|||
{ |
|||
title: '{system.views.user.table.username}', |
|||
field: 'username', |
|||
width: 120, |
|||
fixed: 'left', |
|||
}, |
|||
{ |
|||
title: '{system.views.user.table.fullName}', |
|||
field: 'fullName', |
|||
minWidth: 120, |
|||
fixed: 'left', |
|||
}, |
|||
{ |
|||
title: '{system.views.user.table.userType}', |
|||
field: 'userType', |
|||
width: 120, |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
const defaultProps = { |
|||
title: '选择人员', |
|||
labelField: 'fullName', |
|||
valueField: 'userId', |
|||
multiple: true, |
|||
listApi: listUserById, |
|||
tableProps, |
|||
defaultFullscreen: true, |
|||
}; |
|||
|
|||
const computedProps = computed(() => { |
|||
return { |
|||
...defaultProps, |
|||
...useAttrs(), |
|||
}; |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped></style> |
|||
@ -0,0 +1,236 @@ |
|||
import type { SmartTableProps } from '@/components/SmartTable'; |
|||
import { useSmartTable } from '@/components/SmartTable'; |
|||
import type { ComputedRef, Ref } from 'vue'; |
|||
import { computed, ref, unref, watch } from 'vue'; |
|||
import { remove } from 'lodash-es'; |
|||
|
|||
export const useSmartTableSelect = ( |
|||
tablePropsRef: Ref<SmartTableProps>, |
|||
selectTablePropsRef: Ref<SmartTableProps | undefined>, |
|||
showSelect: boolean, |
|||
valueFieldRef: Ref<string>, |
|||
selectValuesRef: Ref<Array<any>>, |
|||
hasTableSlot: ComputedRef<boolean>, |
|||
listApi: ((data: any) => Promise<any>) | undefined, |
|||
alwaysLoad: Ref<boolean>, |
|||
multiple: Ref<boolean>, |
|||
) => { |
|||
const getTableProps = computed<SmartTableProps>(() => { |
|||
const tableProps = unref(tablePropsRef); |
|||
if (unref(alwaysLoad) && tableProps.proxyConfig) { |
|||
tableProps.proxyConfig.autoLoad = false; |
|||
} |
|||
return { |
|||
...tableProps, |
|||
rowConfig: { |
|||
keyField: unref(valueFieldRef), |
|||
}, |
|||
}; |
|||
}); |
|||
/** |
|||
* 是否有搜索表单 |
|||
*/ |
|||
const getHasSearchForm = computed(() => { |
|||
return unref(tablePropsRef).useSearchForm; |
|||
}); |
|||
|
|||
const getTableCheckboxConfig = computed(() => { |
|||
return { |
|||
highlight: true, |
|||
checkRowKeys: unref(selectValuesRef), |
|||
}; |
|||
}); |
|||
|
|||
/** |
|||
* 获取单选配置 |
|||
*/ |
|||
const getTableRadioConfig = computed(() => { |
|||
const result: Recordable = { |
|||
highlight: true, |
|||
strict: false, |
|||
reserve: true, |
|||
}; |
|||
const selectValues = unref(selectValuesRef); |
|||
if (selectValues && selectValues.length > 0) { |
|||
result.checkRowKey = selectValues[0]; |
|||
} |
|||
return result; |
|||
}); |
|||
|
|||
watch(selectValuesRef, async () => { |
|||
selectRowsRef.value = await getSelectRows(); |
|||
if (!unref(hasTableSlot)) { |
|||
handleSetSelect(); |
|||
} |
|||
}); |
|||
|
|||
const handleSetSelect = async () => { |
|||
if (unref(multiple)) { |
|||
await handleSetSelectRows(); |
|||
} else { |
|||
await handleSetRadioRow(); |
|||
} |
|||
}; |
|||
|
|||
const handleSetSelectRows = async () => { |
|||
await getTableInstance()?.setAllCheckboxRow(false); |
|||
await setCheckboxRow(unref(selectRowsRef), true); |
|||
}; |
|||
|
|||
const handleSetRadioRow = async () => { |
|||
const selectRows = unref(selectRowsRef); |
|||
if (selectRows && selectRows.length > 0) { |
|||
await getTableInstance()?.clearRadioRow(); |
|||
await getTableInstance()?.setRadioRow(selectRows[0]); |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* 获取选中的数据 |
|||
*/ |
|||
const getSelectRows = async () => { |
|||
const selectValues = unref(selectValuesRef); |
|||
if (!selectValues || selectValues.length === 0) { |
|||
return []; |
|||
} |
|||
const valueField = unref(valueFieldRef); |
|||
let tableData: any[] = []; |
|||
try { |
|||
tableData = getData(); |
|||
} catch (e) { |
|||
// do nothing
|
|||
} |
|||
// 没有匹配上的数据
|
|||
let noDataValue: any[] = []; |
|||
const matchDataList: any[] = []; |
|||
if (tableData) { |
|||
tableData.forEach((item) => { |
|||
const key = item[valueField]; |
|||
if (selectValues.includes(key)) { |
|||
matchDataList.push(item); |
|||
} |
|||
}); |
|||
const matchKeyList = matchDataList.map((item) => item[valueField]); |
|||
noDataValue = selectValues.filter((item) => !matchKeyList.includes(item)); |
|||
} |
|||
if (noDataValue.length > 0) { |
|||
// 没有匹配的数据
|
|||
// 1、从已经选中的数据中查找
|
|||
const selectRows = unref(selectRowsRef); |
|||
if (selectRows.length > 0) { |
|||
selectRows.forEach((item) => { |
|||
if (noDataValue.includes(item[valueField])) { |
|||
matchDataList.push(item); |
|||
} |
|||
}); |
|||
const matchKeyList2 = matchDataList.map((item) => item[valueField]); |
|||
noDataValue = noDataValue.filter((item) => !matchKeyList2.includes(item)); |
|||
} |
|||
} |
|||
if (noDataValue.length > 0) { |
|||
// 通过API查询
|
|||
const result = await listApi!(noDataValue); |
|||
matchDataList.push(...result); |
|||
} |
|||
return matchDataList; |
|||
}; |
|||
|
|||
const [registerTable, { setCheckboxRow, getData, getTableInstance, query }] = useSmartTable( |
|||
unref(getTableProps), |
|||
); |
|||
const [registerSelectTable, { setPagination }] = useSmartTable(unref(selectTablePropsRef) || {}); |
|||
|
|||
const selectRowsRef = ref<any[]>([]); |
|||
|
|||
/** |
|||
* 设置选中的数据 |
|||
* @param dataList |
|||
*/ |
|||
const setSelectData = (dataList: any[]) => { |
|||
console.log('-----------------'); |
|||
selectRowsRef.value = dataList; |
|||
}; |
|||
|
|||
/** |
|||
* 添加选中的数据 |
|||
* @param dataList |
|||
*/ |
|||
const addSelectData = (dataList: any[]) => { |
|||
const selectRows = unref(selectRowsRef); |
|||
selectRows.push(...dataList); |
|||
}; |
|||
|
|||
/** |
|||
* 移除数据 |
|||
* @param dataList |
|||
*/ |
|||
const removeSelectData = (dataList: any[]) => { |
|||
const selectRows = unref(selectRowsRef); |
|||
const valueField = unref(valueFieldRef); |
|||
remove(selectRows, (item) => { |
|||
return dataList.some((current) => current[valueField] === item[valueField]); |
|||
}); |
|||
}; |
|||
/** |
|||
* 获取选中的数据 |
|||
*/ |
|||
const getSelectData = () => unref(selectRowsRef); |
|||
|
|||
const handleCheckboxChange = ({ checked, row }) => { |
|||
const selectRows = unref(selectRowsRef); |
|||
if (checked) { |
|||
addSelectData([row]); |
|||
} else { |
|||
removeSelectData([row]); |
|||
} |
|||
if (showSelect) { |
|||
setPagination({ |
|||
total: selectRows.length, |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* 单选触发 |
|||
*/ |
|||
const handleRadioChange = ({ row, newValue }) => { |
|||
setSelectData([]); |
|||
if (newValue) { |
|||
addSelectData([row]); |
|||
} |
|||
}; |
|||
|
|||
const handleCheckboxAll = ({ checked }) => { |
|||
const currentDataList = getData(); |
|||
if (!currentDataList || currentDataList.length === 0) { |
|||
return; |
|||
} |
|||
if (checked) { |
|||
const keyList = unref(selectRowsRef).map((item) => item[unref(valueFieldRef)]); |
|||
addSelectData( |
|||
currentDataList.filter((item) => !keyList.includes(item[unref(valueFieldRef)])), |
|||
); |
|||
} else { |
|||
removeSelectData(currentDataList); |
|||
} |
|||
}; |
|||
|
|||
return { |
|||
registerTable, |
|||
handleCheckboxChange, |
|||
registerSelectTable, |
|||
selectRowsRef, |
|||
setSelectData, |
|||
addSelectData, |
|||
getSelectData, |
|||
removeSelectData, |
|||
getTableCheckboxConfig, |
|||
handleCheckboxAll, |
|||
getData, |
|||
getHasSearchForm, |
|||
query, |
|||
getTableRadioConfig, |
|||
handleRadioChange, |
|||
handleSetSelect, |
|||
}; |
|||
}; |
|||
@ -0,0 +1,70 @@ |
|||
import { ApiServiceEnum, defHttp } from '@/utils/http/axios'; |
|||
|
|||
enum Api { |
|||
list = 'sys/role/list', |
|||
getById = 'sys/role/getById', |
|||
listUser = 'sys/user/list', |
|||
listUserByRoleId = 'sys/user/listUserByRoleId', |
|||
setRoleUser = 'sys/role/setRoleUser', |
|||
delete = 'sys/role/batchDeleteById', |
|||
batchSaveUpdate = 'sys/role/batchSaveUpdate', |
|||
} |
|||
|
|||
export const listApi = (parameter) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: Api.list, |
|||
data: parameter, |
|||
}); |
|||
}; |
|||
|
|||
export const deleteApi = (parameter: any[]) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: Api.delete, |
|||
data: parameter.map((item) => item.roleId), |
|||
}); |
|||
}; |
|||
|
|||
export const getByIdApi = (model) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: Api.getById, |
|||
data: model.roleId, |
|||
}); |
|||
}; |
|||
|
|||
export const listUserApi = (parameter?) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: Api.listUser, |
|||
data: parameter, |
|||
}); |
|||
}; |
|||
|
|||
export const listUserByRoleIdApi = (roleIds: number[]) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: Api.listUserByRoleId, |
|||
data: roleIds, |
|||
}); |
|||
}; |
|||
|
|||
export const setRoleUserApi = (roleId: number, userIdList: number[]) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: Api.setRoleUser, |
|||
data: { |
|||
roleId, |
|||
userIdList, |
|||
}, |
|||
}); |
|||
}; |
|||
|
|||
export const batchSaveUpdateApi = (dataList: any[]) => { |
|||
return defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: Api.batchSaveUpdate, |
|||
data: dataList, |
|||
}); |
|||
}; |
|||
@ -0,0 +1,179 @@ |
|||
import type { SmartColumn, SmartSearchFormSchema } from '@/components/SmartTable'; |
|||
import type { FormSchema } from '@/components/Form'; |
|||
import { tableUseYnClass } from '@/components/SmartTable'; |
|||
|
|||
export const getTableColumns = (): SmartColumn[] => { |
|||
return [ |
|||
{ |
|||
type: 'checkbox', |
|||
width: 60, |
|||
align: 'center', |
|||
fixed: 'left', |
|||
}, |
|||
{ |
|||
title: '{system.views.role.table.roleName}', |
|||
field: 'roleName', |
|||
width: 120, |
|||
fixed: 'left', |
|||
}, |
|||
{ |
|||
title: '{system.views.role.table.roleCode}', |
|||
field: 'roleCode', |
|||
width: 150, |
|||
fixed: 'left', |
|||
}, |
|||
{ |
|||
title: '{system.views.role.table.roleType}', |
|||
field: 'roleType', |
|||
width: 120, |
|||
}, |
|||
{ |
|||
...tableUseYnClass(), |
|||
sortable: true, |
|||
}, |
|||
{ |
|||
title: '{common.table.remark}', |
|||
field: 'remark', |
|||
minWidth: 160, |
|||
}, |
|||
{ |
|||
title: '{common.table.seq}', |
|||
field: 'seq', |
|||
width: 100, |
|||
sortable: true, |
|||
}, |
|||
{ |
|||
title: '{common.table.createTime}', |
|||
field: 'createTime', |
|||
width: 165, |
|||
sortable: true, |
|||
}, |
|||
{ |
|||
title: '{common.table.createUser}', |
|||
field: 'createUserId', |
|||
width: 120, |
|||
formatter: ({ row }: any) => { |
|||
if (row.createUser) { |
|||
return row.createUser.fullName; |
|||
} |
|||
return ''; |
|||
}, |
|||
}, |
|||
{ |
|||
title: '{common.table.updateTime}', |
|||
field: 'updateTime', |
|||
width: 165, |
|||
sortable: true, |
|||
}, |
|||
{ |
|||
title: '{common.table.updateUser}', |
|||
field: 'updateUserId', |
|||
width: 120, |
|||
formatter: ({ row }: any) => { |
|||
if (row.updateUser) { |
|||
return row.updateUser.fullName; |
|||
} |
|||
return ''; |
|||
}, |
|||
}, |
|||
{ |
|||
title: '{common.table.operation}', |
|||
field: 'operation', |
|||
width: 120, |
|||
fixed: 'right', |
|||
slots: { |
|||
default: 'table-operation', |
|||
}, |
|||
}, |
|||
]; |
|||
}; |
|||
|
|||
export const getSearchSchemas = (t: Function): SmartSearchFormSchema[] => { |
|||
return [ |
|||
{ |
|||
label: t('system.views.role.table.roleName'), |
|||
field: 'roleName', |
|||
component: 'Input', |
|||
searchSymbol: 'like', |
|||
componentProps: { |
|||
style: { |
|||
width: '130px', |
|||
}, |
|||
}, |
|||
}, |
|||
{ |
|||
label: t('system.views.role.table.roleCode'), |
|||
field: 'roleCode', |
|||
component: 'Input', |
|||
searchSymbol: 'like', |
|||
componentProps: { |
|||
style: { |
|||
width: '130px', |
|||
}, |
|||
}, |
|||
}, |
|||
{ |
|||
label: t('common.title.useYn'), |
|||
field: 'useYn', |
|||
component: 'Select', |
|||
defaultValue: 1, |
|||
searchSymbol: '=', |
|||
componentProps: { |
|||
style: { |
|||
width: '100px', |
|||
}, |
|||
options: [ |
|||
{ |
|||
label: t('common.form.use'), |
|||
value: 1, |
|||
}, |
|||
{ |
|||
label: t('common.form.noUse'), |
|||
value: 0, |
|||
}, |
|||
], |
|||
}, |
|||
}, |
|||
]; |
|||
}; |
|||
|
|||
export const getAddEditFormSchemas = (t: Function): FormSchema[] => { |
|||
return [ |
|||
{ |
|||
label: '', |
|||
field: 'roleId', |
|||
component: 'Input', |
|||
show: false, |
|||
}, |
|||
{ |
|||
label: t('system.views.role.table.roleCode'), |
|||
field: 'roleCode', |
|||
component: 'Input', |
|||
required: true, |
|||
}, |
|||
{ |
|||
label: t('system.views.role.table.roleName'), |
|||
field: 'roleName', |
|||
component: 'Input', |
|||
required: true, |
|||
}, |
|||
{ |
|||
label: t('common.table.useYn'), |
|||
field: 'useYn', |
|||
component: 'Switch', |
|||
defaultValue: true, |
|||
}, |
|||
{ |
|||
label: t('system.views.role.table.roleType'), |
|||
field: 'roleType', |
|||
component: 'Input', |
|||
}, |
|||
{ |
|||
label: t('common.table.seq'), |
|||
field: 'seq', |
|||
component: 'InputNumber', |
|||
required: true, |
|||
defaultValue: 1, |
|||
}, |
|||
]; |
|||
}; |
|||
@ -0,0 +1,144 @@ |
|||
<template> |
|||
<div class="full-height page-container"> |
|||
<a-layout class="full-height"> |
|||
<a-layout-content class="full-height"> |
|||
<SmartTable |
|||
:size="getTableSize" |
|||
@register="registerTable" |
|||
@current-change="handleCurrentChange" |
|||
> |
|||
<template #table-operation="{ row }"> |
|||
<SmartVxeTableAction :actions="getTableActions(row)" /> |
|||
</template> |
|||
</SmartTable> |
|||
</a-layout-content> |
|||
<a-layout-sider theme="light" class="layout-set-function" width="240px"> |
|||
<RoleSetFunction :role-id="currentRow.roleId" /> |
|||
</a-layout-sider> |
|||
</a-layout> |
|||
<SmartUserSelectModal |
|||
@register="registerSetUserModal" |
|||
@selected="handleSetUser" |
|||
defaultFullscreen |
|||
showSelect |
|||
:title="$t('system.views.role.button.setRoleUser')" |
|||
:select-values="selectUserList" |
|||
/> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { ref } from 'vue'; |
|||
import { |
|||
useSmartTable, |
|||
SmartTable, |
|||
SmartVxeTableAction, |
|||
ActionItem, |
|||
} from '@/components/SmartTable'; |
|||
import { useI18n } from '@/hooks/web/useI18n'; |
|||
import { useSizeSetting } from '@/hooks/setting/UseSizeSetting'; |
|||
import { SmartUserSelectModal } from '@/components/Form'; |
|||
|
|||
import { getAddEditFormSchemas, getSearchSchemas, getTableColumns } from './RoleListView.config'; |
|||
import { listApi, batchSaveUpdateApi, deleteApi, getByIdApi } from './RoleListView.api'; |
|||
import { SystemPermissions } from '@/modules/system/constants/SystemConstants'; |
|||
import RoleSetFunction from './RoleSetFunction.vue'; |
|||
import { useRoleSetUser } from './hook/useRoleSetUser'; |
|||
import { hasPermission } from '@/utils/auth'; |
|||
|
|||
const { t } = useI18n(); |
|||
const { getTableSize } = useSizeSetting(); |
|||
|
|||
const permissions = SystemPermissions.role; |
|||
|
|||
const currentRow = ref<Recordable>({}); |
|||
const handleCurrentChange = ({ row }: any) => { |
|||
currentRow.value = row; |
|||
}; |
|||
|
|||
const { registerSetUserModal, handleSetUser, handleShowSetUser, selectUserList } = |
|||
useRoleSetUser(t); |
|||
|
|||
const getTableActions = (row): ActionItem[] => { |
|||
return [ |
|||
{ |
|||
label: t('common.button.edit'), |
|||
preIcon: 'ant-design:edit-out-lined', |
|||
auth: permissions.update, |
|||
onClick: () => editByRowModal(row), |
|||
}, |
|||
{ |
|||
label: t('system.views.role.button.setRoleUser'), |
|||
preIcon: 'ant-design:user-add-outlined', |
|||
auth: permissions.setRoleUser, |
|||
onClick: () => { |
|||
handleShowSetUser(row); |
|||
}, |
|||
}, |
|||
]; |
|||
}; |
|||
|
|||
const [registerTable, { editByRowModal }] = useSmartTable({ |
|||
id: 'sys_role_list', |
|||
columns: getTableColumns(), |
|||
border: true, |
|||
stripe: true, |
|||
height: 'auto', |
|||
highlightHoverRow: true, |
|||
highlightCurrentRow: true, |
|||
pagerConfig: true, |
|||
columnConfig: { |
|||
resizable: true, |
|||
}, |
|||
useSearchForm: true, |
|||
searchFormConfig: { |
|||
compact: true, |
|||
colon: true, |
|||
searchWithSymbol: true, |
|||
schemas: getSearchSchemas(t), |
|||
layout: 'inline', |
|||
actionColOptions: { |
|||
span: undefined, |
|||
}, |
|||
}, |
|||
proxyConfig: { |
|||
ajax: { |
|||
query: (params) => listApi(params.ajaxParameter), |
|||
delete: ({ body: { removeRecords } }) => deleteApi(removeRecords), |
|||
getById: (model) => getByIdApi(model), |
|||
save: ({ body: { insertRecords, updateRecords } }) => |
|||
batchSaveUpdateApi([...insertRecords, ...updateRecords]), |
|||
}, |
|||
}, |
|||
printConfig: {}, |
|||
authConfig: { |
|||
authHandler: hasPermission, |
|||
}, |
|||
toolbarConfig: { |
|||
zoom: true, |
|||
refresh: true, |
|||
column: true, |
|||
buttons: [ |
|||
{ code: 'ModalAdd', auth: permissions.add }, |
|||
{ code: 'delete', auth: permissions.delete }, |
|||
], |
|||
}, |
|||
addEditConfig: { |
|||
formConfig: { |
|||
schemas: getAddEditFormSchemas(t), |
|||
colon: true, |
|||
wrapperCol: { span: 18 }, |
|||
labelCol: { span: 5 }, |
|||
baseColProps: { |
|||
span: 24, |
|||
}, |
|||
}, |
|||
}, |
|||
}); |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.layout-set-function { |
|||
margin-left: 5px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,158 @@ |
|||
<template> |
|||
<a-layout class="full-height"> |
|||
<a-layout-header style="height: 48px; background: white; line-height: 48px; text-align: center"> |
|||
<h3>{{ $t('system.views.role.title.setFunction') }}</h3> |
|||
</a-layout-header> |
|||
<Divider style="margin: 0" /> |
|||
<a-layout-content style=" overflow: auto;background: white"> |
|||
<Spin :spinning="dataLoading"> |
|||
<a-tree |
|||
ref="treeRef" |
|||
v-model:checkedKeys="checkedKeysModel" |
|||
:tree-data="functionTreeData" |
|||
checkable |
|||
/> |
|||
</Spin> |
|||
</a-layout-content> |
|||
<Divider style="margin: 0" /> |
|||
<a-layout-footer style="height: 50px; padding: 10px 0; background: white; text-align: center"> |
|||
<div style="padding: 0 5px"> |
|||
<a-button |
|||
v-permission="permissions.setFunction" |
|||
:loading="saveLoading" |
|||
block |
|||
type="primary" |
|||
@click="handleSave" |
|||
> |
|||
{{ $t('common.button.save') }} |
|||
</a-button> |
|||
</div> |
|||
</a-layout-footer> |
|||
</a-layout> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { defineComponent, ref, onMounted, toRefs, watch, unref } from 'vue'; |
|||
import type { PropType } from 'vue'; |
|||
|
|||
import { message, Spin, Divider } from 'ant-design-vue'; |
|||
|
|||
import TreeUtils from '@/utils/TreeUtils'; |
|||
|
|||
import { SystemPermissions } from '@/modules/system/constants/SystemConstants'; |
|||
import { ApiServiceEnum, defHttp } from '@/utils/http/axios'; |
|||
|
|||
/** |
|||
* 设置角色对应的功能 |
|||
*/ |
|||
export default defineComponent({ |
|||
name: 'RoleSetFunction', |
|||
components: { |
|||
Spin, |
|||
Divider, |
|||
}, |
|||
props: { |
|||
roleId: { |
|||
type: Number as PropType<number>, |
|||
default: null, |
|||
}, |
|||
}, |
|||
setup(props) { |
|||
const { roleId } = toRefs(props); |
|||
const treeRef = ref(); |
|||
// 树形控件数据 |
|||
const functionTreeData = ref<Array<any>>([]); |
|||
const dataLoading = ref(false); |
|||
const saveLoading = ref(false); |
|||
const checkedKeysModel = ref([]); |
|||
|
|||
/** |
|||
* 加载功能树函数 |
|||
*/ |
|||
const loadFunctionTreeData = async () => { |
|||
dataLoading.value = true; |
|||
try { |
|||
const result = await defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: 'sys/function/list', |
|||
data: { |
|||
sortName: 'seq', |
|||
}, |
|||
}); |
|||
functionTreeData.value = |
|||
TreeUtils.convertList2Tree( |
|||
result.map(({ functionId, functionName, parentId }: any) => { |
|||
return { |
|||
key: functionId, |
|||
title: functionName, |
|||
parentId: parentId, |
|||
}; |
|||
}), |
|||
(item) => item.key, |
|||
(item) => item.parentId, |
|||
0, |
|||
) || []; |
|||
} finally { |
|||
dataLoading.value = false; |
|||
} |
|||
}; |
|||
/** |
|||
* 加载角色对应的功能ID |
|||
*/ |
|||
const loadRoleFunctions = async () => { |
|||
if (roleId.value !== null) { |
|||
dataLoading.value = true; |
|||
try { |
|||
checkedKeysModel.value = await defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: 'sys/role/listFunctionId', |
|||
params: { |
|||
id: unref(roleId), |
|||
}, |
|||
}); |
|||
} finally { |
|||
dataLoading.value = false; |
|||
} |
|||
} |
|||
}; |
|||
/** |
|||
* 执行保存操作 |
|||
*/ |
|||
const handleSave = async () => { |
|||
const tree = unref(treeRef); |
|||
if (roleId.value === null) { |
|||
message.error('请先选定角色'); |
|||
return false; |
|||
} |
|||
saveLoading.value = true; |
|||
try { |
|||
await defHttp.post({ |
|||
service: ApiServiceEnum.SMART_SYSTEM, |
|||
url: 'sys/role/saveRoleMenu', |
|||
data: { |
|||
roleId: roleId.value, |
|||
functionIdList: tree.checkedKeys, |
|||
halfFunctionIdList: tree.halfCheckedKeys, |
|||
}, |
|||
}); |
|||
message.success('保存成功'); |
|||
} finally { |
|||
saveLoading.value = false; |
|||
} |
|||
}; |
|||
watch(roleId, loadRoleFunctions); |
|||
onMounted(loadFunctionTreeData); |
|||
return { |
|||
functionTreeData, |
|||
dataLoading, |
|||
saveLoading, |
|||
checkedKeysModel, |
|||
handleSave, |
|||
permissions: SystemPermissions.role, |
|||
treeRef, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped></style> |
|||
@ -0,0 +1,42 @@ |
|||
import { useModal } from '@/components/Modal'; |
|||
import { message } from 'ant-design-vue'; |
|||
import { ref, unref } from 'vue'; |
|||
|
|||
import { listUserByRoleIdApi, setRoleUserApi } from '../RoleListView.api'; |
|||
|
|||
export const useRoleSetUser = (t: Function) => { |
|||
const [registerSetUserModal, { openModal, setModalProps, closeModal }] = useModal(); |
|||
const currentRole = ref<Recordable | null>(null); |
|||
const selectUserList = ref<number[]>([]); |
|||
|
|||
const handleShowSetUser = async (role: Recordable) => { |
|||
currentRole.value = role; |
|||
openModal(true, { a: 1 }); |
|||
try { |
|||
setModalProps({ loading: true }); |
|||
const result = await listUserByRoleIdApi([role.roleId]); |
|||
selectUserList.value = result.map((item) => item.userId); |
|||
} finally { |
|||
setModalProps({ loading: false }); |
|||
} |
|||
}; |
|||
|
|||
const handleSetUser = async (userId: number[]) => { |
|||
selectUserList.value = userId; |
|||
try { |
|||
setModalProps({ confirmLoading: true }); |
|||
await setRoleUserApi(unref(currentRole)!.roleId, userId); |
|||
message.success(t('common.message.OperationSucceeded')); |
|||
closeModal(); |
|||
} finally { |
|||
setModalProps({ confirmLoading: false }); |
|||
} |
|||
}; |
|||
|
|||
return { |
|||
selectUserList, |
|||
handleShowSetUser, |
|||
registerSetUserModal, |
|||
handleSetUser, |
|||
}; |
|||
}; |
|||
@ -0,0 +1,24 @@ |
|||
export default { |
|||
system: { |
|||
views: { |
|||
role: { |
|||
title: { |
|||
setFunction: 'Set function', |
|||
}, |
|||
table: { |
|||
roleName: 'Role name', |
|||
roleCode: 'Role code', |
|||
roleType: 'Role type', |
|||
}, |
|||
validate: { |
|||
roleName: 'Please enter role name', |
|||
roleCode: 'Please enter role code', |
|||
roleType: 'Please enter role type', |
|||
}, |
|||
button: { |
|||
setRoleUser: 'Set user', |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
}; |
|||
@ -0,0 +1,24 @@ |
|||
export default { |
|||
system: { |
|||
views: { |
|||
role: { |
|||
title: { |
|||
setFunction: '设置功能', |
|||
}, |
|||
table: { |
|||
roleName: '角色名称', |
|||
roleCode: '角色编码', |
|||
roleType: '角色类型', |
|||
}, |
|||
validate: { |
|||
roleName: '请输入角色名称', |
|||
roleCode: '请输入角色编码', |
|||
roleType: '请输入角色类型', |
|||
}, |
|||
button: { |
|||
setRoleUser: '关联用户', |
|||
}, |
|||
}, |
|||
}, |
|||
}, |
|||
}; |
|||
Loading…
Reference in new issue