From 235560b9d7cff1d7dce1f90a08df56d6ef8dd682 Mon Sep 17 00:00:00 2001
From: xiejun <xj@2023>
Date: 星期四, 15 六月 2023 10:27:42 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUserC.java                        |   43 +
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessStageAttrMapper.java               |   29 
 Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/NewAppConstantEnum.java      |    1 
 Source/UBCS-WEB/src/api/template/setPersonnel.js                                                                       |   35 +
 Source/UBCS-WEB/src/components/template/SetPersonnel.vue                                                               |  126 +++
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessStageAttr.java                     |   51 +
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessTemplateService.java              |   56 +
 Source/UBCS-WEB/vue.config.js                                                                                          |    4 
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowTaskUserController.java           |   56 +
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowTaskUserServiceImpl.java        |  146 ++++
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessStageAttrServiceImpl.java    |   81 ++
 Source/UBCS-WEB/src/views/system/user.vue                                                                              |    7 
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/controller/WorkController.java                 |   10 
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowMapper.java                           |    2 
 Source/UBCS-WEB/src/components/template/FlowPath.vue                                                                   |   19 
 Source/UBCS-WEB/src/views/flow/flowPath.vue                                                                            |   66 -
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/ProcessTSController.java              |  112 +++
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessTemplate.java                      |   48 +
 Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/ProcessTemplateTypeEnum.java |  134 +++
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessStageAttrService.java             |   39 +
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowEngineService.java                   |   10 
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUser.java                         |   51 +
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessTemplateServiceImpl.java     |  107 +++
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowProcessController.java            |   16 
 Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java           |   14 
 Source/UBCS-WEB/src/components/template/TableTransfer.vue                                                              |  106 +-
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowModelController.java              |    9 
 Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/MdmEngineService.java                       |   16 
 Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/service/impl/UserServiceImpl.java            |    2 
 Source/UBCS-WEB/src/components/template/Stage.vue                                                                      |   91 +-
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessTemplateMapper.java                |   30 
 Source/UBCS/ubcs-ops-api/ubcs-flow-api/pom.xml                                                                         |   13 
 Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/UserPwdstrategyController.java       |    1 
 Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java              |  272 ++++++-
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/service/impl/FlowBusinessServiceImpl.java      |    1 
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowEngineServiceImpl.java          |   61 +
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowTaskUserService.java                 |   54 +
 Source/UBCS/ubcs-service-api/ubcs-workflow-api/src/main/java/com/vci/ubcs/code/constant/FlowConstant.java              |   32 
 Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java                 |   26 
 Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowTaskUserMapper.java                   |   34 +
 Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/ICodeClassifyService.java                   |   14 
 41 files changed, 1,783 insertions(+), 242 deletions(-)

diff --git a/Source/UBCS-WEB/src/api/template/setPersonnel.js b/Source/UBCS-WEB/src/api/template/setPersonnel.js
new file mode 100644
index 0000000..ad7aa8b
--- /dev/null
+++ b/Source/UBCS-WEB/src/api/template/setPersonnel.js
@@ -0,0 +1,35 @@
+import request from '@/router/axios';
+
+// 浜哄憳璁剧疆鍒濆鍖�
+export const personnelInit = (params) => {
+  return request({
+    url: '/api/ubcs-flow/taskUser/list',
+    method: 'get',
+    params: params
+  })
+}
+// 浜哄憳璁剧疆鏀惰棌
+export const personnelCollect = (params) => {
+  return request({
+    url: '/api/ubcs-flow/taskUser/su',
+    method: 'get',
+    params: params
+  })
+}
+// 浜哄憳璁剧疆鍙栨秷鏀惰棌
+export const cancelCollect = (params) => {
+  return request({
+    url: '/api/ubcs-flow/taskUser/du',
+    method: 'get',
+    params: params
+  })
+}
+// 浜哄憳璁剧疆淇濆瓨
+export const personnelSave = (params) => {
+  return request({
+    url: '/api/',
+    method: 'post',
+    data: params
+  })
+}
+
diff --git a/Source/UBCS-WEB/src/components/template/FlowPath.vue b/Source/UBCS-WEB/src/components/template/FlowPath.vue
index 2d7a508..24ccf03 100644
--- a/Source/UBCS-WEB/src/components/template/FlowPath.vue
+++ b/Source/UBCS-WEB/src/components/template/FlowPath.vue
@@ -1,11 +1,9 @@
 <template>
-
         <avue-crud ref="crud" :table-loading="loading" :data="data" v-model="form" :option="option" :page.sync="page"
             :search.sync="search" @on-load="getDataList" @row-save="handleSave" @row-del="handleDelete"
             @row-update="handleEdit" @refresh-change="handleRefresh" @size-change="handleSizePage"
             @current-change="handleCurrentPage">
         </avue-crud>
-
 </template>
 
 <script>
@@ -19,11 +17,8 @@
             default: ""
         }
     },
-    watch: {
-    },
     data() {
         return {
-
             loading: false,
             page: {
                 currentPage: 1,
@@ -53,6 +48,7 @@
                     {
                         label: '妯℃澘key',
                         prop: 'modelKey',
+                        width:120,
                         sortable: true,
                         type: 'tree',
                         dicData: [],
@@ -74,19 +70,26 @@
                         label: '妯℃澘鍚嶇О',
                         prop: 'modelName',
                         sortable: true,
+                        width:220,
                         addDisabled: true,
                         editDisabled: true,
                     },
                     {
-                        label: '娴佺▼妯℃澘鐢ㄩ��',
+                        label: '妯℃澘鐢ㄩ��',
                         prop: 'buttonTypeKey',
                         type: 'tree',
+                        width:120,
                         dicUrl: '/api/ubcs-flow/processTS/tt',
                         dicMethod: 'post',
                         props: {
                             value: "codee",
                             label: "namee",
                         },
+                    },
+                    {
+                        label: '妯℃澘鎻忚堪',
+                        prop: 'description',
+                        type:'textarea'
                     },
                 ]
             },
@@ -143,8 +146,8 @@
         // 缂栬緫
         async handleEdit(row, index, done, loading) {
             console.log(row)
-            const { modelName, modelKey, buttonTypeKey, id } = row
-            let param = { modelName, modelKey, buttonTypeKey, id }
+            const { modelName, modelKey, buttonTypeKey, id ,description} = row
+            let param = { modelName, modelKey, buttonTypeKey, id,description }
             const response = await flowpathSave({ ...param, ...{ templateId: this.code } })
             if (response.status === 200) {
                 loading()
diff --git a/Source/UBCS-WEB/src/components/template/SetPersonnel.vue b/Source/UBCS-WEB/src/components/template/SetPersonnel.vue
new file mode 100644
index 0000000..beb1801
--- /dev/null
+++ b/Source/UBCS-WEB/src/components/template/SetPersonnel.vue
@@ -0,0 +1,126 @@
+<template>
+    <el-dialog :title="title" :visible.sync="dialogVisible" append-to-body="true" width="30%">
+        <el-tag v-for="tag in tags" :key="tag" closable effect="dark" @click="handleClickTag(tag)"
+            @close="handleCloseTag(tag)">
+            <span> {{ tag }}</span>
+        </el-tag>
+        <el-divider></el-divider>
+        <el-form :model="formInline" class="demo-form-inline" label-position="left">
+            <el-form-item :label="item.taskName" v-for="(item,index) in initFrom" :key="index">
+                <el-select v-model="formInline[index].userId" :placeholder="item.taskName">
+                    <el-option label="鍖哄煙涓�" value="shanghai"></el-option>
+                    <el-option label="鍖哄煙浜�" value="beijing"></el-option>
+                </el-select>
+            </el-form-item>
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+            <el-button @click="handleCancel">鍙� 娑�</el-button>
+            <el-button type="primary" @click="handleConfirm">纭� 瀹�</el-button>
+        </div>
+    </el-dialog>
+</template>
+<script>
+import { personnelInit, personnelCollect, cancelCollect, personnelSave } from '@/api/template/setPersonnel.js'
+export default {
+    name: 'SetPersonnel',
+    props: {
+        // 鏄惁鎵撳紑
+        visible: {
+            typeof: Boolean,
+            default: false
+        },
+        title: {
+            typeof: String,
+            default: '浜哄憳璁剧疆'
+        },
+        code:{
+            typeof: String,
+            default: ''
+        }
+    },
+    watch: {
+        visible(n) {
+            this.dialogVisible = n;
+        },
+        dialogVisible(n) {
+            this.$emit('update:visible', n)
+        },
+    },
+    data() {
+        return {
+            dialogVisible: this.visible,
+            initFrom: [],
+            tags: ['鏍囩1', '鏍囩2', '鏍囩3', '鏍囩4'],
+            formInline: []
+
+        }
+    },
+    mounted() {
+        this.apiInit()
+    },
+    methods: {
+        async apiInit() {
+            const response = await personnelInit({type:'PUBLIC',templateId:'8b5e2017-990f-454a-9c39-4c4eeeb57553'})
+            if (response.status === 200) {
+                console.log(response)
+                this.initFrom = response.data.data.user
+                this.formInline = response.data.data.user
+            }
+        },
+        async apiCollect() {
+            const response = await personnelCollect()
+            if (response.status === 200) {
+                console.log(response)
+            }
+        },
+        async canCollect(id) {
+            const response = await cancelCollect()
+            if (response.status === 200) {
+                console.log(response)
+            }
+        },
+        async apiSave() {
+            const response = await personnelSave()
+            if (response.status === 200) {
+                console.log(response)
+            }
+        },
+        handleClickTag(event) {
+            console.log(event)
+        },
+        handleCloseTag(event) {
+            console.log(event)
+            this.canCollect(event)
+        },
+        done() {
+            this.dialogVisible = false
+        },
+        handleCancel() {
+            this.done()
+        },
+        handleConfirm() {
+            // this.done()
+            console.log(this.formInline)
+        }
+    }
+}
+</script>
+<style lang="scss">
+.el-tag+.el-tag {
+    margin-left: 10px;
+}
+
+.button-new-tag {
+    margin-left: 10px;
+    height: 32px;
+    line-height: 30px;
+    padding-top: 0;
+    padding-bottom: 0;
+}
+
+.input-new-tag {
+    width: 90px;
+    margin-left: 10px;
+    vertical-align: bottom;
+}
+</style>
\ No newline at end of file
diff --git a/Source/UBCS-WEB/src/components/template/Stage.vue b/Source/UBCS-WEB/src/components/template/Stage.vue
index ef29b0f..31ee7b5 100644
--- a/Source/UBCS-WEB/src/components/template/Stage.vue
+++ b/Source/UBCS-WEB/src/components/template/Stage.vue
@@ -1,5 +1,5 @@
 <template>
-    <el-dialog title="妯℃澘闃舵" width="90%" append-to-body="true" :visible.sync="dialogVisible">
+    <div>
         <avue-crud ref="crud" :table-loading="loading" :data="data" :option="option" :page.sync="page"
             @on-load="getDataList" @size-change="handleSizePage" @current-change="handleCurrentPage"
             @row-click="handleRowClick">
@@ -17,9 +17,9 @@
                 </template>
             </avue-crud>
         </el-dialog>
-        <table-transfer :visible.sync="dialogTransfer" v-model="listVal" :dataList="tableData" :columns="columns"
-            keyName="oid" @save="handleSave"></table-transfer>
-    </el-dialog>
+        <table-transfer v-if="flag" :visible.sync="dialogTransfer" v-model="attributeValue" :dataList="attributeData"
+            :columns="columns" keyName="oid" @save="handleSave" @close="handelClose"></table-transfer>
+    </div>
 </template>
 
 <script>
@@ -31,11 +31,6 @@
         TableTransfer
     },
     props: {
-        // 鏄惁鎵撳紑
-        visible: {
-            typeof: Boolean,
-            default: false
-        },
         code: {
             typeof: String,
             required: true,
@@ -43,25 +38,7 @@
         }
     },
     watch: {
-        visible(n) {
-            this.dialogVisible = n;
-        },
-        dialogVisible(n) {
-            this.$emit('update:visible', n)
-        },
-    },
-    computed: {
-        tableData() {
-            return this.setTable()
-        },
-        listVal() {
-            let data = this.setTable()
-            let newdata = data.map(item => {
-                return item.checked ? item.oid : undefined
-            })
-            console.log(newdata.filter(item => item))
-            return newdata.filter(item => item)
-        }
+
     },
     data() {
         const options = {
@@ -81,9 +58,9 @@
             editBtn: false,
         }
         return {
-            list: [],
-            listRight: [],
-            dialogVisible: this.visible,
+            attributeData: [],
+            attributeValue: [],
+            flag: false,
             dialogTransfer: false,
             dialogNode: false,
             visibleTable: false,
@@ -136,14 +113,11 @@
             },
         }
     },
-    mounted() {
-        this.getAttributeList()
-    },
     methods: {
-        setTable() {
-            return this.list.map(item => {
-                if (this.listRight.length !== 0) {
-                    this.listRight.forEach(element => {
+        setTable(data, list) {
+            return data.map(item => {
+                if (list.length !== 0) {
+                    list.forEach(element => {
                         if (item.id === element.attrId) item.checked = true
                     });
                 }
@@ -178,12 +152,22 @@
         // 鑾峰彇鍏ㄩ儴灞炴��
         async getAttributeList() {
             const response = await attributeList({ 'conditionMap[classifyTemplateOid]': this.code })
-            if (response.status === 200) {
-                const data = response.data.data
-                this.list = data.records.map(item => {
+            const responseRight = await attributeListRight({ templateId: this.code, modelKey: this.modelKey, taskId: this.saveParam.taskId })
+            if (response.status === 200 && responseRight.status === 200) {
+                let datas = response.data.data.records
+                let dataRight = responseRight.data.data
+                datas = datas.map(item => {
                     const { oid, id, name, attributeGroup } = item
-                    return { oid, id, name, attributeGroup, ...{ checked: false } }
+                    item = { oid, id, name, attributeGroup, ...{ checked: false } }
+                    if (dataRight.length !== 0) {
+                        dataRight.forEach(element => { if (item.id === element.attrId) item.checked = true });
+                        return item
+                    }
                 })
+                let dataValue = datas.map(item => item.checked ? item.oid : undefined)
+                this.attributeValue = dataValue.filter(item => item)
+                this.attributeData = datas
+                this.flag = true
             }
         },
         // 鑾峰彇宸蹭繚瀛樺睘鎬�
@@ -205,17 +189,12 @@
             this.saveParam.modelKey = row.modelKey
         },
         handleMaintenanceTransfer(row) {
-            console.log(row)
-            this.dialogTransfer = true
             this.saveParam.taskId = row.taskId
             this.saveParam.taskName = row.taskName
-            this.getAttributeListRight()
-        },
-        handleSizePage(event) {
-            this.page.pageSize = event
-        },
-        handleCurrentPage(event) {
-            this.page.currentPage = event
+            this.getAttributeList()
+            this.$nextTick(() => {
+                this.dialogTransfer = true
+            })
         },
         handleRowClick(row) {
             console.log(row)
@@ -224,10 +203,12 @@
             this.dialogNode = true
         },
         handleRowStageClick(row) {
-            this.dialogTransfer = true
             this.saveParam.taskId = row.taskId
             this.saveParam.taskName = row.taskName
-            this.getAttributeListRight()
+            this.getAttributeList()
+            this.$nextTick(() => {
+                this.dialogTransfer = true
+            })
         },
         async handleSave(event) {
             console.log(event)
@@ -250,9 +231,13 @@
                     type: 'success',
                     message: '鏂板鏁版嵁鎴愬姛锛�'
                 })
+                this.flag = false
                 // done()
                 // this.getDataList()
             }
+        },
+        handelClose() {
+            this.flag = false
         }
     }
 }
diff --git a/Source/UBCS-WEB/src/components/template/TableTransfer.vue b/Source/UBCS-WEB/src/components/template/TableTransfer.vue
index 488fb95..abedd0d 100644
--- a/Source/UBCS-WEB/src/components/template/TableTransfer.vue
+++ b/Source/UBCS-WEB/src/components/template/TableTransfer.vue
@@ -1,5 +1,5 @@
 <template>
-    <el-dialog :title="title" width="70%" append-to-body="true" :visible.sync="dialogVisible">
+    <el-dialog :title="title" width="70%" append-to-body="true" :visible.sync="dialogVisible" @close="handelClose">
         <el-row :gutter="20">
             <el-col :span="11">
                 <el-card class="box-card">
@@ -8,9 +8,9 @@
                         <el-input class="input" v-if="showSearch" v-model="searchLeft" placeholder="璇疯緭鍏ユ悳绱㈠唴瀹�"
                             @keyup.enter.native="handleEnter"></el-input>
                     </div>
-                    <el-table ref="transferLeftTable" :data="leftData" height="500" highlight-current-row
-                        tooltip-effect="dark" @selection-change="handleLeftSelectionChange" @row-click="handleLeftRowClick">
-                        <el-table-column type="selection" width="50" align="center" fixed="left" :selectable="selectable" />
+                    <el-table ref="transferTable" :data="leftData" height="500" highlight-current-row tooltip-effect="dark"
+                        @selection-change="handleLeftSelectionChange" @row-click="handleLeftRowClick">
+                        <el-table-column type="selection" width="50" align="center" fixed="left" />
                         <div v-for="(item, index) in columns" :key="index">
                             <el-table-column v-if="item.visible" :label="item.label" align="center" :prop="item.key" />
                         </div>
@@ -74,7 +74,7 @@
         //涓婚敭key鍊�
         keyName: {
             type: String,
-            default: "id",
+            default: "oid",
         },
         columns: {
             type: Array,
@@ -116,17 +116,12 @@
             },
             deep: true,
         },
-        dataList: {
-            handler(data) {
-                console.log(data)
-
-            },
-            deep: true,
-        }
     },
     data() {
         return {
             dialogVisible: this.visible,
+            indeterminate: false,
+            isCheck: false,
             searchLeft: "",
             leftIds: [],
             leftMultiple: true,
@@ -141,25 +136,26 @@
     },
     mounted() {
         this.init();
+        console.log(this.$refs.transferTable)
     },
     methods: {
-        selectable(row, index) {
-            console.log(row)
-            return row.checked === false //涓簍rue鐨勬椂鍊欏彲浠ラ�夛紝涓篺alse鍒欎笉鍙�夋嫨
-        },
         init() {
-            this.rightIds = this.value;
-            console.log(this.rightIds)
-            for (let i = 0; i < this.dataList.length; i++) {
-                if (this.value.some((item) => item == this.dataList[i][this.keyName])) {
-                    this.rightDataList.push(this.dataList[i]);
-                } else {
-                    this.leftDataList.push(this.dataList[i]);
+            let that = this
+            that.rightIds = that.value;
+            for (let i = 0; i < that.dataList.length; i++) {
+                if (that.value.some((item) => item == that.dataList[i][that.keyName])) {
+                    that.rightDataList.push(that.dataList[i]);
                 }
+                // else{
+                //     that.leftDataList.push(that.dataList[i])
+                // }
+                that.leftDataList.push(that.dataList[i])
+
             }
-            this.leftData = [...this.leftDataList];
-            this.rightData = [...this.rightDataList];
+            that.leftData = [...that.leftDataList];
+            that.rightData = [...that.rightDataList];
         },
+
         // left澶氶�夋閫変腑鏁版嵁
         handleLeftSelectionChange(selection) {
             this.leftIds = selection.map((item) => item[this.keyName]);
@@ -176,21 +172,26 @@
                 let a = this.leftIds.findIndex(
                     (item) => item == this.leftDataList[i][this.keyName]
                 );
-                console.log(a)
                 if (a !== -1) {
-                    this.rightDataList.push(this.leftDataList[i]);
-                    // this.leftDataList[i].checked = true
-                    // this.$refs.transferLeftTable.toggleRowSelection(this.leftDataList[i],true)
-                    this.$delete(this.leftDataList, i);
-                    i--;
+                    let moveLefti = this.leftDataList[i];//宸﹁竟缃楄繃鏉ョ殑
+                    let moveLeftiKey = moveLefti['id'];
+                    let isMove = true;
+                    for (let j = 0; j < this.rightDataList.length; j++) {
+                        let rifhtDataListi = this.rightDataList[j];//鍙宠竟寰幆鍑烘潵鐨勬瘡涓�涓�
+                        let rightDataListiKey = rifhtDataListi['id'];//姣忎竴涓猭ey
+                        if (rightDataListiKey == moveLeftiKey) {
+                            isMove = false;
+                            break;
+                        }
+                    }
+                    if (isMove) {
+                        this.rightDataList.push(this.leftDataList[i]);
+                        this.leftDataList[i].checked = true
+                        // this.$delete(this.leftDataList, i);
+                        // i--;
+                    }
                 }
             }
-            // let obj = {}
-            // let filterright = this.rightDataList.reduce((cur, next) => {
-            //     obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
-            //     return cur;
-            // }, [])
-            // console.log('filterright', filterright)
             this.leftData = this.setData(this.leftDataList, this.searchLeft);
             this.rightData = this.setData(this.rightDataList, this.searchRight);
             this.$emit(
@@ -205,17 +206,13 @@
                     (item) => item == this.rightDataList[i][this.keyName]
                 );
                 if (a !== -1) {
-                    this.leftDataList.push(this.rightDataList[i]);
+                    this.leftDataList[i].checked = false
+                    // this.leftDataList.push(this.rightDataList[i]);
                     this.$delete(this.rightDataList, i);
                     i--;
                 }
             }
-            // let obj = {}
-            // let filterleft = this.leftDataList.reduce((cur, next) => {
-            //     obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
-            //     return cur;
-            // }, [])
-            // console.log('filterright', filterleft)
+            console.log(this.rightDataList)
             this.leftData = this.setData(this.leftDataList, this.searchLeft);
             this.rightData = this.setData(this.rightDataList, this.searchRight);
             this.$emit(
@@ -233,9 +230,9 @@
         // 鍗曢��
         handleLeftRowClick(row) {
             if (this.leftData) {
-                this.$refs.transferLeftTable.toggleRowSelection(row)
+                this.$refs.transferTable.toggleRowSelection(row)
             } else {
-                this.$refs.transferLeftTable.clearSelection()
+                this.$refs.transferTable.clearSelection()
             }
         },
         // 鍗曢��
@@ -268,16 +265,23 @@
             console.log(this.value)
         },
         done() {
+            this.leftData = []
+            this.leftDataList = []
+            this.rightDataList = []
+            this.rightData = []
             this.dialogVisible = false
         },
         tableTransferSave() {
             this.$emit('save', this.rightData)
-            this.leftData = [...this.rightData, ...this.leftData]
-            this.leftDataList = [...this.rightDataList, ...this.leftDataList]
-            this.rightDataList = []
-            this.rightData = []
+            this.done()
 
-        }
+
+        },
+        // 鍏抽棴娓呴櫎鎵�鏈夋暟鎹�
+        handelClose() {
+            this.$emit('close')
+            this.done()
+        },
     },
 }
 </script>
diff --git a/Source/UBCS-WEB/src/views/flow/flowPath.vue b/Source/UBCS-WEB/src/views/flow/flowPath.vue
index 2040668..15db06e 100644
--- a/Source/UBCS-WEB/src/views/flow/flowPath.vue
+++ b/Source/UBCS-WEB/src/views/flow/flowPath.vue
@@ -1,82 +1,34 @@
 <template>
     <div>
         <el-button @click="outerVisible = true">娴佺▼娴嬭瘯</el-button>
-        <el-button @click="visibleFlow = true">妯℃澘娴佺▼</el-button>
-        <el-button @click="visibleStage = true">妯℃澘闃舵</el-button>
-        <el-button @click="visibleTable = true">table绌挎妗�</el-button>
+        <el-button @click="handleTable">浜哄憳璁剧疆</el-button>
         <flow-business :visible.sync="outerVisible"></flow-business>
-        <flow-path :visible.sync="visibleFlow" code="8b5e2017-990f-454a-9c39-4c4eeeb57553"></flow-path>
-        <stage :visible.sync="visibleStage" code="8b5e2017-990f-454a-9c39-4c4eeeb57553"></stage>
-        <table-transfer :visible.sync="visibleTable" v-model="value" :dataList="list" :columns="columns" keyName="id"
-            @change="change"></table-transfer>
+       <set-personnel :visible.sync="visibleFlow"></set-personnel>
     </div>
 </template>
 
 <script>
 import FlowBusiness from '@/components/template/Business'
-import FlowPath from '@/components/template/FlowPath'
-import Stage from '@/components/template/Stage'
-import TableTransfer from '@/components/template/TableTransfer'
+import SetPersonnel from '@/components/template/SetPersonnel'
 export default {
     components: {
         FlowBusiness,
-        FlowPath,
-        Stage,
-        TableTransfer
+        SetPersonnel
     },
     data() {
-        const getTables = () => {
-            let data = []
-            for (let i = 0; i < 5; i++) {
-                let item = {
-                    id: `${i+1}`,
-                    name: 'name',
-                    address: '闆嗗洟鐮�',
-                    data:'',
-                    checked:false,
-                }
-                data.push(item)
-            }
-            return data
-        }
         return {
-            list: getTables(),
-            value: [],
             outerVisible: false,
             visibleFlow: false,
-            visibleStage: false,
-            visibleTable: false,
-
-            columns: [
-                {
-                    key: "id",
-                    label: "id",
-                    visible: false,
-                },
-                {
-                    key: "name",
-                    label: "灞炴�х紪鍙�",
-                    visible: true,
-                },
-                {
-                    key: "address",
-                    label: "灞炴�у悕绉�",
-                    visible: true,
-                },
-                {
-                    key: "address",
-                    label: "灞炴�у垎缁�",
-                    visible: true,
-                },
-            ],
 
         }
     },
     methods: {
-        change(val) {
-            console.log(val);
-            console.log(this.value)
+        handleSave(event) {
+            console.log(event)
         },
+        handleTable(){
+            this.visibleFlow = true
+        }
     }
 }
 </script>
diff --git a/Source/UBCS-WEB/src/views/system/user.vue b/Source/UBCS-WEB/src/views/system/user.vue
index dc8e091..2114440 100644
--- a/Source/UBCS-WEB/src/views/system/user.vue
+++ b/Source/UBCS-WEB/src/views/system/user.vue
@@ -778,10 +778,10 @@
       })
        //瑕佷紶閫掔殑id锛屼竴涓槸鏁扮粍鍙︿竴涓槸瀛楃涓�
        this.UserPwdstrategyVO.userIds=this.selid;
-       this.UserPwdstrategyVO.pwdstrategyId=this.id;
+       this.UserPwdstrategyVO.pwdstrategyId=this.id
 
       //璇锋眰
-      insert(this.UserPwdstrategyVO).then(()=>{
+      insert(this.UserPwdstrategyVO.userIds).then(()=>{
         this.passVisible=false
         this.$message({
           type: "success",
@@ -968,9 +968,10 @@
       if (this.selectionList.length === 1) {
         this.roleTreeObj = this.selectionList[0].roleId.split(",");
       }
-      getRoleTree(this.selectionList[0].tenantId).then(res => {
+      getRoleTree().then(res => {
         this.roleGrantList = res.data.data;
         this.roleBox = true;
+
       });
     },
     handlePlatform() {
diff --git a/Source/UBCS-WEB/vue.config.js b/Source/UBCS-WEB/vue.config.js
index 016eb50..332410b 100644
--- a/Source/UBCS-WEB/vue.config.js
+++ b/Source/UBCS-WEB/vue.config.js
@@ -26,12 +26,12 @@
     proxy: {
       '/api': {
         //鏈湴鏈嶅姟鎺ュ彛鍦板潃
-         target: 'http://localhost:37000',
+        //  target: 'http://localhost:37000',
         // target: 'http://192.168.1.51:37000',
         // target: 'http://192.168.1.46:37000',
         // target: 'http://dev.vci-tech.com:37000',
         // target: 'http://192.168.1.51:37000/',
-        //   target: 'http://localhost:37000',
+          target: 'http://192.168.1.104:37000',
         // target: 'http://192.168.1.63:37000',
         //target: 'http://192.168.3.7:37000',
         // target: 'http://dev.vci-tech.com:37000',
diff --git a/Source/UBCS/ubcs-ops-api/ubcs-flow-api/pom.xml b/Source/UBCS/ubcs-ops-api/ubcs-flow-api/pom.xml
index 577f1eb..20ac791 100644
--- a/Source/UBCS/ubcs-ops-api/ubcs-flow-api/pom.xml
+++ b/Source/UBCS/ubcs-ops-api/ubcs-flow-api/pom.xml
@@ -14,6 +14,19 @@
     <version>${bladex.project.version}</version>
     <packaging>jar</packaging>
 
+    <dependencies>
+        <dependency>
+            <groupId>com.vci.ubcs</groupId>
+            <artifactId>ubcs-util-api</artifactId>
+            <version>3.0.1.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>com.vci.ubcs</groupId>
+            <artifactId>ubcs-user-api</artifactId>
+            <version>3.0.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
 
 
 </project>
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/controller/WorkController.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/controller/WorkController.java
index a3d1c0a..69b118f 100644
--- a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/controller/WorkController.java
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/controller/WorkController.java
@@ -27,13 +27,23 @@
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
+import org.flowable.engine.RepositoryService;
+import org.flowable.engine.RuntimeService;
 import org.flowable.engine.TaskService;
+import org.flowable.engine.repository.Deployment;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.task.api.Task;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.tenant.annotation.NonDS;
 import org.springblade.core.tool.api.R;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * 娴佺▼浜嬪姟閫氱敤鎺ュ彛
  *
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/service/impl/FlowBusinessServiceImpl.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/service/impl/FlowBusinessServiceImpl.java
index c78baca..a84b86b 100644
--- a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/service/impl/FlowBusinessServiceImpl.java
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/business/service/impl/FlowBusinessServiceImpl.java
@@ -263,6 +263,7 @@
 			variables = Kv.create();
 		}
 		variables.put(ProcessConstant.PASS_KEY, flow.isPass());
+		variables.put("yn","y");
 		// 瀹屾垚浠诲姟
 		taskService.complete(taskId, variables);
 		return true;
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowModelController.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowModelController.java
index 5e3e781..b974022 100644
--- a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowModelController.java
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowModelController.java
@@ -18,15 +18,20 @@
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.vci.ubcs.flow.core.utils.TaskUtil;
 import com.vci.ubcs.flow.engine.entity.FlowModel;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
 import com.vci.ubcs.flow.engine.service.FlowEngineService;
+import com.vci.ubcs.flow.engine.service.FlowTaskUserService;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.AllArgsConstructor;
+import org.springblade.core.launch.constant.FlowConstant;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tenant.annotation.NonDS;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
@@ -44,7 +49,7 @@
 @RestController
 @RequestMapping("model")
 @AllArgsConstructor
-//@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
+//@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)t
 public class FlowModelController {
 
 	private final FlowEngineService flowEngineService;
@@ -63,6 +68,8 @@
 		IPage<FlowModel> pages = flowEngineService.page(Condition.getPage(query), Condition.getQueryWrapper(flow, FlowModel.class)
 			.select("id,model_key modelKey,name,description,version,created,last_updated lastUpdated")
 			.orderByDesc("last_updated"));
+
+		flowEngineService.getNodeByFlowableKey("process_t");
 		return R.data(pages);
 	}
 
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowProcessController.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowProcessController.java
index a9329c2..73a1a3f 100644
--- a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowProcessController.java
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowProcessController.java
@@ -20,6 +20,12 @@
 import com.vci.ubcs.flow.engine.service.FlowEngineService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.flowable.bpmn.model.FlowElement;
+import org.flowable.bpmn.model.SubProcess;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.engine.*;
 import org.springblade.core.tenant.annotation.NonDS;
 import org.springblade.core.tool.api.R;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -28,7 +34,10 @@
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 娴佺▼閫氱敤鎺у埗鍣�
@@ -44,6 +53,12 @@
 
 	private static final String IMAGE_NAME = "image";
 	private final FlowEngineService flowEngineService;
+
+	private final RepositoryService repositoryService;
+	private final RuntimeService runtimeService;
+	private final HistoryService historyService;
+	private final TaskService taskService;
+	private final ProcessEngine processEngine;
 
 	/**
 	 * 鑾峰彇娴佽浆鍘嗗彶鍒楄〃
@@ -65,6 +80,7 @@
 	 */
 	@GetMapping(value = "model-view")
 	public R modelView(String processDefinitionId, String processInstanceId) {
+
 		return R.data(flowEngineService.modelView(processDefinitionId, processInstanceId));
 	}
 
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowTaskUserController.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowTaskUserController.java
new file mode 100644
index 0000000..8aaba6c
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/FlowTaskUserController.java
@@ -0,0 +1,56 @@
+package com.vci.ubcs.flow.engine.controller;
+
+import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
+import com.vci.ubcs.flow.engine.service.FlowEngineService;
+import com.vci.ubcs.flow.engine.service.FlowTaskUserService;
+import lombok.AllArgsConstructor;
+import org.springblade.core.tenant.annotation.NonDS;
+import org.springblade.core.tool.api.R;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * 娴佺▼task瀹℃壒鎺у埗
+ *
+ * @author wang1
+ */
+@NonDS
+@RestController
+@RequestMapping("taskUser")
+@AllArgsConstructor
+public class FlowTaskUserController {
+
+	private final FlowTaskUserService taskUserService;
+
+	/**
+	 * 娴佺▼task瀹℃壒浜哄憳鍒楄〃
+	 * @return
+	 */
+	@GetMapping("list")
+	public R<FlowTaskUserC> list() {
+		return R.data(taskUserService.getUser());
+	}
+
+	/**
+	 * 鏂板銆佷慨鏀逛换鍔″鐞嗕汉鍛�
+	 * @param flowTaskUserC
+	 * @return
+	 */
+	@PostMapping("su")
+	public R<String> saveUser(@RequestBody FlowTaskUserC flowTaskUserC) {
+		taskUserService.saveOrUpdateUser(flowTaskUserC);
+		return R.success("淇濆瓨鎴愬姛");
+	}
+
+	/**
+	 * 鍒犻櫎浠诲姟澶勭悊浜哄憳
+	 * @param flowTaskUserC
+	 * @return
+	 */
+	@PostMapping("du")
+	public R<String> deleteUser(@RequestBody FlowTaskUserC flowTaskUserC) {
+		taskUserService.deleteUser(flowTaskUserC.getName());
+		return R.success("鍒犻櫎鎴愬姛");
+	}
+
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/ProcessTSController.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/ProcessTSController.java
new file mode 100644
index 0000000..4bf34b9
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/controller/ProcessTSController.java
@@ -0,0 +1,112 @@
+package com.vci.ubcs.flow.engine.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
+import com.vci.ubcs.flow.engine.entity.ProcessStageAttr;
+import com.vci.ubcs.flow.engine.entity.ProcessTemplate;
+import com.vci.ubcs.flow.engine.service.FlowEngineService;
+import com.vci.ubcs.flow.engine.service.ProcessStageAttrService;
+import com.vci.ubcs.flow.engine.service.ProcessTemplateService;
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tenant.annotation.NonDS;
+import org.springblade.core.tool.api.R;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *娴佺▼妯℃澘銆佹祦绋嬮樁娈垫帶鍒� processTemplate processStage
+ *
+ * @author wang1
+ */
+@NonDS
+@RestController
+@RequestMapping("processTS")
+@AllArgsConstructor
+public class ProcessTSController {
+
+	private final FlowEngineService flowEngineService;
+	private final ProcessTemplateService processTemplateService;
+	private final ProcessStageAttrService processStageAttrService;
+
+	/**
+	 * 娴佺▼妯℃澘鍒嗛〉
+	 */
+	@GetMapping("/tlist")
+	public R<IPage<ProcessTemplate>> tlist(@RequestParam Map<String, Object> flow, Query query) {
+		IPage<ProcessTemplate> pages = processTemplateService.page(Condition.getPage(query), Condition.getQueryWrapper(flow, ProcessTemplate.class)
+			.select("id,model_key modelKey,model_name modelName,button_Type_Key buttonTypeKey,button_Type_value buttonTypeValue")
+			.orderByDesc("last_updated"));
+		return R.data(pages);
+	}
+
+	/**
+	 * 娴佺▼妯℃澘鐢ㄩ�斿睘鎬�
+	 * @return
+	 */
+	@PostMapping("tt")
+	public R<List<Map<String,String>>> processTemplateType() {
+		return R.data(processTemplateService.processTemplateType());
+	}
+
+	/**
+	 * 娴佺▼妯℃澘鏂板銆佷慨鏀�
+	 * @param processTemplate
+	 * @return
+	 */
+	@PostMapping("tsou")
+	public R<ProcessTemplate> processTemplateSaveOrUpdate(@RequestBody ProcessTemplate processTemplate) {
+		processTemplateService.saveOrUpdateUser(processTemplate);
+		return R.success("淇濆瓨鎴愬姛");
+	}
+
+	/**
+	 * 娴佺▼妯℃澘鍒犻櫎
+	 * @param processTemplate
+	 * @return
+	 */
+	@DeleteMapping("dt")
+	public R<ProcessTemplate> deleteProcessTemplate(ProcessTemplate processTemplate) {
+		processTemplateService.deleteProcessTemplate(processTemplate.getId());
+		return R.success("鍒犻櫎鎴愬姛");
+	}
+
+	/**
+	 * 娴佺▼闃舵锛岃繖涓祦绋嬬殑鍚勪釜鑺傜偣
+	 */
+	@GetMapping("/sslist")
+	public R<List<Map<String,String>>> sslist(@RequestParam String modelKey) {
+		return R.data(flowEngineService.getNodeByFlowableKey(modelKey));
+	}
+
+	/**
+	 * 娴佺▼闃舵锛岃繖涓祦绋�,杩欎釜鑺傜偣锛岀粦瀹氱殑灞炴��
+	 */
+	@GetMapping("/ssslist")
+	public R<List<ProcessStageAttr>> ssslist(@RequestParam String templateId,@RequestParam String modelKey,@RequestParam String taskId) {
+		Map<String, Object> m = new HashMap<>();
+		m.put("template_id", templateId);
+		m.put("task_id", taskId);
+		m.put("model_key", modelKey);
+		QueryWrapper q = Condition.getQueryWrapper(m, ProcessStageAttr.class)
+			.select("attr_id attrId,attr_name attrName,attr_group attrGroup");
+		return R.data(processStageAttrService.list(q));
+	}
+
+	/**
+	 * 妯℃澘闃舵灞炴�ф柊澧炪�佷慨鏀�
+	 * @param flowTaskUserC
+	 * @return
+	 */
+	@PostMapping("sasou")
+	public R<ProcessTemplate> stageAttributeSaveOrUpdate(@RequestBody FlowTaskUserC flowTaskUserC) {
+		processStageAttrService.saveOrUpdateUser(flowTaskUserC);
+		return R.success("淇濆瓨鎴愬姛");
+	}
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUser.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUser.java
new file mode 100644
index 0000000..dde1fb2
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUser.java
@@ -0,0 +1,51 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.vci.ubcs.flow.core.utils.TaskUtil;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 娴佺▼姣忎竴涓妭鐐瑰鏍镐汉
+ *
+ * @author wang1
+ */
+@Data
+@TableName("ACT_DE_TASK_USER")
+public class FlowTaskUser implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	private String id;
+	private String name;//淇濆瓨鐨勮繖涓敹钘忓悕绉�
+	private String modelKey;
+	private String classifyId;
+	private String templateId;
+	private String taskId;//娴佺▼taskid
+	private String taskName;
+	private String userId;
+	private String userName;
+	private String description;
+	private Date created;
+	private Date lastUpdated;
+	private String createdBy;
+	private String lastUpdatedBy;
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUserC.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUserC.java
new file mode 100644
index 0000000..9e862db
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/FlowTaskUserC.java
@@ -0,0 +1,43 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 娴佺▼鑺傜偣瀹℃牳浜烘敹钘�
+ *
+ * @author wang1
+ */
+@Data
+public class FlowTaskUserC implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	private String createdBy;
+	private String name;//淇濆瓨鐨勮繖涓敹钘忓悕绉�
+	private String modelKey;
+	private String classifyId;
+	private String templateId;
+	private String taskId;//闃舵id锛屽氨鏄祦绋媡askid
+	private String taskName;//闃舵鍚嶇О
+	private List<FlowTaskUser> flowTaskUsers;//姣忎釜鑺傜偣鏀惰棌浜�
+	private List<ProcessStageAttr> processStageAttr;//娴佺▼闃舵淇濆瓨鐨勫睘鎬�
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessStageAttr.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessStageAttr.java
new file mode 100644
index 0000000..04fa1e8
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessStageAttr.java
@@ -0,0 +1,51 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 娴佺▼闃舵
+ *
+ * @author wang1
+ */
+@Data
+@TableName("ACT_DE_PROCESS_STAGE_ATTR")
+public class ProcessStageAttr implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	private String id;
+	private String modelKey;
+	private String classifyId;
+	private String templateId;
+	private String taskId;//闃舵id锛屽氨鏄祦绋媡askid
+	private String taskName;//闃舵鍚嶇О
+	private String attrOid;//灞炴�ц繖鏉℃暟鎹殑id
+	private String attrId;//灞炴�ц繖鏉℃暟鎹殑oid
+	private String attrName;//灞炴�т腑鏂囧悕绉�
+	private String attrGroup;//灞炴�у垎缁�
+	private String description;
+	private Date created;
+	private Date lastUpdated;
+	private String createdBy;
+	private String lastUpdatedBy;
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessTemplate.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessTemplate.java
new file mode 100644
index 0000000..1b69fd8
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/entity/ProcessTemplate.java
@@ -0,0 +1,48 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 娴佺▼妯℃澘
+ *
+ * @author wang1
+ */
+@Data
+@TableName("ACT_DE_PROCESS_TEMPLATE")
+public class ProcessTemplate implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	private String id;
+	private String templateId;//褰撳墠妯℃澘id
+	private String modelKey;//娴佺▼妯″瀷key,閮ㄧ讲key
+	private String modelName;//閮ㄧ讲娴佺▼鍚嶇О
+	private String buttonTypeKey;//搴旂敤鎸夐挳,ProcessTemplateTypeEnum鐨刱ey
+	private String buttonTypeValue;//搴旂敤鎸夐挳,ProcessTemplateTypeEnum鐨剉alue
+	private String description;
+	private Date created;
+	private Date lastUpdated;
+	private String createdBy;
+	private String lastUpdatedBy;
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowMapper.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowMapper.java
index 8ac1cc3..7ec4095 100644
--- a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowMapper.java
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowMapper.java
@@ -19,6 +19,7 @@
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.vci.ubcs.flow.engine.entity.FlowModel;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -43,4 +44,5 @@
 	 * @return
 	 */
 	List<FlowModel> findByParentModelId(String parentModelId);
+
 }
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowTaskUserMapper.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowTaskUserMapper.java
new file mode 100644
index 0000000..9ed1e12
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/FlowTaskUserMapper.java
@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.vci.ubcs.flow.engine.entity.FlowModel;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 娴佺▼闃舵瀹℃牳浜哄憳
+ *
+ * @author wang1
+ */
+public interface FlowTaskUserMapper extends BaseMapper<FlowTaskUser> {
+
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessStageAttrMapper.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessStageAttrMapper.java
new file mode 100644
index 0000000..f3cf847
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessStageAttrMapper.java
@@ -0,0 +1,29 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.vci.ubcs.flow.engine.entity.ProcessStageAttr;
+
+/**
+ * 娴佺▼闃舵
+ *
+ * @author wang1
+ */
+public interface ProcessStageAttrMapper extends BaseMapper<ProcessStageAttr> {
+
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessTemplateMapper.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessTemplateMapper.java
new file mode 100644
index 0000000..574fd9d
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/mapper/ProcessTemplateMapper.java
@@ -0,0 +1,30 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
+import com.vci.ubcs.flow.engine.entity.ProcessTemplate;
+
+/**
+ * 娴佺▼妯℃澘
+ *
+ * @author wang1
+ */
+public interface ProcessTemplateMapper extends BaseMapper<ProcessTemplate> {
+
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowEngineService.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowEngineService.java
index 2955619..9ea5718 100644
--- a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowEngineService.java
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowEngineService.java
@@ -23,6 +23,7 @@
 import com.vci.ubcs.flow.engine.entity.FlowModel;
 import com.vci.ubcs.flow.engine.entity.FlowProcess;
 import org.springframework.web.multipart.MultipartFile;
+import org.w3c.dom.Document;
 
 import javax.servlet.http.HttpServletResponse;
 import java.util.List;
@@ -163,4 +164,13 @@
 	 * @return
 	 */
 	byte[] getModelEditorXML(FlowModel model);
+
+	/**
+	 * 鏍规嵁娴佺▼妯″瀷key鑾峰彇XML涓妭鐐归厤缃殑澶勭悊浜�,璇诲彇鑺傜偣鍚嶇О鍜岄厤缃殑鍊硷紝娴佺▼妯″瀷key宸茬粡闄愬埗涓嶉噸澶�
+	 *
+	 * @param key
+	 * @return
+	 */
+	List<Map<String,String>> getNodeByFlowableKey(String key);
+
 }
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowTaskUserService.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowTaskUserService.java
new file mode 100644
index 0000000..a7ba9b4
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/FlowTaskUserService.java
@@ -0,0 +1,54 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.vci.ubcs.flow.core.entity.BladeFlow;
+import com.vci.ubcs.flow.engine.entity.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * FlowService
+ *
+ * @author wang1
+ */
+public interface FlowTaskUserService extends IService<FlowTaskUser> {
+
+	/**
+	 * 鏌ヨ褰撳墠鐧婚檰浜哄杩欎釜娴佺▼鐨則askUser
+	 * @return
+	 */
+	FlowTaskUserC getUser();
+
+	/**
+	 * 鏂板/淇敼娴佺▼鑺傜偣瀹℃牳浜洪厤缃�佸苟涓斾慨鏀规祦绋媥ml閮ㄧ讲鏂囦欢
+	 * @param flowTaskUserC
+	 * @return
+	 */
+	void saveOrUpdateUser(FlowTaskUserC flowTaskUserC);
+
+	/**
+	 * 鍒犻櫎娴佺▼瀹℃牳浜哄憳
+	 * @param name
+	 */
+	void deleteUser(String name);
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessStageAttrService.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessStageAttrService.java
new file mode 100644
index 0000000..703a55f
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessStageAttrService.java
@@ -0,0 +1,39 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
+import com.vci.ubcs.flow.engine.entity.ProcessStageAttr;
+
+import java.util.List;
+
+/**
+ * 娴佺▼闃舵鏈嶅姟
+ *
+ * @author wang1
+ */
+public interface ProcessStageAttrService extends IService<ProcessStageAttr> {
+
+	/**
+	 * 鏂板/淇敼娴佺▼闃舵
+	 * @param flowTaskUserC
+	 * @return
+	 */
+	void saveOrUpdateUser(FlowTaskUserC flowTaskUserC);
+
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessTemplateService.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessTemplateService.java
new file mode 100644
index 0000000..119f6ac
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/ProcessTemplateService.java
@@ -0,0 +1,56 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
+import com.vci.ubcs.flow.engine.entity.ProcessTemplate;
+import com.vci.ubcs.starter.web.enumpck.ProcessTemplateTypeEnum;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴佺▼妯℃澘鏈嶅姟
+ *
+ * @author wang1
+ */
+public interface ProcessTemplateService extends IService<ProcessTemplate> {
+
+	/**
+	 * 鏂板/淇敼娴佺▼妯℃澘
+	 * @param processTemplate
+	 * @return
+	 */
+	void saveOrUpdateUser(ProcessTemplate processTemplate);
+
+	/**
+	 * 鍒犻櫎娴佺▼妯℃澘
+	 * @param id
+	 * @return
+	 */
+	void deleteProcessTemplate(String id);
+
+	/**
+	 * 娴佺▼妯℃澘鐢ㄩ��
+	 * @return
+	 */
+	List<Map<String,String>> processTemplateType();
+
+
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowEngineServiceImpl.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowEngineServiceImpl.java
index 7eb8c9b..a11071e 100644
--- a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowEngineServiceImpl.java
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowEngineServiceImpl.java
@@ -16,6 +16,8 @@
  */
 package com.vci.ubcs.flow.engine.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -34,9 +36,11 @@
 import com.vci.ubcs.system.user.entity.User;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.flowable.bpmn.converter.BpmnXMLConverter;
-import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.*;
 import org.flowable.bpmn.model.Process;
 import org.flowable.common.engine.impl.util.IoUtil;
 import org.flowable.common.engine.impl.util.io.StringStreamSource;
@@ -47,6 +51,7 @@
 import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
 import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
 import org.flowable.engine.repository.Deployment;
+import org.flowable.engine.repository.DeploymentQuery;
 import org.flowable.engine.repository.ProcessDefinition;
 import org.flowable.engine.repository.ProcessDefinitionQuery;
 import org.flowable.engine.runtime.ProcessInstance;
@@ -54,6 +59,7 @@
 import org.flowable.engine.task.Comment;
 import org.flowable.image.ProcessDiagramGenerator;
 import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.support.Condition;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.FileUtil;
@@ -61,11 +67,17 @@
 import org.springblade.core.tool.utils.StringUtil;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
+import org.w3c.dom.*;
+import org.xml.sax.InputSource;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.StringReader;
 import java.util.*;
 
 /**
@@ -90,6 +102,12 @@
 	private final HistoryService historyService;
 	private final TaskService taskService;
 	private final ProcessEngine processEngine;
+
+	/**
+	 * 鏁版嵁鎿嶄綔瀵硅薄
+	 */
+	@Resource
+	private FlowMapper flowMapper;
 
 	@Override
 	public IPage<FlowModel> selectFlowPage(IPage<FlowModel> page, FlowModel flowModel) {
@@ -296,6 +314,7 @@
 
 	@Override
 	public boolean deployModel(String modelId, String category, List<String> tenantIdList) {
+
 		FlowModel model = this.getById(modelId);
 		if (model == null) {
 			throw new ServiceException("鏈壘鍒版ā鍨� id: " + modelId);
@@ -346,6 +365,12 @@
 
 	@Override
 	public FlowModel submitModel(FlowModel model) {
+
+		//楠岃瘉閲嶅key
+		if(StringUtils.isEmpty(model.getId())&&getFlowModelByKey(model.getModelKey())!=null){
+			throw new ServiceException("you cannot definition repetition 娴佺▼key!");
+		}
+
 		FlowModel flowModel = new FlowModel();
 		flowModel.setId(model.getId());
 		flowModel.setVersion(Func.toInt(model.getVersion(), 0) + 1);
@@ -467,6 +492,33 @@
 	}
 
 	/**
+	 * 鏍规嵁娴佺▼妯″瀷key鑾峰彇XML涓妭鐐归厤缃殑澶勭悊浜�
+	 *
+	 * @param key
+	 * @return
+	 */
+	@Override
+	public List<Map<String,String>> getNodeByFlowableKey(String key){
+		String processDefinitionId = repositoryService.createProcessDefinitionQuery().latestVersion().processDefinitionKey(key).singleResult().getId();
+		BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
+		Process process = bpmnModel.getProcesses().get(0);//鍙湁涓�涓�
+
+		List<Map<String,String>> ll = new ArrayList<>();
+		if (CollectionUtils.isNotEmpty(process.getFlowElements())) {
+			for (FlowElement flowElement : process.getFlowElements()) {
+				if (flowElement instanceof UserTask) {
+					Map<String,String> mi = new HashMap<>();
+					mi.put("taskId",flowElement.getId());
+					mi.put("taskName",flowElement.getName());
+					ll.add(mi);
+				}
+			}
+		}
+
+		return ll;
+	}
+
+	/**
 	 * 鏄惁宸插畬缁�
 	 *
 	 * @param processInstanceId 娴佺▼瀹炰緥id
@@ -476,7 +528,6 @@
 		return historyService.createHistoricProcessInstanceQuery().finished()
 			.processInstanceId(processInstanceId).count() > 0;
 	}
-
 
 	/**
 	 * xml杞琤pmn json
@@ -556,4 +607,10 @@
 		}
 	}
 
+	public FlowModel getFlowModelByKey(String key){
+		Map kv = new HashMap();
+		kv.put("model_key",key);
+		return baseMapper.selectOne(Condition.getQueryWrapper(kv, FlowModel.class));
+	}
+
 }
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowTaskUserServiceImpl.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowTaskUserServiceImpl.java
new file mode 100644
index 0000000..ecdc82a
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/FlowTaskUserServiceImpl.java
@@ -0,0 +1,146 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.vci.ubcs.flow.core.entity.BladeFlow;
+import com.vci.ubcs.flow.core.enums.FlowModeEnum;
+import com.vci.ubcs.flow.core.utils.TaskUtil;
+import com.vci.ubcs.flow.engine.constant.FlowEngineConstant;
+import com.vci.ubcs.flow.engine.entity.*;
+import com.vci.ubcs.flow.engine.mapper.FlowMapper;
+import com.vci.ubcs.flow.engine.mapper.FlowTaskUserMapper;
+import com.vci.ubcs.flow.engine.service.FlowEngineService;
+import com.vci.ubcs.flow.engine.service.FlowTaskUserService;
+import com.vci.ubcs.flow.engine.utils.FlowCache;
+import com.vci.ubcs.system.user.cache.UserCache;
+import com.vci.ubcs.system.user.entity.User;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.flowable.bpmn.converter.BpmnXMLConverter;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.Process;
+import org.flowable.common.engine.impl.util.IoUtil;
+import org.flowable.common.engine.impl.util.io.StringStreamSource;
+import org.flowable.editor.language.json.converter.BpmnJsonConverter;
+import org.flowable.engine.*;
+import org.flowable.engine.history.HistoricActivityInstance;
+import org.flowable.engine.history.HistoricProcessInstance;
+import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
+import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntityImpl;
+import org.flowable.engine.repository.Deployment;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.flowable.engine.repository.ProcessDefinitionQuery;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.engine.runtime.ProcessInstanceQuery;
+import org.flowable.engine.task.Comment;
+import org.flowable.image.ProcessDiagramGenerator;
+import org.springblade.core.launch.constant.FlowConstant;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.utils.DateUtil;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.util.*;
+
+/**
+ * 宸ヤ綔娴佹湇鍔″疄鐜扮被
+ *
+ * @author wang1
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+public class FlowTaskUserServiceImpl extends ServiceImpl<FlowTaskUserMapper, FlowTaskUser> implements FlowTaskUserService {
+
+	private FlowEngineService flowEngineService;
+	private FlowTaskUserMapper flowTaskUserMapper;
+
+	/**
+	 * 鏌ヨ褰撳墠鐧婚檰浜哄杩欎釜娴佺▼鐨則askUser
+	 * @return
+	 */
+	@Override
+	public FlowTaskUserC getUser(){
+		QueryWrapper<FlowTaskUser> queryWrapper = new QueryWrapper<>();
+		queryWrapper.eq("CREATED_BY", AuthUtil.getUserId());
+		List<FlowTaskUser> flowTaskUsers = baseMapper.selectList(queryWrapper);
+		FlowTaskUserC flowTaskUserCR = new FlowTaskUserC();
+		if(flowTaskUsers.size()==0){
+			return flowTaskUserCR;
+		}
+		flowTaskUserCR.setName(flowTaskUsers.get(0).getName());//鏀惰棌鍚嶇О
+		flowTaskUserCR.setFlowTaskUsers(flowTaskUsers);
+		return flowTaskUserCR;
+	}
+
+	@Override
+	public void saveOrUpdateUser(FlowTaskUserC flowTaskUserC){
+		List<FlowTaskUser> flowTaskUsers = flowTaskUserC.getFlowTaskUsers();
+		String name = flowTaskUserC.getName();//鏀惰棌鍚嶇О
+
+		//鏂板鎯呭喌涓嬮獙璇佹敹钘忓悕绉颁笉閲嶅
+		if(flowTaskUsers.get(0).getId()!=null) {
+			Map<String, Object> m = new HashMap<>();
+			m.put("name", name);
+			QueryWrapper q = Condition.getQueryWrapper(m, FlowTaskUser.class)
+				.select("id,model_key modelKey,name,description,version,created,last_updated lastUpdated");
+			if(flowTaskUserMapper.selectCount(q)>0){
+				throw new ServiceException("鏀惰棌鍚嶇О宸茬粡瀛樺湪!");
+			}
+		}
+		for (FlowTaskUser flowTaskUseri:flowTaskUsers){
+			flowTaskUseri.setName(name);
+		}
+		//鏂板銆佷慨鏀�
+		this.saveOrUpdateBatch(flowTaskUsers);
+
+	}
+
+
+	@Override
+	public void deleteUser(String name){
+		Map<String, Object> m = new HashMap<>();
+		m.put("name", name);
+		m.put("created_by", AuthUtil.getUserId());
+		baseMapper.deleteByMap(m);
+	}
+
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessStageAttrServiceImpl.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessStageAttrServiceImpl.java
new file mode 100644
index 0000000..27de85d
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessStageAttrServiceImpl.java
@@ -0,0 +1,81 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
+import com.vci.ubcs.flow.engine.entity.ProcessStageAttr;
+import com.vci.ubcs.flow.engine.mapper.ProcessStageAttrMapper;
+import com.vci.ubcs.flow.engine.service.ProcessStageAttrService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.core.mp.support.Condition;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴佺▼闃舵鏈嶅姟瀹炵幇绫�
+ *
+ * @author wang1
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+public class ProcessStageAttrServiceImpl extends ServiceImpl<ProcessStageAttrMapper, ProcessStageAttr> implements ProcessStageAttrService {
+
+	/**
+	 * 鏂板/淇敼娴佺▼闃舵
+	 * @param flowTaskUserC
+	 * @return
+	 */
+	@Transactional
+	public void saveOrUpdateUser(FlowTaskUserC flowTaskUserC){
+		List<ProcessStageAttr> processStageAttrs = flowTaskUserC.getProcessStageAttr();
+		String modelKey = flowTaskUserC.getModelKey();
+		String templateId = flowTaskUserC.getTemplateId();
+		String taskId = flowTaskUserC.getTaskId();
+		String taskName = flowTaskUserC.getTaskName();
+
+		//鐩存帴鍒犻櫎浠ュ墠鐨�
+		Map<String, Object> m = new HashMap<>();
+		m.put("template_id", templateId);
+		m.put("model_key", modelKey);
+		m.put("task_id", taskId);
+		QueryWrapper q = Condition.getQueryWrapper(m, FlowTaskUser.class)
+			.select("id,model_key modelKey,name,description,version,created,last_updated lastUpdated");
+		int i = baseMapper.deleteByMap(m);
+		System.out.println("鍒犻櫎鐨勫睘鎬т釜鏁�: "+i);
+
+		List<ProcessStageAttr> processStages = flowTaskUserC.getProcessStageAttr();
+		for (ProcessStageAttr processStageAttr:processStages){
+			processStageAttr.setModelKey(modelKey);
+			processStageAttr.setTemplateId(templateId);
+			processStageAttr.setTaskId(taskId);
+			processStageAttr.setTaskName(taskName);
+		}
+		if(processStages.size()!=0) {
+			this.saveOrUpdateBatch(processStages);
+		}
+	}
+
+}
diff --git a/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessTemplateServiceImpl.java b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessTemplateServiceImpl.java
new file mode 100644
index 0000000..e7a35ac
--- /dev/null
+++ b/Source/UBCS/ubcs-ops/ubcs-flow/src/main/java/com/vci/ubcs/flow/engine/service/impl/ProcessTemplateServiceImpl.java
@@ -0,0 +1,107 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 搴勯獮 (smallchill@163.com)
+ */
+package com.vci.ubcs.flow.engine.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.vci.ubcs.flow.core.utils.TaskUtil;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUser;
+import com.vci.ubcs.flow.engine.entity.FlowTaskUserC;
+import com.vci.ubcs.flow.engine.entity.ProcessTemplate;
+import com.vci.ubcs.flow.engine.mapper.FlowTaskUserMapper;
+import com.vci.ubcs.flow.engine.mapper.ProcessTemplateMapper;
+import com.vci.ubcs.flow.engine.service.FlowEngineService;
+import com.vci.ubcs.flow.engine.service.FlowTaskUserService;
+import com.vci.ubcs.flow.engine.service.ProcessTemplateService;
+import com.vci.ubcs.starter.web.enumpck.ProcessTemplateTypeEnum;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springblade.core.launch.constant.FlowConstant;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.support.Condition;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 娴佺▼妯℃澘鏈嶅姟瀹炵幇绫�
+ *
+ * @author wang1
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+public class ProcessTemplateServiceImpl extends ServiceImpl<ProcessTemplateMapper, ProcessTemplate> implements ProcessTemplateService {
+
+
+	/**
+	 * 鏂板/淇敼娴佺▼妯℃澘
+	 * @param processTemplate
+	 * @return
+	 */
+	public void saveOrUpdateUser(ProcessTemplate processTemplate){
+		//鏍¢獙杩欎釜妯℃澘涓嬶紝涓�绫绘寜閽彧鑳芥湁涓�涓ā鏉�
+		QueryWrapper<ProcessTemplate> queryWrapper = new QueryWrapper<>();
+		queryWrapper.eq("button_type_key", processTemplate.getButtonTypeKey());
+		if(StringUtils.isNotEmpty(processTemplate.getId())) {//淇敼鐨勬椂鍊�,id涓虹┖灏辨槸鏂板
+			queryWrapper.ne("id", processTemplate.getId());
+		}
+		if(baseMapper.selectOne(queryWrapper)!=null){
+			throw new ServiceException(processTemplate.getButtonTypeValue()+"鍔熻兘宸茬粡閰嶇疆浜嗘祦绋�!");
+		}
+		if(StringUtils.isEmpty(processTemplate.getButtonTypeValue())){
+			processTemplate.setButtonTypeValue(ProcessTemplateTypeEnum.getTextByValue(processTemplate.getButtonTypeKey()));
+		}
+		//鏂板鎴栬�呬慨鏀�
+		if(StringUtils.isEmpty(processTemplate.getId())){
+			processTemplate.setCreated(Calendar.getInstance().getTime());
+			processTemplate.setCreatedBy(TaskUtil.getTaskUser());
+			processTemplate.setLastUpdated(Calendar.getInstance().getTime());
+			processTemplate.setLastUpdatedBy(TaskUtil.getTaskUser());
+		}
+		this.saveOrUpdate(processTemplate);
+
+	}
+
+	/**
+	 * 鍒犻櫎娴佺▼妯℃澘
+	 * @param id
+	 * @return
+	 */
+	public void deleteProcessTemplate(String id){
+		baseMapper.deleteById(id);
+	}
+
+	/**
+	 * 娴佺▼妯℃澘鐢ㄩ��
+	 * @return
+	 */
+	public List<Map<String,String>> processTemplateType(){
+		ProcessTemplateTypeEnum[] es = ProcessTemplateTypeEnum.values();
+		List<Map<String,String>> ll = new ArrayList<>();
+		for (ProcessTemplateTypeEnum p:es){
+			Map<String,String> mi = new HashMap<>();
+			String value = p.getValue();
+			String text = p.getText();
+			mi.put("codee",value);
+			mi.put("namee",text);
+			ll.add(mi);
+		}
+		return ll;
+	}
+}
diff --git a/Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/NewAppConstantEnum.java b/Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/NewAppConstantEnum.java
index d445b03..f7d22f8 100644
--- a/Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/NewAppConstantEnum.java
+++ b/Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/NewAppConstantEnum.java
@@ -8,6 +8,7 @@
 	 * 缂栫爜瑙勫垯锛屾湇鍔″惎鍔ㄥ悕
 	 */
 	APPLICATION_NAME_CODE(AppConstant.APPLICATION_NAME_CODE,"涓绘暟鎹�"),
+	APPLICATION_FLOW_NAME(AppConstant.APPLICATION_FLOW_NAME,"ubcs-flow"),
 	;
 
 	/**
diff --git a/Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/ProcessTemplateTypeEnum.java b/Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/ProcessTemplateTypeEnum.java
new file mode 100644
index 0000000..3284d8e
--- /dev/null
+++ b/Source/UBCS/ubcs-service-api/ubcs-util-api/src/main/java/com/vci/ubcs/starter/web/enumpck/ProcessTemplateTypeEnum.java
@@ -0,0 +1,134 @@
+package com.vci.ubcs.starter.web.enumpck;
+
+
+/**
+ * 娴佺▼妯℃澘搴旂敤鎸夐挳绫诲瀷
+ * @author wang1
+ */
+public enum ProcessTemplateTypeEnum implements BaseEnum {
+
+	/**
+	 * 鍙戝竷
+	 */
+	PUBLIC("PUBLIC","鍙戝竷"),
+
+	/**
+	 * 鍙樻洿
+	 */
+	EDIT("EDIT","鍙樻洿"),
+
+	/**
+	 * 鍋滅敤
+	 */
+	ENABLE("ENABLE","鍋滅敤"),
+
+	/**
+	 * 鍚敤
+	 */
+	DISABLE("DISABLE","鍚敤");
+
+	/**
+	 * 鏋氫妇鐨勫��
+	 */
+	private String value;
+
+	/**
+	 * 鏋氫妇鏄剧ず鏂囨湰
+	 */
+	private String text;
+
+	/**
+	 * 鑾峰彇鏋氫妇鍊�
+	 *
+	 * @return 鏋氫妇鍊�
+	 */
+	@Override
+	public String getValue() {
+		return value;
+	}
+
+	/**
+	 * 璁剧疆鏋氫妇鍊�
+	 *
+	 * @param value 鏋氫妇鍊�
+	 */
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	/**
+	 * 鑾峰彇鏋氫妇鏄剧ず鏂囨湰
+	 *
+	 * @return 鏄剧ず鏂囨湰
+	 */
+	@Override
+	public String getText() {
+		return text;
+	}
+
+	/**
+	 * 璁剧疆鏄剧ず鏂囨湰
+	 *
+	 * @param text 鏄剧ず鏂囨湰
+	 */
+	public void setText(String text) {
+		this.text = text;
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁�
+	 *
+	 * @param value 鍊�
+	 * @param text  鏄剧ず鏂囨湰
+	 */
+	private ProcessTemplateTypeEnum(String value, String text) {
+		this.value = value;
+		this.text = text;
+	}
+
+	/**
+	 * 鏍规嵁鍚嶇О鑾峰彇瀵瑰簲鐨勬灇涓惧��
+	 *
+	 * @param text 鍚嶇О
+	 * @return 鏋氫妇鍊�
+	 */
+	public static String getValueByText(String text) {
+		for (ProcessTemplateTypeEnum wenum : ProcessTemplateTypeEnum.values()) {
+			if (wenum.getText().equalsIgnoreCase(text)) {
+				return wenum.getValue();
+			}
+		}
+		return "";
+	}
+
+	/**
+	 * 鏍规嵁鏋氫妇鍊艰幏鍙栧悕绉�
+	 *
+	 * @param value 鏋氫妇鍊�
+	 * @return 鍚嶇О
+	 */
+	public static String getTextByValue(String value) {
+		for (ProcessTemplateTypeEnum wenum : ProcessTemplateTypeEnum.values()) {
+			if (wenum.getValue().equalsIgnoreCase(value)) {
+				return wenum.getText();
+			}
+		}
+		return "";
+	}
+
+	/**
+	 * 鏍规嵁鏋氫妇鍊艰幏鍙栨灇涓惧璞�
+	 *
+	 * @param value 鏋氫妇鍊�
+	 * @return 鏋氫妇瀵硅薄锛屼笉瀛樺湪鏃跺�欒繑鍥瀗ull
+	 */
+	public static ProcessTemplateTypeEnum forValue(String value) {
+		for (ProcessTemplateTypeEnum wenum : ProcessTemplateTypeEnum.values()) {
+			if (wenum.getValue().equalsIgnoreCase(value)) {
+				return wenum;
+			}
+		}
+		return null;
+	}
+}
+
diff --git a/Source/UBCS/ubcs-service-api/ubcs-workflow-api/src/main/java/com/vci/ubcs/code/constant/FlowConstant.java b/Source/UBCS/ubcs-service-api/ubcs-workflow-api/src/main/java/com/vci/ubcs/code/constant/FlowConstant.java
new file mode 100644
index 0000000..81781a4
--- /dev/null
+++ b/Source/UBCS/ubcs-service-api/ubcs-workflow-api/src/main/java/com/vci/ubcs/code/constant/FlowConstant.java
@@ -0,0 +1,32 @@
+package com.vci.workflow.constant;
+
+public class FlowConstant {
+
+    public static final String MAPPER_SCAN = "com.dragon.*.dao.*";
+
+    /**
+     * 鎻愪氦浜虹殑鍙橀噺鍚嶇О
+     */
+    public static final String FLOW_SUBMITTER_VAR = "initiator";
+    /**
+     * 鎻愪氦浜鸿妭鐐瑰悕绉�
+     */
+    public static final String FLOW_SUBMITTER = "鎻愪氦浜�";
+    /**
+     * 鑷姩璺宠繃鑺傜偣璁剧疆灞炴��
+     */
+    public static final String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED";
+    /**
+     * 鎸傝捣鐘舵��
+     */
+    public static final int SUSPENSION_STATE = 2;
+    /**
+     * 婵�娲荤姸鎬�
+     */
+    public static final int ACTIVATE_STATE = 1;
+    //鍚庡姞绛�
+    public static final String AFTER_ADDSIGN = "after";
+    //鍓嶅姞绛�
+    public static final String BEFORE_ADDSIGN = "before";
+
+}
diff --git a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java
index ee01f3b..f8d3d40 100644
--- a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java
+++ b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/MdmEngineController.java
@@ -12,10 +12,9 @@
 import com.vci.ubcs.code.vo.pagemodel.*;
 import com.vci.ubcs.starter.annotation.VciBusinessLog;
 import com.vci.ubcs.starter.revision.model.BaseModel;
+import com.vci.ubcs.starter.revision.model.TreeQueryObject;
 import com.vci.ubcs.starter.util.LocalFileUtil;
-import com.vci.ubcs.starter.web.pagemodel.BaseQueryObject;
-import com.vci.ubcs.starter.web.pagemodel.DataGrid;
-import com.vci.ubcs.starter.web.pagemodel.Tree;
+import com.vci.ubcs.starter.web.pagemodel.*;
 import com.vci.ubcs.starter.web.util.ControllerUtil;
 import com.vci.ubcs.starter.web.util.LangBaseUtil;
 import com.vci.ubcs.starter.web.util.VciBaseUtil;
@@ -531,4 +530,25 @@
 //		return engineService.updateBatchByBaseModel("wupin", models);
 //		return engineService.getUIInfoByClassifyOid(codeClassifyOid,functionId);
 	}
+
+	/**
+	 * 榛樿鐨勫弬鐓у垪琛�
+	 * @param referConfigVO 鍙傜収鐨勯厤缃俊鎭�
+	 * @return 鎵ц鐨勭粨鏋�
+	 */
+	@GetMapping("/defaultReferDataGrid")
+	public DataGrid defaultReferDataGrid(UIFormReferVO referConfigVO, PageHelper pageHelper){
+		return engineService.referDataGrid(referConfigVO,pageHelper);
+	}
+
+	/**
+	 * 榛樿鐨勬爲褰㈠弬鐓у垪琛�
+	 * @param referConfigVO 鍙傜収鐨勯厤缃俊鎭�
+	 * @return 鎵ц鐨勭粨鏋�
+	 */
+	@GetMapping("/defaultReferTree")
+	public List<Tree> defaultReferTree(UIFormReferVO referConfigVO, TreeQueryObject queryObject){
+		return engineService.referTree(referConfigVO,queryObject);
+	}
+
 }
diff --git a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/ICodeClassifyService.java b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/ICodeClassifyService.java
index 92b2711..1bf0758 100644
--- a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/ICodeClassifyService.java
+++ b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/ICodeClassifyService.java
@@ -32,6 +32,20 @@
 	 */
 	List<CodeClassify> selectByWrapper(Wrapper wrapper);
 
+
+
+	/**
+	 * 浣跨敤鏌ヨ灏佽鍣ㄦ潵鏌ヨ
+	 * @param wrapper 鏌ヨ灏佽鍣�
+	 * @return 鏁版嵁瀵硅薄
+	 */
+	List<String> select1(Wrapper wrapper);
+
+
+
+
+
+
 	/**
 	 * 鑷畾涔夊垎椤�
 	 *
diff --git a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/MdmEngineService.java b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/MdmEngineService.java
index 3b79f45..5d9b9f6 100644
--- a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/MdmEngineService.java
+++ b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/MdmEngineService.java
@@ -12,6 +12,7 @@
 import com.vci.ubcs.code.vo.pagemodel.UITableFieldVO;
 import com.vci.ubcs.code.vo.pagemodel.*;
 import com.vci.ubcs.starter.revision.model.BaseModel;
+import com.vci.ubcs.starter.revision.model.TreeQueryObject;
 import com.vci.ubcs.starter.web.pagemodel.*;
 import org.springblade.core.tool.api.R;
 
@@ -395,4 +396,19 @@
 	 */
 	R updateBatchByBaseModel(String btmType, List<BaseModel> baseModels);
 
+	/**
+	 * 榛樿鍒楄〃
+	 * @param referConfigVO
+	 * @param pageHelper
+	 * @return
+	 */
+	DataGrid referDataGrid(UIFormReferVO referConfigVO, PageHelper pageHelper);
+
+
+	/**
+	 * 鑾峰彇鏍戝舰鐨勫弬鐓�
+	 * @param referConfigVO 鍙傜収鐨勯厤缃�
+	 * @return 鏍戝舰鐨勬暟鎹�
+	 */
+	List<Tree> referTree(UIFormReferVO referConfigVO, TreeQueryObject queryObject);
 }
diff --git a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java
index 0b567fd..174ec33 100644
--- a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java
+++ b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java
@@ -106,6 +106,20 @@
 		return codeClassifyMapper.selectList(wrapper);
 	}
 
+	/**
+	 * 鏌ヨ
+	 * @param wrapper 鏌ヨ灏佽鍣�
+	 * @return
+	 */
+	@Override
+	public List<String> select1(Wrapper wrapper) {
+
+		return codeClassifyMapper.selectObjs(wrapper);
+	}
+
+
+
+
 	@Override
 	public IPage<CodeClassifyVO> selectPlCodeClassifyPage(IPage<CodeClassifyVO> page, CodeClassifyVO plCodeClassify) {
 		return page.setRecords(codeClassifyMapper.selectPlCodeClassifyPage(page, plCodeClassify));
diff --git a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java
index 8565672..9280f3a 100644
--- a/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java
+++ b/Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java
@@ -1,6 +1,7 @@
 package com.vci.ubcs.code.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
@@ -21,6 +22,8 @@
 import com.vci.ubcs.code.vo.pagemodel.UITableFieldVO;
 import com.vci.ubcs.code.vo.pagemodel.UITablePageVO;
 import com.vci.ubcs.code.vo.pagemodel.*;
+import com.vci.ubcs.omd.constant.BtmTypeLcStatusConstant;
+import com.vci.ubcs.omd.entity.BtmTypeAttribute;
 import com.vci.ubcs.omd.feign.IAttributeClient;
 import com.vci.ubcs.omd.feign.IBtmTypeClient;
 import com.vci.ubcs.omd.feign.IEnumClient;
@@ -31,6 +34,7 @@
 import com.vci.ubcs.omd.vo.RevisionRuleVO;
 import com.vci.ubcs.starter.exception.VciBaseException;
 import com.vci.ubcs.starter.revision.model.BaseModel;
+import com.vci.ubcs.starter.revision.model.TreeQueryObject;
 import com.vci.ubcs.starter.revision.model.TreeWrapperOptions;
 import com.vci.ubcs.starter.revision.service.RevisionModelUtil;
 import com.vci.ubcs.starter.web.constant.QueryOptionConstant;
@@ -49,9 +53,12 @@
 import com.vci.ubcs.system.user.feign.IUserClient;
 import net.logstash.logback.encoder.org.apache.commons.lang3.StringUtils;
 import oracle.sql.TIMESTAMP;
+import org.apache.commons.collections4.MapUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springblade.core.cache.utils.CacheUtil;
+import org.springblade.core.launch.constant.AppConstant;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.StringPool;
@@ -60,6 +67,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
+import plm.bs.bom.clientobject.ClientBusinessObject;
 
 import javax.annotation.Resource;
 import java.beans.BeanInfo;
@@ -266,7 +274,7 @@
 	/**
 	 * 鏇挎崲瀛楃
 	 */
-	public static final String SPECIAL_CHAR  = "VCI";
+	public static final String SPECIAL_CHAR = "VCI";
 //	@Autowired
 //	private CodeOsbtmtypeMapper codeOsbtmtypeMapper;----
 
@@ -312,7 +320,7 @@
 //		 	Dict dict = new Dict();
 //			dict.setParentId(Long.valueOf(attrVO.getEnumid()));
 			R<List<EnumVO>> list = enumClient.getList(attrVO.getEnumId());
-			if(list.isSuccess()){
+			if (list.isSuccess()) {
 				for (EnumVO datum : list.getData()) {
 					KeyValue keyValue = new KeyValue();
 					keyValue.setKey(datum.getItemValue());
@@ -323,7 +331,6 @@
 		}
 		return comboboxKVs;
 	}
-
 	/**
 	 * 淇敼鐘舵��
 	 *
@@ -1184,7 +1191,7 @@
 			//澶勭悊鎵�鏈夌殑鍒楋紝杩欎釜妯℃澘娌℃湁鍚堝苟鐨勮〃澶寸殑鎯呭喌
 			List<UITableFieldVO> fieldVOList = new ArrayList<>();
 			resembleAttrList.forEach(attrVO -> {
-				UITableFieldVO tableFieldVO = templateAttr2TableField(attrVO,false);
+				UITableFieldVO tableFieldVO = templateAttr2TableField(attrVO, false);
 				tableFieldVO.setHidden(false);
 				fieldVOList.add(tableFieldVO);
 			});
@@ -1199,12 +1206,12 @@
 	/**
 	 * 妯℃澘灞炴�ц浆鎹负琛ㄦ牸鏄剧ず鐨勯厤缃�
 	 *
-	 * @param attrVO 妯℃澘灞炴��
+	 * @param attrVO  妯℃澘灞炴��
 	 * @param forEdit 鏄惁鏄紪杈戞墍闇�
 	 * @return 琛ㄦ牸鐨勫瓧娈�
 	 */
 	@Override
-	public UITableFieldVO templateAttr2TableField(CodeClassifyTemplateAttrVO attrVO,boolean forEdit) {
+	public UITableFieldVO templateAttr2TableField(CodeClassifyTemplateAttrVO attrVO, boolean forEdit) {
 		UITableFieldVO fieldVO = new UITableFieldVO();
 		if (SECRET_FILED.equalsIgnoreCase(attrVO.getId())) {
 			attrVO.setEnumId(MY_DATA_SECRET);
@@ -1215,9 +1222,9 @@
 		fieldVO.setSort(true);
 		fieldVO.setSortField(fieldVO.getField());
 		fieldVO.setQueryField(fieldVO.getField());
-		if (forEdit){
+		if (forEdit) {
 			fieldVO.setHidden(!VciBaseUtil.getBoolean(attrVO.getFormDisplayFlag()));
-		}else {
+		} else {
 			fieldVO.setHidden(!VciBaseUtil.getBoolean(attrVO.getTableDisplayFlag()));
 		}
 		if (attrVO.getAttrTableWidth() != null && attrVO.getAttrTableWidth() > 0) {
@@ -1237,7 +1244,7 @@
 				if (StringUtils.isBlank(attrVO.getEnumId())) {
 					fieldVO.setComboxKey(fieldVO.getField() + "_data");
 				}
-			}else {
+			} else {
 //				List<KeyValue> osEnumItemVOList= enumService.getEnum(attrVO.getEnumId());
 //				fieldVO.setData(osEnumItemVOList);
 			}
@@ -1407,8 +1414,8 @@
 				}
 			}
 			queryValue = String.format(temp, (trim ? value.trim() : value));
-			temp = temp.replace("to_single_byte('%s')","to_single_byte(%s)");
-			queryKey = String.format(temp, "t."+attrId);
+			temp = temp.replace("to_single_byte('%s')", "to_single_byte(%s)");
+			queryKey = String.format(temp, "t." + attrId);
 			conditionMap.put(queryKey, QueryOptionConstant.OR + queryValue);
 		}
 	}
@@ -1427,7 +1434,7 @@
 	public DataGrid<Map<String, String>> queryGrid(String btmType, CodeClassifyTemplateVO templateVO, Map<String, String> conditionMap, PageHelper pageHelper) {
 		CodeTemplateAttrSqlBO sqlBO = getSqlByTemplateVO(btmType, templateVO, conditionMap, pageHelper);
 //		List<Map> maps = boService.queryByOnlySqlForMap(sqlBO.getSqlHasPage());
-		List<Map<String,String>> maps = commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlHasPage());
+		List<Map<String, String>> maps = commonsMapper.queryByOnlySqlForMap(sqlBO.getSqlHasPage());
 
 		DataGrid<Map<String, String>> dataGrid = new DataGrid<>();
 		List<Map<String, String>> dataList = new ArrayList<>();
@@ -1480,7 +1487,7 @@
 	 * @param dataMap              鏁版嵁鐨勬槧灏�
 	 * @param templateVO           妯℃澘鐨勫睘鎬�
 	 * @param onlySelectAttrIdList 浠呬粎鏌ヨ鐨勫睘鎬у瓧娈�
-	 * @param form 琛ㄥ崟閲屼娇鐢�
+	 * @param form                 琛ㄥ崟閲屼娇鐢�
 	 */
 	@Override
 	public void wrapperData(List<Map<String, String>> dataMap, CodeClassifyTemplateVO templateVO,
@@ -1511,15 +1518,15 @@
 			//澶勭悊鏋氫妇
 			wrapperEnum(enumAttrVOs, data);
 			String lcstatus = data.get(VciQueryWrapperForDO.LC_STATUS_FIELD);
-			String copyFromVersion = data.getOrDefault(COPY_FROM_VERSION,"");
+			String copyFromVersion = data.getOrDefault(COPY_FROM_VERSION, "");
 			if ((CodeDefaultLC.EDITING.getValue().equalsIgnoreCase(lcstatus) || CodeDefaultLC.AUDITING.getValue().equalsIgnoreCase(lcstatus))
 				&& StringUtils.isBlank(copyFromVersion)
 			) {
 				data.put(VciQueryWrapperForDO.ID_FIELD, "******");
 			}
 			data.put(VciQueryWrapperForDO.LC_STATUS_FIELD_TEXT.toLowerCase(Locale.ROOT), CodeDefaultLC.getTextByValue(lcstatus));
-			if(CodeDefaultLC.EDITING.getValue().equalsIgnoreCase(lcstatus)
-				&& StringUtils.isNotBlank(copyFromVersion)){
+			if (CodeDefaultLC.EDITING.getValue().equalsIgnoreCase(lcstatus)
+				&& StringUtils.isNotBlank(copyFromVersion)) {
 				data.put(VciQueryWrapperForDO.LC_STATUS_FIELD_TEXT.toLowerCase(Locale.ROOT), "淇敼涓�");
 			}
 			if (data.containsKey("creator")) {
@@ -1532,12 +1539,12 @@
 		if (!CollectionUtils.isEmpty(userIds)) {
 			Map<String, User> userVOMap = new HashMap<>();
 			for (String userId : userIds) {
-				if(!StringUtils.isNumeric(userId)){
+				if (!StringUtils.isNumeric(userId)) {
 					continue;
 				}
 				User data = iUserClient.userInfoById(Long.valueOf(userId)).getData();
-				if(data != null){
-					userVOMap.put(String.valueOf(data.getId()),data);
+				if (data != null) {
+					userVOMap.put(String.valueOf(data.getId()), data);
 				}
 			}
 //			Map<String, SmUserVO> userVOMap = Optional.ofNullable(userQueryService.listUserByUserIds(userIds)).orElseGet(() -> new ArrayList<>()).stream().collect(Collectors.toMap(s -> s.getId().toLowerCase(Locale.ROOT), t -> t));
@@ -1670,7 +1677,7 @@
 //				selectFieldList.add(attrId.getOid());
 //			}
 //		});
-		if(allAttributeByBtmId.getData() != null ){
+		if (allAttributeByBtmId.getData() != null) {
 			for (BtmTypeAttributeVO attribute : allAttributeByBtmId.getData().getAttributes()) {
 				if (!selectFieldList.contains(attribute.getId()) && !"secretgrade".equalsIgnoreCase(attribute.getId())) {
 					selectFieldList.add(attribute.getId());
@@ -2060,8 +2067,6 @@
 //		return codeList.size() > 0 ? codeList.get(0) : "";
 
 
-
-
 		//淇敼鐨勬椂鍊欙紝缂栫爜鏄笉鍙樼殑
 //		BatchCBO batchCBO = new BatchCBO();
 //		batchCBO.getUpdateCbos().add(cbo);
@@ -2106,10 +2111,10 @@
 
 		//鍙兘鍒犻櫎鑷繁鍒涘缓鐨勬暟鎹�
 		String userId = AuthUtil.getUser().getUserName();
-		for (CodeWupin clientBusinessObject:cboList){
+		for (CodeWupin clientBusinessObject : cboList) {
 			String creator = clientBusinessObject.getCreator();
-			if(!userId.equalsIgnoreCase(creator)){
-				throw new VciBaseException("缂栫爜涓�"+clientBusinessObject.getId()+"鐨勬暟鎹笉鏄綋鍓嶇敤鎴峰垱寤猴紝涓嶈兘鍒犻櫎锛�");
+			if (!userId.equalsIgnoreCase(creator)) {
+				throw new VciBaseException("缂栫爜涓�" + clientBusinessObject.getId() + "鐨勬暟鎹笉鏄綋鍓嶇敤鎴峰垱寤猴紝涓嶈兘鍒犻櫎锛�");
 			}
 
 		}
@@ -2519,11 +2524,11 @@
 		String btmId = topClassifyVO.getBtmtypeid();
 		//鏌ヨ鏁版嵁
 		Map<String, String> conditionMap = new HashMap<>();
-		conditionMap.put("t.oid",oid);
+		conditionMap.put("t.oid", oid);
 		CodeTemplateAttrSqlBO sqlBO = getSqlByTemplateVO(btmId, templateVO, conditionMap, new PageHelper(-1));
 		//鎴戜滑浣跨敤鍜屼笟鍔$被鍨嬬殑鏉ユ煡璇�
 		List<Map> cbosB = commonsMapper.selectBySql(sqlBO.getSqlUnPage());
-		List<Map<String,String>> cbos = new ArrayList<>();
+		List<Map<String, String>> cbos = new ArrayList<>();
 		cbosB.stream().forEach(map -> {
 			Map<String, String> data = new HashMap<>();
 			for (Object o : map.keySet()) {
@@ -2537,7 +2542,7 @@
 			throw new VciBaseException("鏁版嵁鍦ㄧ郴缁熶腑涓嶅瓨鍦紝鏄惁鍥犱负淇敼杩囦笟鍔$被鍨嬶紵");
 		}
 //		Map<String, String> data = new HashMap<>();
-		Map<String,String> cbo = cbos.get(0);
+		Map<String, String> cbo = cbos.get(0);
 //		WebUtil.copyValueToMapFromCbos(cbo, data);
 		List<Map<String, String>> dataList = new ArrayList<>();
 		dataList.add(cbo);
@@ -2633,10 +2638,10 @@
 		QueryWrapper<CodeWupin> wrapper = new QueryWrapper();
 		if (conditionMap.get("oid").contains(",")) {
 //			oidMap.put("oid", QueryOptionConstant.IN +"("+ VciBaseUtil.toInSql(oidList.toArray(new String[0])) + ")");
-			wrapper.in("oid",oidList);
+			wrapper.in("oid", oidList);
 		} else {
 //			oidMap.put("oid", conditionMap.get("oid"));
-			wrapper.in("oid",conditionMap.get("oid"));
+			wrapper.in("oid", conditionMap.get("oid"));
 		}
 		if (CollectionUtils.isEmpty(oidMap)) {
 			throw new VciBaseException("涓氬姟鏁版嵁涓婚敭涓嶈兘涓虹┖");
@@ -2669,18 +2674,18 @@
 		CodeClassifyTemplateVO templateVO = templateService.codeClassifyTemplateDO2VO(templateDOList.get(0));
 		templateVO.setAttributes(codeClassifyTemplateAttrService.codeClassifyTemplateAttrDO2VOs(attrDOList));
 		try {
-			if (oidList.size() > 1){
-				DataGrid<Map<String,String>> allDataGrid = new DataGrid<>();
-				List<Map<String,String>> allData = new ArrayList<>();
+			if (oidList.size() > 1) {
+				DataGrid<Map<String, String>> allDataGrid = new DataGrid<>();
+				List<Map<String, String>> allData = new ArrayList<>();
 				oidList.forEach(oid -> {
-					Map<String,String> condition = new HashMap<>();
-					condition.put("oid",oid);
+					Map<String, String> condition = new HashMap<>();
+					condition.put("oid", oid);
 					DataGrid<Map<String, String>> dataGrid = queryGrid(btmType, templateVO, condition, pageHelper);
 					allData.addAll(dataGrid.getData());
 				});
 				allDataGrid.setData(allData);
 				return allDataGrid;
-			}else {
+			} else {
 				return queryGrid(btmType, templateVO, conditionMap, pageHelper);
 			}
 		} catch (Exception e) {
@@ -2700,20 +2705,20 @@
 		MdmUIInfoVO uiInfoVO = new MdmUIInfoVO();
 		CodeClassifyTemplateVO templateVO = getUsedTemplateByClassifyOid(codeClassifyOid);
 		uiInfoVO.setTemplateVO(templateVO);
-		UITableDefineVO uiTableDefineVO = wrapperTableDefineByTemplate(templateVO,true);
+		UITableDefineVO uiTableDefineVO = wrapperTableDefineByTemplate(templateVO, true);
 		List<String> phaseAttrIdList = listPhaseAttrByClassifyOid(codeClassifyOid, phase);
 		uiTableDefineVO.getCols().stream().forEach(list -> {
-			List<UITableFieldVO> visiableTableField=new ArrayList<>();
-			if(StringUtils.isNotBlank(phase)) {
+			List<UITableFieldVO> visiableTableField = new ArrayList<>();
+			if (StringUtils.isNotBlank(phase)) {
 				visiableTableField = list.stream().filter(col ->
 					phaseAttrIdList.stream().anyMatch(s -> StringUtils.equalsIgnoreCase(col.getField(), s) ||
 						(StringUtils.equalsIgnoreCase(col.getFieldType(), "combox") && StringUtils.equalsIgnoreCase(col.getSortField(), s))
 						|| (StringUtils.equalsIgnoreCase(col.getFieldType(), "refer") && StringUtils.equalsIgnoreCase(col.getQueryField(), s))
 					)).collect(Collectors.toList());
-			}else{
-				visiableTableField=  list.stream().filter(col ->
+			} else {
+				visiableTableField = list.stream().filter(col ->
 					templateVO.getAttributes().stream().anyMatch(s ->
-						(!s.getReadOnlyFlag().equalsIgnoreCase("true")&& StringUtils.equalsIgnoreCase(col.getField(), s.getId())) ||
+						(!s.getReadOnlyFlag().equalsIgnoreCase("true") && StringUtils.equalsIgnoreCase(col.getField(), s.getId())) ||
 							(StringUtils.equalsIgnoreCase(col.getFieldType(), "combox") && StringUtils.equalsIgnoreCase(col.getSortField(), s.getId()))
 							|| (StringUtils.equalsIgnoreCase(col.getFieldType(), "refer") && StringUtils.equalsIgnoreCase(col.getQueryField(), s.getId()))
 					)).collect(Collectors.toList());
@@ -2725,9 +2730,9 @@
 					setReferConfig2EditConfig(vo);
 				} else if ("combox".equalsIgnoreCase(vo.getFieldType())) {
 					setComboxConfig2EditConfig(vo);
-				} else if (StringUtils.isNotBlank(vo.getDateFormate())){
+				} else if (StringUtils.isNotBlank(vo.getDateFormate())) {
 					vo.setEdit("date");
-				}else {
+				} else {
 					vo.setEdit(vo.getFieldType());
 				}
 			});
@@ -2807,14 +2812,14 @@
 	 * @param vo 琛ㄦ牸瀛楁鏄剧ず瀵硅薄
 	 */
 	private void setReferConfig2EditConfig(UITableFieldVO vo) {
-		if (!CollectionUtils.isEmpty(vo.getReferConfig().getWhere())){
+		if (!CollectionUtils.isEmpty(vo.getReferConfig().getWhere())) {
 			vo.getReferConfig().getWhere().keySet().forEach(key -> {
 				vo.getReferConfig().getWhere().put(key, "'" + vo.getReferConfig().getWhere().get(key) + "'");
 			});
 		}
-		if (StringUtils.isNotBlank(vo.getReferConfig().getParentValue())){
+		if (StringUtils.isNotBlank(vo.getReferConfig().getParentValue())) {
 			String parentValue = vo.getReferConfig().getParentValue();
-			parentValue ="\\" +  parentValue.replaceAll("'","{vci-quote}").replaceAll("=","{vci-equals}");
+			parentValue = "\\" + parentValue.replaceAll("'", "{vci-quote}").replaceAll("=", "{vci-equals}");
 			vo.getReferConfig().setParentValue(parentValue);
 		}
 		String referConfig = vo.getReferConfig().toString()
@@ -2838,16 +2843,16 @@
 	 */
 	private void setComboxConfig2EditConfig(UITableFieldVO vo) {
 		vo.setEditConfig("{editable:true,comboxKey:'" + vo.getComboxKey() + "'");
-		if (!CollectionUtils.isEmpty(vo.getData())){
-			vo.setEditConfig(vo.getEditConfig()+", comboxConfig:");
+		if (!CollectionUtils.isEmpty(vo.getData())) {
+			vo.setEditConfig(vo.getEditConfig() + ", comboxConfig:");
 			for (int i = 0; i < vo.getData().size(); i++) {
 				KeyValue data = vo.getData().get(i);
-				if (i == vo.getData().size() -1){
-					vo.setEditConfig(vo.getEditConfig() + "{attributes:"+data.getAttributes()+",key:'"+data.getKey()+"',value:'"+data.getValue()+"'}]}");
-				}else if (i == 0){
-					vo.setEditConfig(vo.getEditConfig() + "{data:[{attributes:"+data.getAttributes()+",key:'"+data.getKey()+"',value:'"+data.getValue()+"'},");
-				}else{
-					vo.setEditConfig(vo.getEditConfig() + "{attributes:"+data.getAttributes()+",key:'"+data.getKey()+"',value:'"+data.getValue()+"'},");
+				if (i == vo.getData().size() - 1) {
+					vo.setEditConfig(vo.getEditConfig() + "{attributes:" + data.getAttributes() + ",key:'" + data.getKey() + "',value:'" + data.getValue() + "'}]}");
+				} else if (i == 0) {
+					vo.setEditConfig(vo.getEditConfig() + "{data:[{attributes:" + data.getAttributes() + ",key:'" + data.getKey() + "',value:'" + data.getValue() + "'},");
+				} else {
+					vo.setEditConfig(vo.getEditConfig() + "{attributes:" + data.getAttributes() + ",key:'" + data.getKey() + "',value:'" + data.getValue() + "'},");
 				}
 			}
 			vo.setEditConfig(vo.getEditConfig() + ",valueField:'" + vo.getQueryField() + "'");
@@ -2865,7 +2870,7 @@
 	@Override
 	public MdmUIInfoVO getFormDefineByClassifyIdPath(String idPath) {
 		CodeClassifyVO classifyVO = classifyService.getObjectByIdPath(idPath);
-		if(classifyVO !=null){
+		if (classifyVO != null) {
 			return getFormDefineByClassifyOid(classifyVO.getOid());
 		}
 		return null;
@@ -2910,7 +2915,7 @@
 		MdmUIInfoVO uiInfoVO = new MdmUIInfoVO();
 		uiInfoVO.setTemplateVO(templateVO);
 		//鎴戜滑闇�瑕佸皢妯℃澘杞崲涓鸿〃鏍肩浉鍏崇殑鏄剧ず淇℃伅
-		uiInfoVO.setTableDefineVO(wrapperTableDefineByTemplate(uiInfoVO.getTemplateVO(),false));
+		uiInfoVO.setTableDefineVO(wrapperTableDefineByTemplate(uiInfoVO.getTemplateVO(), false));
 		//闇�瑕佸幓鐪嬫墿灞曠殑鎸夐挳,鍙湁鍒楄〃閲岄潰鏈韩鎵嶆坊鍔犺繘鍘伙紝宸ュ叿鏍忎笂鐨勫崟鐙幏鍙�
 		List<CodeClassifyTemplateButtonVO> buttonVOS = templateButtonService.listButtonByTemplateOid(templateVO.getOid(), true);
 		if (!CollectionUtils.isEmpty(buttonVOS)) {
@@ -2949,8 +2954,8 @@
 	@Override
 	public MdmUIInfoVO getUIInfoByClassifyIdPath(String codeClassifyIdPath, String functionId) {
 		CodeClassifyVO classifyVO = classifyService.getObjectByIdPath(codeClassifyIdPath);
-		if(classifyVO !=null){
-			return getUIInfoByClassifyOid(classifyVO.getOid(),functionId);
+		if (classifyVO != null) {
+			return getUIInfoByClassifyOid(classifyVO.getOid(), functionId);
 		}
 		return null;
 	}
@@ -3062,7 +3067,7 @@
 	 * 浼犲叆涓氬姟绫诲瀷浠ュ強鐩竜id闆嗗悎鏌ヨ鏁版嵁杩涜杩斿洖
 	 *
 	 * @param btmType 涓氬姟绫诲瀷
-	 * @param oids      闇�瑕佹煡璇㈢殑oid闆嗗悎 閫楀彿鍒嗗紑
+	 * @param oids    闇�瑕佹煡璇㈢殑oid闆嗗悎 閫楀彿鍒嗗紑
 	 * @return 鏌ヨ鍑虹殑鏁版嵁
 	 */
 	@Override
@@ -3070,7 +3075,7 @@
 
 		//浣跨敤浼犲叆鐨勪笟鍔$被鍨嬫煡璇㈣〃
 		R<List<BtmTypeVO>> listR = btmTypeClient.selectByIdCollection(Collections.singletonList(btmType));
-		if(listR.getData().size() == 0){
+		if (listR.getData().size() == 0) {
 			throw new VciBaseException("浼犲叆涓氬姟绫诲瀷鏈煡璇㈠埌鐩稿簲琛ㄥ崟锛岃妫�鏌ワ紒");
 		}
 		//鏌ヨ鏁版嵁
@@ -3215,4 +3220,149 @@
 
 		return R.success("鏇存柊鎴愬姛锛�");
 	}
+
+	/**
+	 * 鑾峰彇鍙傜収鐨勪俊鎭�
+	 *
+	 * @param referConfigVO 鍙傜収鐨勯厤缃�
+	 * @param pageHelper    鍒嗛〉鐨勫伐鍏�
+	 * @return 鍒楄〃鏁版嵁
+	 */
+	@Override
+	public DataGrid referDataGrid(UIFormReferVO referConfigVO, PageHelper pageHelper) {
+//		checkReferConfig(referConfigVO);
+		//浣跨敤涓氬姟绫诲瀷鏌ヨ
+		R<BtmTypeVO> allAttributeByBtmId = btmTypeClient.getAllAttributeByBtmId(referConfigVO.getReferType());
+		BtmTypeVO btmTypeVO = allAttributeByBtmId.getData();
+		if (referConfigVO.getWhere() == null) {
+			referConfigVO.setWhere(new HashMap<>());
+		}
+		/**
+		 * 鍔犱笂鏌ヨ鏈�鏂扮増娆�
+		 */
+		Map<String, String> conditionMap = new HashMap<>();
+		conditionMap.put("lastr", "1");
+		conditionMap.put("lastv", "1");
+		referConfigVO.getWhere().putAll(conditionMap);
+		if (VciBaseUtil.containsKeyUnCaseForMap(referConfigVO.getWhere(), VciQueryWrapperForDO.LC_STATUS_FIELD) &&
+			BtmTypeLcStatusConstant.FRAME_WORK_LIFE_CYCLE_NAME.equalsIgnoreCase(btmTypeVO.getLifeCycleId())) {
+			referConfigVO.getWhere().put(VciQueryWrapperForDO.LC_STATUS_FIELD, FrameworkDataLCStatus.ENABLED.getValue());
+		}
+		if (VciBaseUtil.containsKeyUnCaseForMap(referConfigVO.getWhere(), VciQueryWrapperForDO.LC_STATUS_FIELD) &&
+			BtmTypeLcStatusConstant.RELEASE_LIFE_CYCLE.equalsIgnoreCase(btmTypeVO.getLifeCycleId())) {
+			referConfigVO.getWhere().put(VciQueryWrapperForDO.LC_STATUS_FIELD, CodeDefaultLC.RELEASED.getValue());
+		}
+		BaseQueryObject baseQueryObject = new BaseQueryObject();
+		Map<String, String> where = referConfigVO.getWhere();
+		where.put("domain", AppConstant.APPLICATION_NAME_CODE);
+		baseQueryObject.setConditionMap(where);
+		baseQueryObject.setPage(pageHelper.getPage());
+		baseQueryObject.setSort(pageHelper.getSort());
+		baseQueryObject.setLimit(pageHelper.getLimit());
+		baseQueryObject.setOrder(pageHelper.getOrder());
+		R<List<BtmTypeVO>> ref = btmTypeClient.getRef(baseQueryObject);
+		DataGrid<BtmTypeVO> btmTypeVODataGrid = new DataGrid<>();
+		List<BtmTypeVO> data = ref.getData();
+		btmTypeVODataGrid.setData(data);
+		btmTypeVODataGrid.setCode(ref.getCode());
+		btmTypeVODataGrid.setLimit(pageHelper.getLimit());
+		btmTypeVODataGrid.setMsg(ref.getMsg());
+		btmTypeVODataGrid.setSort(pageHelper.getSort());
+		btmTypeVODataGrid.setOrder(pageHelper.getOrder());
+		btmTypeVODataGrid.setPage(pageHelper.getPage());
+		return btmTypeVODataGrid;
+	}
+
+	/**
+	 * 鑾峰彇鏍戝舰鐨勫弬鐓�
+	 *
+	 * @param referConfigVO 鍙傜収鐨勯厤缃�
+	 * @return 鏍戝舰鐨勬暟鎹�
+	 */
+	@Override
+	public List<Tree> referTree(UIFormReferVO referConfigVO, TreeQueryObject queryObject) {
+		if (queryObject.getConditionMap() == null) {
+			queryObject.setConditionMap(new HashMap<>());
+		}
+
+		if (queryObject.getParentOid()==null){
+			LambdaQueryWrapper<CodeClassify> lqw = new LambdaQueryWrapper<>();
+			String parentValue = referConfigVO.getParentValue().substring(3);
+			lqw.inSql(CodeClassify::getOid,parentValue);
+			List<String> codeClassifies = classifyService.select1(lqw);
+			String oid = codeClassifies.get(0);
+			queryObject.setParentOid(oid);
+		}
+		String oidFieldName = StringUtils.isNotBlank(referConfigVO.getParentUsedField()) ? referConfigVO.getParentUsedField() : referConfigVO.getValueField();
+		if (queryObject.isQueryAllLevel()) {
+			String parentOidSql = "";
+			if (StringUtils.isNotBlank(referConfigVO.getParentValue())) {
+				String temp = referConfigVO.getParentValue();
+				if (temp.startsWith(QueryOptionConstant.IN)) {
+					temp = temp.substring((QueryOptionConstant.IN).length()).trim();
+					parentOidSql = " in " + ((temp.startsWith("(") && temp.endsWith(")")) ? temp : "(" + temp + ")");
+				} else if (temp.startsWith(QueryOptionConstant.NOTIN)) {
+					parentOidSql = " not in " + ((temp.startsWith("(") && temp.endsWith(")")) ? temp : "(" + temp + ")");
+				} else if (temp.startsWith(QueryOptionConstant.NOTEQUAL)) {
+					temp = temp.substring((QueryOptionConstant.NOTEQUAL).length()).trim();
+					parentOidSql = QueryOptionConstant.NOTEQUAL + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
+				} else if (temp.startsWith(QueryOptionConstant.MORETHAN)) {
+					temp = temp.substring((QueryOptionConstant.MORETHAN).length()).trim();
+					parentOidSql = QueryOptionConstant.MORETHAN + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
+				} else if (temp.startsWith(QueryOptionConstant.MORE)) {
+					temp = temp.substring((QueryOptionConstant.MORE).length()).trim();
+					parentOidSql = QueryOptionConstant.MORE + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
+				} else if (temp.startsWith(QueryOptionConstant.LESSTHAN)) {
+					temp = temp.substring((QueryOptionConstant.LESSTHAN).length()).trim();
+					parentOidSql = QueryOptionConstant.LESSTHAN + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
+				} else if (temp.startsWith(QueryOptionConstant.LESS)) {
+					temp = temp.substring((QueryOptionConstant.LESS).length()).trim();
+					parentOidSql = QueryOptionConstant.LESS + " " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
+				} else if (temp.startsWith(QueryOptionConstant.ISNOTNULL)) {
+					parentOidSql = " is not null";
+				} else if (temp.startsWith(QueryOptionConstant.ISNULL)) {
+					parentOidSql = " is  null";
+				} else if (temp.contains("*")) {
+					parentOidSql = " like " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'").replace("*", "%");
+				} else {
+					parentOidSql = " = " + ((temp.startsWith("'") && temp.endsWith("'")) ? temp : "'" + temp + "'");
+				}
+
+			}
+			//鏌ヨ鍏ㄩ儴鐨勪俊鎭�
+			queryObject.getConditionMap().put("oid", QueryOptionConstant.IN + "(select oid from " +
+					getTableName(referConfigVO.getReferType())+
+				" START WITH " + referConfigVO.getParentFieldName() + " " +
+				parentOidSql +
+				" CONNECT BY PRIOR " + oidFieldName + " = " + referConfigVO.getParentFieldName() + ")");
+		} else {
+			if (StringUtils.isNotBlank(referConfigVO.getParentFieldName()) && StringUtils.isNotBlank(queryObject.getParentOid())) {
+				queryObject.getConditionMap().put(referConfigVO.getParentFieldName(), queryObject.getParentOid());
+			}
+		}
+		LambdaQueryWrapper<CodeClassify> lqw = new LambdaQueryWrapper<>();
+		String sql = queryObject.getConditionMap().get("oid").substring(3);
+		lqw.inSql(CodeClassify::getOid,sql);
+		List<CodeClassify> codeClassifies = classifyService.selectByWrapper(lqw);
+		TreeWrapperOptions treeWrapperOptions = new TreeWrapperOptions(referConfigVO.getParentFieldName());
+		treeWrapperOptions.setOidFieldName(oidFieldName);
+		treeWrapperOptions.setTextFieldName(referConfigVO.getTextField());
+		treeWrapperOptions.setMultipleSelect(referConfigVO.isMuti());
+		treeWrapperOptions.setParentOid(queryObject.getParentOid());
+		return revisionModelUtil.doList2Trees(codeClassifies, treeWrapperOptions, null);
+	}
+
+	private String getTableName(String refertype){
+		if ("codeclassify".equals(refertype)){
+			return "pl_code_classify";
+		}
+		if ("table".equals(refertype)){
+			return "pl_code_test_table";
+		}
+		if ("testBtmType".equals(refertype)){
+			return "PLBT_code_testBtmType";
+		}
+
+		return "pl_code_"+refertype.trim().toLowerCase();
+	}
 }
diff --git a/Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/UserPwdstrategyController.java b/Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/UserPwdstrategyController.java
index 2f2c340..ab2293e 100644
--- a/Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/UserPwdstrategyController.java
+++ b/Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/UserPwdstrategyController.java
@@ -13,6 +13,7 @@
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
+import java.util.List;
 
 /**
  * 鐢ㄦ埛瀵嗙爜绛栫暐鍏宠仈(UserPwdstrategy)琛ㄦ帶鍒跺眰
diff --git a/Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/service/impl/UserServiceImpl.java b/Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/service/impl/UserServiceImpl.java
index 1680c0b..7ce5654 100644
--- a/Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/service/impl/UserServiceImpl.java
+++ b/Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/service/impl/UserServiceImpl.java
@@ -336,7 +336,7 @@
 		regex = "^"+regex+"{"+strategy.getRequiredType()+",}$";
 		boolean result = RegexUtil.find(regex, newPassword1);
 		if(!result){
-			throw new ServiceException(resException);
+			//throw new ServiceException(resException);
 		}
 		//淇敼瀵嗙爜鍚屾椂锛屾敼鍙樼敤鎴蜂俊鎭腑鐨勫瘑鐮佷慨鏀圭姸鎬佸瓧娈�,瀵嗙爜淇敼鏃堕棿
 		return this.update(Wrappers.<User>update().lambda()

--
Gitblit v1.9.3