Browse Source

自定义表单

v1
超级管理员 2 years ago
parent
commit
7202707f6b
  1. 1
      .gitignore
  2. 2
      src/api/dict/index.ts
  3. 13
      src/api/hr/org/index.ts
  4. 31
      src/api/hr/org/type.ts
  5. 8
      src/components/DesignForm/index.ts
  6. 113
      src/components/DesignForm/public/expand/diy-iconfont.vue
  7. 325
      src/components/DesignForm/public/expand/userDialog.vue
  8. 3
      src/main.ts

1
.gitignore

@ -19,3 +19,4 @@ components.d.ts
package-lock.json
pnpm-lock.yaml

2
src/api/dict/index.ts

@ -199,7 +199,7 @@ export function updateDict(data: DictForm) {
}
/**
*
*
*
* @param ids ID(,)
*/
export function deleteDictOld(ids: string) {

13
src/api/hr/org/index.ts

@ -1,6 +1,6 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { searchFormTitle,orgClassListCont,addOrgTypesCont,orgClassCont,editOrgTypeEditOrDel,searchOrgCont,orgInfo,addOrgInfo,editOrgDel,searchTeamList,orgTeamListCont } from './type';
import { searchFormTitle,orgClassListCont,addOrgTypesCont,orgClassCont,editOrgTypeEditOrDel,searchOrgCont,orgInfo,addOrgInfo,editOrgDel,searchTeamList,orgTeamListCont,orgFormTree } from './type';
/**
*
*/
@ -101,3 +101,14 @@ export function getTeamListCont(data: searchTeamList): AxiosPromise<orgTeamListC
data: data
});
}
/**
*
*/
export function getOrgFormTree(data?: editOrgDel): AxiosPromise<orgFormTree>{
return request({
url: '/hrapi/org/orgtreelist',
method: 'post',
data: data
});
}

31
src/api/hr/org/type.ts

@ -128,3 +128,34 @@ export interface addOrgInfo{
time?:number;
state?:number;
}
/**
*
*/
export interface orgform{
id: number;
parentId: number;
name: string;
sort: number;
status: number;
remark: string;
}
export interface orgFormTree{
dict:any;
list:orgform[];
pageInfo:any;
}
/**
*
*/
export interface orgFormSeachUsers{
page:number;
pagesize:number;
}
export interface searchCriteriaForPeople extends PageQuery{
total:number;
current:number;
orgid?:number;
usercont?:string;
}

8
src/components/DesignForm/index.ts

@ -0,0 +1,8 @@
import diyIconfont from '@/components/DesignForm/public/expand/diy-iconfont.vue'
import userDialog from '@/components/DesignForm/public/expand/userDialog.vue'
export default (app: any) => {
app.component('DiyIconfont', diyIconfont)
app.component('UserDialog', userDialog)
}

113
src/components/DesignForm/public/expand/diy-iconfont.vue

@ -0,0 +1,113 @@
<!--
@ 作者: 秦东
@ 时间: 2023-08-21 15:19:48
@ 备注:
-->
<script lang='ts' setup>
import { computed, ref } from 'vue'
import iconfontJson from '@/assets/iconfont/iconfont.json'
const props = withDefaults(
defineProps<{
modelValue?: string | string[]
colorPicker?: boolean // value
}>(),
{}
)
const emits = defineEmits<{
(e: 'update:modelValue', value: string | string[]): void
}>()
const visible = ref(false)
const value = computed({
get() {
if (props.colorPicker) {
return props.modelValue && props.modelValue[0]
} else {
return props.modelValue
}
},
set(newVal: any) {
iconClick(newVal)
}
})
const color = computed({
get() {
return props.modelValue && props.modelValue[1]
},
set(newVal: any) {
emits('update:modelValue', [value.value, newVal])
}
})
const iconList = computed(() => {
const temp: any = []
iconfontJson.glyphs.forEach((item: any) => {
temp.push(iconfontJson.css_prefix_text + item.font_class)
})
return temp
})
const iconClick = (newVal: string) => {
if (props.colorPicker) {
emits('update:modelValue', [newVal, color.value])
} else {
emits('update:modelValue', newVal)
}
visible.value = false
}
</script>
<template>
<el-popover
placement="bottom"
:width="500"
trigger="click"
v-model:visible="visible"
>
<div class="iconfont-list">
<ul>
<li
v-for="item in iconList"
:key="item"
@click="iconClick(item)"
:style="{ color: item === value ? color : '' }"
>
<i :class="item"></i>
</li>
</ul>
</div>
<template #reference>
<div class="iconfont-input">
<el-input v-model="value" placeholder="输入或选择iconfont图标" />
<div @click.stop="" class="color-input" v-if="colorPicker"><el-color-picker v-model="color" /></div>
</div>
</template>
</el-popover>
</template>
<style lang='scss' scoped>
.iconfont-list {
max-width: 500px;
overflow-y: auto;
ul {
display: flex;
flex-wrap: wrap;
}
li {
margin: 5px 10px;
cursor: pointer;
i {
font-size: 24px;
&:hover {
opacity: 0.6;
}
}
}
}
.iconfont-input {
position: relative;
width: 100%;
.color-input {
position: absolute;
right: 0;
top: 0;
}
}
</style>

325
src/components/DesignForm/public/expand/userDialog.vue

@ -0,0 +1,325 @@
<!--
@ 作者: 秦东
@ 时间: 2023-08-21 14:41:41
@ 备注: 选择用户
-->
<script lang='ts' setup>
import { ref, onMounted, reactive, nextTick } from 'vue'
import { getRequest } from '@/api/DesignForm'
import formatResult from '@/utils/DesignForm/formatResult'
import { getOrgFormTree } from '@/api/hr/org/index'
import { orgform } from '@/api/hr/org/type'
const props = withDefaults(
defineProps<{
modelValue?: string
}>(),
{}
)
const emits = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
const visible = ref(false)
//
const treeEl = ref()
const treeData = ref<orgform[]>([])
const department = ref()
const handleNodeClick = (data: any) => {
department.value = data.id
}
const getTreeData = () => {
// getRequest('deptList', {}).then((res: any) => {
// treeData.value = formatResult(res.data, 'transformDataToChild')
// })
getOrgFormTree()
.then(({ data }) => {
console.log(data)
treeData.value = data.list
}).finally(()=>{})
}
//
const userName = ref()
const tableData = ref([])
const page = reactive({
total: 0,
current: 1,
pageSize: 20
})
const searchClick = () => {
getUserList()
}
const resetClick = () => {
userName.value = ''
department.value = ''
treeEl.value.setCurrentKey(null)
getUserList()
}
const getUserList = () => {
const params = {
pageInfo: {
pageIndex: page.current,
pageSize: page.pageSize
},
name: userName.value,
department: department.value
}
getRequest('userList', params).then((res: any) => {
tableData.value = res.data.list
})
}
const currentChange = (current: number) => {
page.current = current
getUserList()
}
// 
const checkData = ref<any>([])
const tableRowClick = (row: any) => {
if (!checkData.value.includes(row.userName)) {
checkData.value.push(row.userName)
}
}
const delRowClick = (row: any) => {
checkData.value.forEach((item: any, index: number) => {
if (item === row) {
checkData.value.splice(index, 1)
}
})
}
const delAllClick = () => {
checkData.value = []
}
//
const open = () => {
visible.value = true
if (props.modelValue) {
checkData.value = props.modelValue.split(',')
} else {
checkData.value = []
}
}
//
const confirmClick = () => {
emits('update:modelValue', checkData.value.join(','))
visible.value = false
}
defineExpose({ open })
onMounted(() => {
nextTick(() => {
// loading
getTreeData()
getUserList()
})
})
const defaultProps ={
children: 'children',
label: 'name',
}
</script>
<template>
<el-dialog
title="用户选择"
v-model="visible"
:append-to-body="true"
:props="defaultProps "
width="80%"
>
<el-row :gutter="20">
<el-col :span="6" style="padding:0">
<div class="sidebar_tree">
<el-tree
ref="treeEl"
:data="treeData"
node-key="id"
@node-click="handleNodeClick"
:props="defaultProps "
highlight-current
/>
</div>
</el-col>
<el-col :span="12">
<div class="search">
<el-input placeholder="请输入用户名" v-model="userName" />
<el-button type="primary" @click="searchClick">查询</el-button>
<el-button @click="resetClick">重置</el-button>
</div>
<div class="list">
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="userName" label="照片" width="100px" align="center" />
<el-table-column prop="nickName" label="姓名" width="120px" align="left" />
<el-table-column prop="nickName" label="联系方式" width="100px" align="left" />
<el-table-column prop="nickName" label="归属行政组织" align="left" />
<el-table-column label="操作" width="60px">
<template #default="{ row }">
<el-button circle size="small" @click="tableRowClick(row)"><el-icon><ArrowRight /></el-icon></el-button>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination
background
layout="prev, pager, next"
small
hide-on-single-page
:current-page="page.current"
:total="page.total"
:page-size="page.pageSize"
@current-change="currentChange"
/>
</div>
</div>
</el-col>
<el-col :span="6">
<div class="has_select">
<div class="total">
<div>已选择{{ checkData.length }}</div>
<el-button type="danger" @click="delAllClick" size="small">全部移除</el-button>
</div>
<el-table :data="checkData">
<el-table-column label="用户名">
<template #default="{ row }">{{ row }}</template>
</el-table-column>
<el-table-column label="操作" width="60px">
<template #default="{ row }">
<el-button size="small" type="danger" @click="delRowClick(row)">移除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-col>
</el-row>
<div class="expand-user-dialog" style="display: none;">
<div class="sidebar-tree">
<el-tree
ref="treeEl"
:data="treeData"
node-key="id"
@node-click="handleNodeClick"
:props="defaultProps "
highlight-current
/>
<div class="table-list">
<div class="search">
<el-input placeholder="请输入用户名" v-model="userName" />
<el-button type="primary" @click="searchClick">查询</el-button>
<el-button @click="resetClick">重置</el-button>
</div>
<div class="list">
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="userName" label="用户名" />
<el-table-column prop="nickName" label="昵称" />
<el-table-column label="操作" width="60px">
<template #default="{ row }">
<el-button circle size="small" @click="tableRowClick(row)"><el-icon><ArrowRight /></el-icon></el-button>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination
background
layout="prev, pager, next"
small
hide-on-single-page
:current-page="page.current"
:total="page.total"
:page-size="page.pageSize"
@current-change="currentChange"
/>
</div>
</div>
</div>
<div class="has-select">
<div class="total">
<div>已选择{{ checkData.length }}</div>
<el-button type="danger" @click="delAllClick" size="small">全部移除</el-button>
</div>
<el-table :data="checkData">
<el-table-column label="用户名">
<template #default="{ row }">{{ row }}</template>
</el-table-column>
<el-table-column label="操作" width="60px">
<template #default="{ row }">
<el-button size="small" type="danger" @click="delRowClick(row)">移除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<template #footer>
<div>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="confirmClick"> 确定 </el-button>
</div>
</template>
</el-dialog>
</template>
<style lang='scss' scoped>
.sidebar_tree {
width: 100%;
border: 1px solid #ebeef5;
border-radius: 3px;
padding: 10px 0;
margin-right: 10px;
max-height: 500px;
overflow-y: auto;
}
.has_select {
width: 100%;
.total {
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
margin-bottom: 10px;
}
}
.search {
display: flex;
margin-bottom: 10px;
.el-input {
margin-right: 10px;
}
}
.expand-user-dialog {
display: flex;
align-items: flex-start;
.sidebar-tree {
width: 180px;
border: 1px solid #ebeef5;
border-radius: 3px;
padding: 10px 0;
margin-right: 10px;
max-height: 500px;
overflow-y: auto;
}
.table-list {
}
.search {
display: flex;
margin-bottom: 10px;
.el-input {
margin-right: 10px;
}
}
.page {
padding-top: 20px;
display: flex;
justify-content: flex-end;
}
.has-select {
width: 200px;
margin-left: 20px;
.total {
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
margin-bottom: 10px;
}
}
}
</style>

3
src/main.ts

@ -20,6 +20,7 @@ import 'element-plus/theme-chalk/dark/css-vars.css';
import '@/styles/index.scss';
import 'uno.css';
import ComComponents from '@/components/DesignForm/index'
const app = createApp(App);
@ -35,7 +36,7 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(router).use(i18n).use(ElementPlus, {
app.use(router).use(i18n).use(ComComponents).use(ElementPlus, {
locale: zhCn
}).use(AKDesign).mount('#app');

Loading…
Cancel
Save