Jelajahi Sumber

区域权限

ZaiZai 2 tahun lalu
induk
melakukan
659d267baa

+ 52 - 0
src/api/modules/tasks/flow.js

@@ -0,0 +1,52 @@
+import {httpApi} from "../../request/httpApi";
+
+export default {
+    //分页数据
+    async getPageData(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/fixedFlow/page',
+            method: 'get',
+            params: form
+        }, msg)
+    },
+    //获取系统所有角色划分
+    async queryAllRoleList(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/fixedFlow/queryAllRoleList',
+            method: 'get',
+            params: form
+        }, msg);
+    },
+    //详情
+    async queryFixedFlowDetail(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/fixedFlow/detail',
+            method: 'get',
+            params: form
+        }, msg);
+    },
+    //新增
+    async addFixedFlowData(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/fixedFlow/save',
+            method: 'post',
+            data: form
+        }, msg);
+    },
+    //修改
+    async updateFixedFlowData(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/fixedFlow/update',
+            method: 'post',
+            data: form
+        }, msg);
+    },
+    //删除
+    async removeFixedFlowData(form, msg = true) {
+        return httpApi({
+            url: '/api/blade-business/fixedFlow/remove',
+            method: 'post',
+            params: form
+        }, msg);
+    },
+}

+ 273 - 0
src/global/components/hc-tasks-user/index.vue

@@ -0,0 +1,273 @@
+<template>
+    <div :class="ui" class="hc-tasks-user">
+        <div class="tasks-user-box">
+            <div class="tag-user-list" @click="showModalClick">
+                <template v-for="(item,index) in UserDataList" :key="index">
+                    <el-tag>{{ setCheckboxUserName(item) }}</el-tag>
+                    <HcIcon v-if="(UserDataList.length - 1) > index" name="arrow-right" ui="arrow-icon-tag"/>
+                </template>
+                <div v-if="UserDataList.length <= 0" class="tasks-placeholder"> 点击这里选择任务人</div>
+            </div>
+        </div>
+
+        <!--选择任务人-->
+        <el-dialog v-model="showModal" class="hc-modal-border hc-modal-nop" destroy-on-close draggable title="选择任务人"
+                   width="62rem">
+            <div class="hc-tasks-user-modal-content-box">
+                <div class="tree-box">
+                    <el-scrollbar>
+                        <ElTree :data="ElTreeData" :default-expanded-keys="[0]" :props="ElTreeProps" accordion
+                                class="hc-tree-node-box" highlight-current node-key="roleId" @node-click="ElTreeNodeClick"/>
+                    </el-scrollbar>
+                </div>
+                <div class="user-box">
+                    <div class="y-user-list-box">
+                        <div class="title-box">
+                            <div class="title">可选择</div>
+                        </div>
+                        <div class="user-list">
+                            <el-scrollbar>
+                                <el-checkbox-group v-model="checkboxUserList">
+                                    <template v-for="item in signUserList">
+                                        <div class="user-item checkbox-li">
+                                            <el-checkbox
+                                                :label="`${item['certificateUserName']}-${item['certificateUserId']}`">
+                                                <div class="item-user-name">{{ item['certificateUserName'] }}</div>
+                                            </el-checkbox>
+                                        </div>
+                                    </template>
+                                </el-checkbox-group>
+                            </el-scrollbar>
+                        </div>
+                    </div>
+                    <div class="s-user-list-box">
+                        <div class="title-box">
+                            <div class="title">已选择({{ checkboxUserList.length }})</div>
+                        </div>
+                        <div class="user-list">
+                            <el-scrollbar>
+                                <template v-for="(item,index) in checkboxUserList" :key="index">
+                                    <el-tag closable @close="delCheckboxUser(index)">{{ setCheckboxUserName(item) }}
+                                    </el-tag>
+                                </template>
+                            </el-scrollbar>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <template #footer>
+                <div class="dialog-footer">
+                    <el-button size="large" @click="showModal = false">
+                        <HcIcon name="close"/>
+                        <span>取消</span>
+                    </el-button>
+                    <el-button :loading="sureSignUserLoading" hc-btn type="primary" @click="sureSignUserClick">
+                        <HcIcon name="check"/>
+                        <span>确定</span>
+                    </el-button>
+                </div>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script setup>
+import {ref, watch, onMounted} from "vue";
+import tasksFlowApi from '~api/tasks/flow';
+import {getArrValue, deepClone} from "js-fast-way"
+
+//参数
+const props = defineProps({
+    ui: {
+        type: String,
+        default: ''
+    },
+    //选中的用户数组
+    users: {
+        type: String,
+        default: ''
+    },
+    projectId: {
+        type: [String, Number],
+        default: ''
+    },
+    contractId: {
+        type: [String, Number],
+        default: ''
+    }
+})
+
+//变量
+const showModal = ref(false)
+const sequenceModal = ref(false)
+const checkboxUserList = ref([])
+const UserDataList = ref([])
+const projectId = ref(props.projectId)
+const contractId = ref(props.contractId)
+
+//树数据
+const ElTreeProps = {children: 'childRoleList', label: 'roleName'}
+const ElTreeData = ref([{
+    roleName: '全部人员',
+    roleId: 0,
+    childRoleList: [],
+    signPfxFileList: []
+}])
+
+//监听
+watch(() => [
+    props.users,
+    props.projectId,
+    props.contractId,
+], ([users, pid, cid]) => {
+    projectId.value = pid
+    contractId.value = cid
+    setUserDataList(users)
+})
+
+//渲染完成
+onMounted(() => {
+    setUserDataList(props.users)
+    queryAllRoleList()
+})
+
+//处理用户数据
+const setUserDataList = (users) => {
+    if (users) {
+        const usersArr = users.split(',')
+        UserDataList.value = usersArr
+        checkboxUserList.value = usersArr
+    } else {
+        UserDataList.value = []
+        checkboxUserList.value = []
+    }
+}
+
+//展开弹窗
+const showModalClick = () => {
+    showModal.value = true
+}
+
+//获取系统所有角色划分
+const signUserList = ref([])
+const queryAllRoleList = async () => {
+    const {error, code, data} = await tasksFlowApi.queryAllRoleList({
+        contractId: contractId.value
+    })
+    //处理数据
+    if (!error && code === 200) {
+        let signList = [], dataArr = getArrValue(data)
+        ElTreeData.value[0].childRoleList = dataArr
+        if (dataArr.length > 0) {
+            dataArr.forEach(item => {
+                signList = signList.concat(item.signPfxFileList)
+            })
+        }
+        ElTreeData.value[0].signPfxFileList = signList
+        signUserList.value = signList
+    } else {
+        signUserList.value = []
+        ElTreeData.value[0].childRoleList = []
+        ElTreeData.value[0].signPfxFileList = []
+    }
+}
+
+//树被点击
+const ElTreeNodeClick = (data) => {
+    signUserList.value = getArrValue(data?.signPfxFileList)
+}
+
+//处理已选择的用户问题
+const setCheckboxUserName = (item) => {
+    if (item) {
+        const itemArr = item.split('-')
+        if (itemArr.length > 0 && itemArr[0]) {
+            return itemArr[0]
+        } else {
+            return ''
+        }
+    } else {
+        return ''
+    }
+}
+
+//删除已选择的用户
+const delCheckboxUser = (index) => {
+    checkboxUserList.value.splice(index, 1);
+}
+
+//事件
+const emit = defineEmits(['change'])
+
+//确认选择
+const sureSignUserLoading = ref(false)
+const sureSignUserClick = () => {
+    let newUser = [], newUserId = [], users = '';
+    const dataList = deepClone(checkboxUserList.value)
+    UserDataList.value = dataList
+    if (dataList.length > 0) {
+        sureSignUserLoading.value = true
+        //封装数据
+        dataList.forEach(item => {
+            const itemArr = item.split('-')
+            if (itemArr.length > 0 && itemArr[0]) {
+                users = users ? `${users},${item}` : item
+                newUser.push({
+                    userId: itemArr[1],
+                    userName: itemArr[0],
+                })
+                newUserId.push(itemArr[1])
+            }
+        })
+        showModal.value = false
+        sureSignUserLoading.value = false
+        emit('change', newUser, newUserId, users)
+    } else {
+        window.$message?.warning('请先选择任务人员,或点击取消')
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import './style.scss';
+</style>
+
+<style lang="scss">
+.hc-tasks-user .tasks-user-box .tag-user-list {
+    .el-tag {
+        --el-icon-size: 14px;
+        padding: 0 10px;
+        height: 26px;
+        margin: 4px 0;
+    }
+}
+.hc-tasks-user-modal-content-box {
+    .checkbox-li .el-checkbox {
+        width: 100%;
+        .el-checkbox__input {
+            position: absolute;
+            right: 0;
+            .el-checkbox__inner {
+                width: 18px;
+                height: 18px;
+                &:after {
+                    height: 9px;
+                    left: 6px;
+                    top: 2px;
+                }
+            }
+        }
+        .el-checkbox__label {
+            flex: 1;
+            padding-left: 0;
+            padding-right: 20px;
+        }
+    }
+    .user-list {
+        .el-tag {
+            margin-right: 10px;
+            margin-top: 12px;
+        }
+    }
+}
+</style>

+ 147 - 0
src/global/components/hc-tasks-user/style.scss

@@ -0,0 +1,147 @@
+.hc-tasks-user {
+    position: relative;
+    .tasks-user-box {
+        position: relative;
+        border: 1px solid #e0e0e6;
+        border-radius: 4px;
+        padding: 0 12px;
+        cursor: pointer;
+        min-height: 40px;
+        .tag-user-list {
+            position: relative;
+            display: flex;
+            align-items: center;
+            flex-flow: row wrap;
+            min-height: inherit;
+            .tasks-placeholder {
+                color: #a9abb2;
+                font-size: 14px;
+            }
+            .arrow-icon-tag {
+                position: relative;
+                color: #a9abb2;
+                font-size: 18px;
+                margin: 0 8px;
+            }
+        }
+    }
+}
+
+.hc-tasks-user-modal-content-box {
+    position: relative;
+    display: flex;
+    height: 460px;
+    .tree-box {
+        flex: 1;
+        user-select: none;
+        position: relative;
+        padding: 20px;
+        overflow: hidden;
+        border-right: 1px solid #EEEEEE;
+    }
+    .user-box {
+        flex: 2;
+        position: relative;
+        display: flex;
+        flex-direction: column;
+        .y-user-list-box, .s-user-list-box {
+            position: relative;
+            overflow: hidden;
+            display: flex;
+            flex-direction: column;
+            .title-box {
+                position: relative;
+                padding: 2px 24px;
+                display: flex;
+                align-items: center;
+                border-bottom: 1px solid #EEEEEE;
+                background-color: #F8F8F8;
+                color: #838791;
+                .title {
+                    flex: auto;
+                }
+            }
+            .user-list {
+                position: relative;
+                overflow: hidden;
+                padding: 0 24px;
+                .user-item {
+                    position: relative;
+                    padding: 4px 0;
+                }
+                .user-item + .user-item {
+                    border-top: 1px dashed #EEEEEE;
+                }
+            }
+        }
+        .y-user-list-box {
+            flex: 1;
+            .user-list {
+                flex: 1;
+            }
+        }
+        .s-user-list-box {
+            position: relative;
+            border-top: 1px solid #EEEEEE;
+            .user-list {
+                height: 6rem;
+            }
+        }
+    }
+}
+
+.sort-node-body-box.list-group {
+    position: relative;
+    min-height: 20px;
+    border: 1px solid #EEEEEE;
+    .list-group-item {
+        position: relative;
+        display: flex;
+        align-items: center;
+        padding: 6px 15px;
+        cursor: move;
+        transition: background 0.2s;
+        .index-box {
+            position: relative;
+            width: 50px;
+        }
+        .title-box {
+            position: relative;
+            padding-right: 24px;
+            flex: 1;
+        }
+        .icon-box {
+            position: relative;
+            font-size: 18px;
+            display: flex;
+            align-items: center;
+            .icon {
+                cursor: pointer;
+                display: flex;
+                align-items: center;
+            }
+        }
+        &:first-child .icon-box i:last-child,
+        &:last-child .icon-box i:first-child {
+            cursor: default;
+            color: #aaaaaa;
+        }
+        &:hover {
+            background: var(--el-color-primary-light-9);
+        }
+    }
+    .list-group-item + .list-group-item {
+        border-top: 1px solid #EEEEEE;
+    }
+    &.header {
+        border-bottom: 0;
+        .list-group-item {
+            cursor: default;
+            padding: 8px 15px;
+            background-color: #F8F8F8;
+            .index-box, .title-box, .icon-box {
+                font-size: 14px;
+            }
+        }
+    }
+}

+ 2 - 0
src/global/components/index.js

@@ -3,6 +3,7 @@ import HcTipItem from './hc-tooltip/item.vue'
 import HcTableForm from './table-form/index.vue'
 import HcPageLayout from './page-layout/index.vue'
 import HcTreeData from './tree-data/index.vue'
+import HcTasksUser from './hc-tasks-user/index.vue'
 
 //注册全局组件
 export const setupComponents = (App) => {
@@ -10,5 +11,6 @@ export const setupComponents = (App) => {
     App.component('HcTipItem', HcTipItem)
     App.component('HcTableForm', HcTableForm)
     App.component('HcTreeData', HcTreeData)
+    App.component('HcTasksUser', HcTasksUser)
     App.component('HcPageLayout', HcPageLayout)
 }

+ 8 - 2
src/global/components/tree-data/index.vue

@@ -1,5 +1,7 @@
 <template>
-    <HcDataTree :h-props="treeProps" :autoExpandKeys="autoExpandKeys" :treeKey="treeKey" :datas="treeLoadNode" @nodeTap="treeNodeClick">
+    <HcDataTree :h-props="treeProps" :autoExpandKeys="autoExpandKeys" :treeKey="treeKey" :datas="treeLoadNode"
+                :showCheckbox="showCheckbox"
+                @nodeTap="treeNodeClick">
         <template #default="{node, data, level}">
             <div :class="level === 1 ? 'level-name':''" class="label flex items-center">
                 <span class="hc-tree-node-type" v-if="level !== 1">县</span>
@@ -46,7 +48,11 @@ const props = defineProps({
     isMenu: {
         type: Boolean,
         default: true
-    }
+    },
+    showCheckbox: {
+        type: Boolean,
+        default: false
+    },
 })
 
 //渲染完成

+ 30 - 0
src/styles/base/region.scss

@@ -36,3 +36,33 @@
         }
     }
 }
+
+.base-region-dialog {
+    position: relative;
+    display: flex;
+    height: 100%;
+    .dialog-form, .dialog-action {
+        position: relative;
+        height: 100%;
+    }
+    .dialog-form {
+        flex: 1;
+        margin-right: 20px;
+    }
+    .dialog-action {
+        flex: 1;
+        margin-left: 20px;
+        .title {
+            font-size: 18px;
+            color: #101010;
+        }
+        .data-tree-box {
+            position: relative;
+            border: 1px solid #dddfe6;
+            border-radius: 3px;
+            margin-top: 20px;
+            height: calc(100% - 40px);
+            padding: 6px 0;
+        }
+    }
+}

+ 58 - 1
src/views/base/region.vue

@@ -54,6 +54,38 @@
         <template #action>
             <HcPages :pages="searchForm" @change="pageChange"/>
         </template>
+
+        <!--新增/编辑-->
+        <HcDialog isToBody bgColor="white" :show="rowModal" isTable widths="62rem" :title="formModel.id?'编辑':'新增'" @save="rowModalSave" @close="rowModalClose">
+            <div class="base-region-dialog">
+                <div class="dialog-form">
+                    <el-scrollbar>
+                        <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" size="large">
+                            <el-form-item label="编号:" prop="key1">
+                                <el-input v-model="formModel.key1"/>
+                            </el-form-item>
+                            <el-form-item label="名称:" prop="key2">
+                                <el-input v-model="formModel.key2"/>
+                            </el-form-item>
+                            <el-form-item label="备注:" prop="key3">
+                                <el-input v-model="formModel.key3"/>
+                            </el-form-item>
+                            <el-form-item label="关联用户" prop="key4">
+                                <HcTasksUser :contractId="0" :projectId="0" ui="w-full" @change="tasksUserChange"/>
+                            </el-form-item>
+                        </el-form>
+                    </el-scrollbar>
+                </div>
+                <div class="dialog-action">
+                    <div class="title">区域权限授权</div>
+                    <div class="data-tree-box">
+                        <el-scrollbar>
+                            <HcTreeData :isMenu="false" showCheckbox/>
+                        </el-scrollbar>
+                    </div>
+                </div>
+            </div>
+        </HcDialog>
     </HcCard>
 </template>
 
@@ -133,14 +165,39 @@ const tableSelectionChange = (rows) => {
     console.log(rows)
 }
 
+//弹窗
+const rowModal = ref(false)
+const formRef = ref(null)
+const formModel = ref({})
+const formRules = {
+    key1: [{required: true, message: '请输入名称', trigger: 'blur'}],
+}
+
+const tasksUserChange = (user) => {
+    console.log(user)
+}
+
 //新增
 const addRowClick = () => {
-
+    formModel.value = {}
+    rowModal.value = true
 }
 
 //编辑
 const editRowClick = (row) => {
+    formModel.value = row
+    rowModal.value = true
+}
+
+//保存
+const rowModalSave = () => {
+
+}
 
+//关闭弹窗
+const rowModalClose = () => {
+    rowModal.value = false
+    formModel.value = {}
 }
 </script>