156 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <section class="AiLibTable">
 | |
|     <ai-search-bar>
 | |
|       <template v-if="$scopedSlots.left" #left>
 | |
|         <slot name="left"/>
 | |
|       </template>
 | |
|       <template #right>
 | |
|         <slot v-if="$scopedSlots.right" name="right"/>
 | |
|         <el-input v-else placeholder="搜索应用名称" size="small" v-model="search[searchKey]" @change="page.current=1,getTableData()" clearable/>
 | |
|       </template>
 | |
|     </ai-search-bar>
 | |
|     <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :colConfigs="columns"
 | |
|               :size.sync="page.size" @getList="getTableData" tableSize="mini" :dict="dict" v-bind="$attrs" :pageSizes="[10,50,100,200,500]">
 | |
|       <el-table-column slot="chb" width="100px" v-if="!disabled">
 | |
|         <template #header>
 | |
|           <el-checkbox v-if="multiple" v-model="selectAll" @change="handleCheckAll"/>
 | |
|         </template>
 | |
|         <template slot-scope="{row}">
 | |
|           <el-checkbox v-model="row.checked" @change="handleCheck(row)"/>
 | |
|         </template>
 | |
|       </el-table-column>
 | |
|       <el-table-column v-if="$scopedSlots.options" slot="options" label="操作" align="center">
 | |
|         <template slot-scope="scope">
 | |
|           <slot name="options" v-bind="scope"/>
 | |
|         </template>
 | |
|       </el-table-column>
 | |
|     </ai-table>
 | |
|   </section>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|   name: "AiLibTable",
 | |
|   model: {
 | |
|     prop: "value",
 | |
|     event: "change"
 | |
|   },
 | |
|   props: {
 | |
|     value: {default: null},
 | |
|     instance: Function,
 | |
|     dict: Object,
 | |
|     permissions: Function,
 | |
|     action: {default: "/node/wechatapps/list"},
 | |
|     colConfigs: {
 | |
|       default: () => [
 | |
|         {prop: 'label', label: "应用名称"},
 | |
|         {prop: 'project', label: "项目/框架"},
 | |
|         {prop: 'category', label: "分类"},
 | |
|         {prop: 'name', label: "模块名"},
 | |
|       ]
 | |
|     },
 | |
|     nodeKey: {default: "id"},
 | |
|     searchKey: {default: "name"},
 | |
|     multiple: Boolean,
 | |
|     disabled: Boolean,
 | |
|     meta: {default: () => []},
 | |
|     choose: {default: null},
 | |
|     customData: Boolean
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       page: {total: 0, current: 1, size: 10},
 | |
|       search: {},
 | |
|       tableData: [],
 | |
|       selectAll: false
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     columns() {
 | |
|       return [
 | |
|         {slot: "chb"}, ...this.colConfigs
 | |
|       ]
 | |
|     },
 | |
|     selected() {
 | |
|       const {choose, value, nodeKey} = this,
 | |
|           list = [choose].flat().map(e => e?.[nodeKey])
 | |
|       return [...new Set([value, list].flat())].filter(Boolean) || []
 | |
|     }
 | |
|   },
 | |
|   watch: {
 | |
|     action(v) {
 | |
|       v && (this.page.current = 1, this.getTableData())
 | |
|     },
 | |
|   },
 | |
|   methods: {
 | |
|     getTableData() {
 | |
|       const {page, search, action, meta, searchKey, dict, customData} = this
 | |
|       if (meta.length > 0 || customData) {
 | |
|         const reg = new RegExp(search[searchKey])
 | |
|         this.handleTableData(meta.filter(e => reg.test(e.label) || reg.test(e.name) || reg.test(e.category)))
 | |
|       } else this.instance?.post(action, null, {
 | |
|         params: {...page, ...search}
 | |
|       }).then(res => {
 | |
|         if (res?.data) {
 | |
|           this.page.total = res.data.total
 | |
|           this.handleTableData(res.data.records || res.data || [])
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     handleTableData(list) {
 | |
|       const {nodeKey} = this
 | |
|       list.map(e => {
 | |
|         e.category = e.libPath.replace(/^\/[^\/]+\/([^\/]+)\/.+/, '$1')
 | |
|         if (/\/project\//.test(e.libPath)) {
 | |
|           e.project = e.libPath.replace(/.*project\/([^\/]+)\/.+/, '$1')
 | |
|         } else if (/\/core\//.test(e.libPath)) {
 | |
|           e.project = "core"
 | |
|         } else e.project = "standard"
 | |
|       })
 | |
|       this.tableData = list.map(e => ({...e, checked: this.selected.includes(e[nodeKey])}))
 | |
|     },
 | |
|     handleCheck(row) {
 | |
|       const {nodeKey} = this
 | |
|       if (this.multiple) {
 | |
|         let selected = this.$copy(this.selected),
 | |
|             choose = this.$copy(this.choose) || []
 | |
|         if (row.checked) {
 | |
|           selected.push(row[nodeKey])
 | |
|           choose.push(row)
 | |
|         } else {
 | |
|           selected = selected.filter(e => e != row[nodeKey])
 | |
|           choose = choose.filter(e => e[nodeKey] != row[nodeKey])
 | |
|         }
 | |
|         this.$emit("change", selected)
 | |
|         this.$emit("update:choose", choose)
 | |
|         this.$emit("select", choose)
 | |
|       } else {
 | |
|         this.tableData.map(e => e.checked = e[nodeKey] == row.id && row.checked)
 | |
|         this.$emit("change", row.checked ? row[nodeKey] : '')
 | |
|         this.$emit("update:choose", row.checked ? row : null)
 | |
|         this.$emit("select", row.checked ? row : null)
 | |
|       }
 | |
|     },
 | |
|     handleCheckAll(v) {
 | |
|       const {nodeKey} = this
 | |
|       let selected = this.tableData.map(e => {
 | |
|         e.checked = v
 | |
|         return e
 | |
|       }).filter(e => e.checked) || []
 | |
|       this.$emit("change", selected?.map(e => e[nodeKey]))
 | |
|       this.$emit("update:choose", selected)
 | |
|       this.$emit("select", selected)
 | |
|     }
 | |
|   },
 | |
|   created() {
 | |
|     this.$set(this.search, this.searchKey, "")
 | |
|     this.getTableData()
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| .AiLibTable {
 | |
| }
 | |
| </style>
 |