From adeb4d53b1f93ee1402c2e124ae69c2cd637e817 Mon Sep 17 00:00:00 2001
From: zhaowei <zhaowei>
Date: 星期五, 04 七月 2025 19:49:46 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 src/components/jeecgbiz/JSelectRepairDepart.vue            |  183 ++++++++++++++++++
 src/views/system/UserList.vue                              |    7 
 src/views/system/modules/UserModal.vue                     |   82 +++++++
 src/components/jeecgbiz/modal/JSelectRepairDepartModal.vue |  294 +++++++++++++++++++++++++++++
 4 files changed, 560 insertions(+), 6 deletions(-)

diff --git a/src/components/jeecgbiz/JSelectRepairDepart.vue b/src/components/jeecgbiz/JSelectRepairDepart.vue
new file mode 100644
index 0000000..c2442a1
--- /dev/null
+++ b/src/components/jeecgbiz/JSelectRepairDepart.vue
@@ -0,0 +1,183 @@
+<template>
+  <div class="components-input-demo-presuffix">
+    <!---->
+    <a-input @click="openModal" placeholder="璇风偣鍑婚�夋嫨缁翠慨閮ㄩ棬" v-model="textVals" readOnly :disabled="disabled">
+      <a-icon slot="prefix" type="cluster" title="缁翠慨閮ㄩ棬閫夋嫨鎺т欢"/>
+      <a-icon v-if="storeVals" slot="suffix" type="close-circle" @click="handleEmpty" title="娓呯┖"/>
+    </a-input>
+    <j-select-repair-depart-modal
+      ref="innerRepairDepartSelectModal"
+      :modal-width="modalWidth"
+      :multi="multi"
+      :rootOpened="rootOpened"
+      :repairDepartId="value"
+      :store="storeField"
+      :text="textField"
+      :treeRepairDepartOpera="treeRepairDepartOpera"
+      @ok="handleOK"
+      @initComp="initComp">
+
+    </j-select-repair-depart-modal>
+  </div>
+</template>
+
+<script>
+  import JSelectRepairDepartModal from './modal/JSelectRepairDepartModal'
+  import { underLinetoHump } from '@/components/_util/StringUtil'
+  export default {
+    name: 'JSelectRepairDepart',
+    components:{
+      JSelectRepairDepartModal
+    },
+    props:{
+      modalWidth:{
+        type:Number,
+        default:500,
+        required:false
+      },
+      multi:{
+        type:Boolean,
+        default:false,
+        required:false
+      },
+      rootOpened:{
+        type:Boolean,
+        default:true,
+        required:false
+      },
+      value:{
+        type:String,
+        required:false
+      },
+      disabled:{
+        type: Boolean,
+        required: false,
+        default: false
+      },
+      // 鑷畾涔夎繑鍥炲瓧娈碉紝榛樿杩斿洖 id
+      customReturnField: {
+        type: String,
+        default: ''
+      },
+      backRepairDepart: {
+        type: Boolean,
+        default: false,
+        required: false
+      },
+      // 瀛樺偍瀛楁 [key field]
+      store: {
+        type: String,
+        default: 'id',
+        required: false
+      },
+      // 鏄剧ず瀛楁 [label field]
+      text: {
+        type: String,
+        default: 'departName',
+        required: false
+      },
+      treeRepairDepartOpera: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+
+    },
+    data(){
+      return {
+        visible:false,
+        confirmLoading:false,
+        storeVals: '', //[key values]
+        textVals: '' //[label values]
+      }
+    },
+    computed:{
+      storeField(){
+        let field = this.customReturnField
+        if(!field){
+          field = this.store;
+        }
+        return underLinetoHump(field)
+      },
+      textField(){
+        return underLinetoHump(this.text)
+      }
+    },
+    mounted(){
+      this.storeVals = this.value
+    },
+    watch:{
+      value(val){
+        this.storeVals = val
+      }
+    },
+    methods:{
+      initComp(textVals){
+        this.textVals = textVals
+      },
+      //杩斿洖閫変腑鐨勮溅闂翠俊鎭�
+      backRepairDepartInfo(){
+        if(this.backRepairDepart===true){
+          //LOWCOD-2147 銆愮敤鎴风鐞嗐�戦�夋嫨閮ㄩ棬鍜屼笂绾т互鍚庯紝璐熻矗閮ㄩ棬娌℃湁鏁版嵁鍙�� (闄剁値鏀归�犺嚜瀹氫箟杩斿洖瀛楁瀵艰嚧)
+          if(this.storeVals && this.storeVals.length>0){
+            let arr1 = this.storeVals.split(',')
+            let arr2 = this.textVals.split(',')
+            let info = []
+            for(let i=0;i<arr1.length;i++){
+              info.push({
+                value: arr1[i],
+                text: arr2[i]
+              })
+            }
+            this.$emit('back', info)
+          }
+        }
+      },
+      openModal(){
+        this.$refs.innerRepairDepartSelectModal.show()
+      },
+      handleOK(rows) {
+        if (!rows && rows.length <= 0) {
+          this.textVals = ''
+          this.storeVals = ''
+        } else {
+          let arr1 = []
+          let arr2 = []
+          for(let dep of rows){
+            arr1.push(dep[this.storeField])
+            arr2.push(dep[this.textField])
+          }
+          this.storeVals = arr1.join(',')
+          this.textVals = arr2.join(',')
+        }
+        this.$emit("change", this.storeVals)
+        this.backRepairDepartInfo()
+      },
+      getRepairDepartNames(){
+        return this.departNames
+      },
+      handleEmpty(){
+        this.handleOK('')
+      }
+    },
+    model: {
+      prop: 'value',
+      event: 'change'
+    }
+  }
+</script>
+
+<style scoped>
+  .components-input-demo-presuffix .anticon-close-circle {
+    cursor: pointer;
+    color: #ccc;
+    transition: color 0.3s;
+    font-size: 12px;
+  }
+  .components-input-demo-presuffix .anticon-close-circle:hover {
+    color: #f5222d;
+  }
+  .components-input-demo-presuffix .anticon-close-circle:active {
+    color: #666;
+  }
+</style>
\ No newline at end of file
diff --git a/src/components/jeecgbiz/modal/JSelectRepairDepartModal.vue b/src/components/jeecgbiz/modal/JSelectRepairDepartModal.vue
new file mode 100644
index 0000000..681d17d
--- /dev/null
+++ b/src/components/jeecgbiz/modal/JSelectRepairDepartModal.vue
@@ -0,0 +1,294 @@
+<template>
+  <j-modal
+    title="閫夋嫨缁翠慨閮ㄩ棬"
+    :width="modalWidth"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    @ok="handleSubmit"
+    @cancel="handleCancel"
+    @update:fullscreen="isFullscreen"
+    wrapClassName="j-repair-depart-select-modal"
+    switchFullscreen
+    cancelText="鍏抽棴">
+    <a-spin tip="Loading..." :spinning="false">
+      <a-input-search style="margin-bottom: 1px" placeholder="璇疯緭鍏ョ淮淇儴闂ㄥ悕绉版寜鍥炶溅杩涜鎼滅储" @search="onSearch" />
+      <a-tree
+        checkable
+        :class="treeScreenClass"
+        :treeData="treeData"
+        :checkStrictly="checkStrictly"
+        @check="onCheck"
+        @select="onSelect"
+        @expand="onExpand"
+        :autoExpandParent="autoExpandParent"
+        :expandedKeys="expandedKeys"
+        :checkedKeys="checkedKeys">
+
+        <template slot="title" slot-scope="{title}">
+          <span v-if="title.indexOf(searchValue) > -1">
+            {{title.substr(0, title.indexOf(searchValue))}}
+            <span style="color: #f50">{{searchValue}}</span>
+            {{title.substr(title.indexOf(searchValue) + searchValue.length)}}
+          </span>
+          <span v-else>{{title}}</span>
+        </template>
+      </a-tree>
+    </a-spin>
+  </j-modal>
+</template>
+
+<script>
+  import { queryRepairDepartTreeList } from '@/api/api'
+  export default {
+    name: 'JSelectRepairDepartModal',
+    props:['modalWidth','multi','rootOpened','repairDepartId', 'store', 'text','treeOpera'],
+    data(){
+      return {
+        visible:false,
+        confirmLoading:false,
+        treeData:[],
+        autoExpandParent:true,
+        expandedKeys:[],
+        dataList:[],
+        checkedKeys:[],
+        checkedRows:[],
+        searchValue:"",
+        checkStrictly: false,
+        fullscreen:false
+      }
+    },
+    created(){
+      this.loadRepairDepart();
+    },
+    watch:{
+      repairDepartId(){
+        this.initDepartComponent()
+      },
+      visible: {
+        handler() {
+          this.initRepairDepartComponent(true)
+        }
+      }
+    },
+    computed:{
+      treeScreenClass() {
+        return {
+          'my-dept-select-tree': true,
+          'fullscreen': this.fullscreen,
+        }
+      },
+    },
+    methods:{
+      show(){
+        this.visible=true
+        this.checkedRows=[]
+        this.checkedKeys=[]
+      },
+      loadRepairDepart(){
+        // 杩欎釜鏂规硶鏄壘鍒版墍鏈夌殑閮ㄩ棬淇℃伅
+        queryRepairDepartTreeList().then(res=>{
+          if(res.success){
+            let arr = [...res.result]
+            this.reWriterWithSlot(arr)
+            this.treeData = arr
+            this.initRepairDepartComponent()
+            if(this.rootOpened){
+              this.initExpandedKeys(res.result)
+            }
+          }
+        })
+      },
+      initRepairDepartComponent(flag){
+        let arr = []
+        //璇ユ柟娉曚袱涓湴鏂圭敤 1.visible鏀瑰彉浜嬩欢閲嶆柊璁剧疆閫変腑椤� 2.缁勪欢缂栬緫椤甸潰鍥炴樉
+        let fieldName = flag==true?'key':this.text
+        if(this.repairDepartId){
+          let arr2 = this.repairDepartId.split(',')
+          for(let item of this.dataList){
+            if(arr2.indexOf(item[this.store])>=0){
+              arr.push(item[fieldName])
+            }
+          }
+        }
+        if(flag==true){
+          this.checkedKeys = [...arr]
+        }else{
+          this.$emit("initComp", arr.join(','))
+        }
+      },
+      reWriterWithSlot(arr){
+        for(let item of arr){
+          if(item.children && item.children.length>0){
+            this.reWriterWithSlot(item.children)
+            let temp = Object.assign({},item)
+            temp.children = {}
+            this.dataList.push(temp)
+          }else{
+            this.dataList.push(item)
+            item.scopedSlots={ title: 'title' }
+          }
+        }
+      },
+      initExpandedKeys(arr){
+        if(arr && arr.length>0){
+          let keys = []
+          for(let item of arr){
+            if(item.children && item.children.length>0){
+              keys.push(item.id)
+            }
+          }
+          this.expandedKeys=[...keys]
+          //鍏ㄩ儴keys
+          //this.allTreeKeys = [...keys]
+        }else{
+          this.expandedKeys=[]
+          //this.allTreeKeys = []
+        }
+      },
+      onCheck (checkedKeys,info) {
+        if(!this.multi){
+          let arr = checkedKeys.checked.filter(item => this.checkedKeys.indexOf(item) < 0)
+          this.checkedKeys = [...arr]
+          this.checkedRows = (this.checkedKeys.length === 0) ? [] : [info.node.dataRef]
+        }else{
+          if(this.checkStrictly){
+            this.checkedKeys = checkedKeys.checked
+          }else{
+            this.checkedKeys = checkedKeys
+          }
+          this.checkedRows = this.getCheckedRows(this.checkedKeys)
+        }
+      },
+      onSelect(selectedKeys,info) {
+        //鍙栨秷鍏宠仈鐨勬儏鍐典笅鎵嶈蛋onSelect鐨勯�昏緫
+        if(this.checkStrictly){
+          let keys = []
+          keys.push(selectedKeys[0])
+          if(!this.checkedKeys || this.checkedKeys.length===0 || !this.multi){
+            this.checkedKeys = [...keys]
+            this.checkedRows=[info.node.dataRef]
+          }else{
+            let currKey = info.node.dataRef.key
+            if(this.checkedKeys.indexOf(currKey)>=0){
+              this.checkedKeys = this.checkedKeys.filter(item=> item !==currKey)
+            }else{
+              this.checkedKeys.push(...keys)
+            }
+          }
+          this.checkedRows = this.getCheckedRows(this.checkedKeys)
+        }
+      },
+      onExpand (expandedKeys) {
+        this.expandedKeys = expandedKeys
+        this.autoExpandParent = false
+      },
+      handleSubmit(){
+        if(!this.checkedKeys || this.checkedKeys.length==0){
+          this.$emit("ok",'')
+        }else{
+          let checkRow = this.getCheckedRows(this.checkedKeys)
+          let keyStr = this.checkedKeys.join(",")
+          this.$emit("ok", checkRow, keyStr)
+        }
+        this.handleClear()
+      },
+      handleCancel(){
+        this.handleClear()
+      },
+      handleClear(){
+        this.visible=false
+        this.checkedKeys=[]
+      },
+      getParentKey(currKey,treeData){
+        let parentKey
+        for (let i = 0; i < treeData.length; i++) {
+          const node = treeData[i]
+          if (node.children) {
+            if (node.children.some(item => item.key === currKey)) {
+              parentKey = node.key
+            } else if (this.getParentKey(currKey, node.children)) {
+              parentKey = this.getParentKey(currKey, node.children)
+            }
+          }
+        }
+        return parentKey
+      },
+      onSearch(value){
+        const expandedKeys = this.dataList.map((item) => {
+          if (item.title.indexOf(value) > -1) {
+            return this.getParentKey(item.key,this.treeData)
+          }
+          return null
+        }).filter((item, i, self) => item && self.indexOf(item) === i)
+
+        Object.assign(this, {
+          expandedKeys,
+          searchValue: value,
+          autoExpandParent: true,
+        })
+
+
+      },
+      // 鏍规嵁 checkedKeys 鑾峰彇 rows
+      getCheckedRows(checkedKeys) {
+        const forChildren = (list, key) => {
+          for (let item of list) {
+            if (item.id === key) {
+              return item
+            }
+            if (item.children instanceof Array) {
+              let value = forChildren(item.children, key)
+              if (value != null) {
+                return value
+              }
+            }
+          }
+          return null
+        }
+
+        let rows = []
+        for (let key of checkedKeys) {
+          let row = forChildren(this.treeData, key)
+          if (row != null) {
+            rows.push(row)
+          }
+        }
+        return rows
+      },
+      switchCheckStrictly (v) {
+        if(v==1){
+          this.checkStrictly = false
+        }else if(v==2){
+          this.checkStrictly = true
+        }
+      },
+      isFullscreen(val){
+        this.fullscreen=val
+      }
+    }
+  }
+
+</script>
+
+<style lang="less" scoped>
+  // 闄愬埗閮ㄩ棬閫夋嫨鏍戦珮搴︼紝閬垮厤閮ㄩ棬澶鏃剁偣鍑荤‘瀹氫笉渚�
+  .my-dept-select-tree{
+    height:350px;
+
+    &.fullscreen{
+      height: calc(100vh - 250px);
+    }
+    overflow-y: scroll;
+  }
+  .drawer-bootom-button {
+    position: absolute;
+    bottom: 0;
+    width: 100%;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    text-align: right;
+    left: 0;
+    background: #fff;
+    border-radius: 0 0 2px 2px;
+  }
+</style>
\ No newline at end of file
diff --git a/src/views/system/UserList.vue b/src/views/system/UserList.vue
index 5c9d39c..b186bbc 100644
--- a/src/views/system/UserList.vue
+++ b/src/views/system/UserList.vue
@@ -220,6 +220,13 @@
             ellipsis: true,
           },
           {
+            title: '缁翠慨閮ㄩ棬',
+            align: "center",
+            width: 240,
+            dataIndex: 'repairDepartName',
+            ellipsis: true,
+          },
+          {
             title: '鐘舵��',
             align: "center",
             width: 80,
diff --git a/src/views/system/modules/UserModal.vue b/src/views/system/modules/UserModal.vue
index 0bb2e81..375d389 100644
--- a/src/views/system/modules/UserModal.vue
+++ b/src/views/system/modules/UserModal.vue
@@ -212,6 +212,20 @@
           />
         </a-form-model-item>
 
+        <a-form-model-item
+          label="缁翠慨閮ㄩ棬/鐝粍鍒嗛厤"
+          :labelCol="labelCol"
+          :wrapperCol="wrapperCol"
+          v-show="!repairDepartDisabled"
+        >
+          <j-select-repair-depart
+            v-model="model.selectedRepairDeparts"
+            :multi="true"
+            @back="backRepairDepartInfo"
+            :backRepairDepart="true"
+            :treeRepairDepartOpera="true"
+          ></j-select-repair-depart>
+        </a-form-model-item>
 
         <a-form-model-item
           label="璐熻矗閮ㄩ棬"
@@ -267,6 +281,7 @@
   import { disabledAuthFilter } from '@/utils/authFilter'
   import { duplicateCheck } from '@/api/api'
   import JSelectProduction from '../../../components/jeecgbiz/JSelectProduction'
+  import JSelectRepairDepart from '../../../components/jeecgbiz/JSelectRepairDepart'
   import { mapActions } from 'vuex'
   import { ajaxGetDictItems, getDictItemsFromCache } from '@/api/api'
   import SelectDeviceModal from './SelectDeviceModal'
@@ -275,13 +290,15 @@
     name: 'UserModal',
     components: {
       SelectDeviceModal,
-      JSelectProduction
+      JSelectProduction,
+      JSelectRepairDepart
     },
     data() {
       return {
         departDisabled: false, //鏄惁鏄垜鐨勯儴闂ㄨ皟鐢ㄨ椤甸潰
         productionDisabled: false, //鏄惁鏄垜鐨勮溅闂磋皟鐢ㄨ椤甸潰
         roleDisabled: false, //鏄惁鏄鑹茬淮鎶よ皟鐢ㄨ椤甸潰
+        repairDepartDisabled: false, //鏄惁鏄垜鐨勭淮淇儴闂ㄧ彮缁勮皟鐢ㄨ椤甸潰
         modalWidth: 800,
         drawerWidth: 700,
         modaltoggleFlag: true,
@@ -331,15 +348,19 @@
           userProductionList: '/sys/user/userProductionList',
           userId: '/sys/user/generateUserId', // 寮曞叆鐢熸垚娣诲姞鐢ㄦ埛鎯呭喌涓嬬殑url
           syncUserByUserName: '/act/process/extActProcess/doSyncUserByUserName',//鍚屾鐢ㄦ埛鍒板伐浣滄祦
-          queryTenantList: '/sys/tenant/queryList'
+          queryTenantList: '/sys/tenant/queryList',
+          userRepairDepartList: '/sys/user/userRepairDepartList',
+          repairDepartTreeList: '/eam/eamBaseRepairDepart/queryTreeList'
         },
         tenantsOptions: [],
         rolesOptions: [],
         nextDepartOptions: [],
         nextProductionOptions: [],
+        nextRepairDepartOptions: [],
         isDepartType: '',
         model: {
-          selectedProduction: ''
+          selectedProduction: '',
+          selectedRepairDeparts: ''
         }
       }
     },
@@ -367,6 +388,7 @@
       this.initRoleList()
       this.initTenantList()
       this.queryTreeData()
+      this.getRepairDepartTreeDataByApi()
     },
     computed: {
       uploadAction: function() {
@@ -389,6 +411,20 @@
         }).finally(() => {
         })
       },
+      // 鑾峰彇缁翠慨鐝粍鏍�
+      getRepairDepartTreeDataByApi() {
+        getAction(this.url.repairDepartTreeList)
+          .then(res => {
+            if (res.success) {
+              this.repairDepartTreeData = res.result
+            } else {
+              this.$notification.warning({
+                message: '娑堟伅',
+                description: res.message
+              })
+            }
+          })
+      },
       add() {
         this.refresh()
         this.edit({
@@ -397,7 +433,8 @@
           userIdentity: 1,
           selectedroles: '',
           selecteddeparts: '',
-          selectedProduction: ''
+          selectedProduction: '',
+          selectedRepairDeparts: ''
         })
       },
       edit(record) {
@@ -418,6 +455,8 @@
         if (record.hasOwnProperty('id')) {
           that.getUserRoles(record.id)
           that.getUserDeparts(record.id)
+          that.getUserProductions(record.id)
+          that.getUserRepairDeparts(record.id)
         }
       },
       isDisabledAuth(code) {
@@ -490,7 +529,9 @@
             that.nextDepartOptions = departOptions
           }
         })
-
+      },
+      getUserProductions(userid) {
+        let that = this
         // 鑾峰彇杞﹂棿鍒嗛厤
         getAction(that.url.userProductionList, { userId: userid }).then((res) => {
           if (res.success) {
@@ -509,7 +550,27 @@
             that.nextProductionOptions = ProductionOptions
           }
         })
-        //杞﹂棿鐨剈rl
+      },
+      getUserRepairDeparts(userid) {
+        let that = this
+        // 鑾峰彇缁翠慨閮ㄩ棬/鐝粍鍒嗛厤
+        getAction(that.url.userRepairDepartList, { userId: userid }).then((res) => {
+          if (res.success) {
+            let repairDepartOptions = []
+            let selectedRepairDepartKeys = []
+            for (let i = 0; i < res.result.length; i++) {
+              selectedRepairDepartKeys.push(res.result[i].key)
+              //鏂板璐熻矗缁翠慨閮ㄩ棬/鐝粍閫夋嫨涓嬫媺妗�
+              repairDepartOptions.push({
+                value: res.result[i].key,
+                label: res.result[i].title
+              })
+            }
+
+            this.$set(this.model, 'selectedRepairDeparts', selectedRepairDepartKeys.join(','))
+            that.nextRepairDepartOptions = repairDepartOptions
+          }
+        })
       },
       backDepartInfo(info) {
         this.model.departIds = this.model.selecteddeparts
@@ -525,11 +586,19 @@
           return c
         })
       },
+      backRepairDepartInfo(info) {
+        this.model.repairDepartIds = this.model.selectedRepairDeparts
+        this.nextRepairDepartOptions = info.map((item, index, arr) => {
+          let c = { label: item.text, value: item.value + '' }
+          return c
+        })
+      },
 
       refresh() {
         this.userId = ''
         this.nextDepartOptions = []
         this.nextProductionOptions = []
+        this.nextRepairDepartOptions = []
         this.departIdShow = false
       },
       close() {
@@ -538,6 +607,7 @@
         this.disableSubmit = false
         this.nextDepartOptions = []
         this.nextProductionOptions = []
+        this.nextRepairDepartOptions = []
         this.departIdShow = false
         this.$refs.form.resetFields()
       },

--
Gitblit v1.9.3