fix
This commit is contained in:
		
							
								
								
									
										210
									
								
								packages/wxwork/AppMassNotification/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								packages/wxwork/AppMassNotification/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | |||||||
|  | <template> | ||||||
|  |   <ai-list class="List"> | ||||||
|  |     <template #title> | ||||||
|  |       <ai-title title="群发通知" isShowBottomBorder></ai-title> | ||||||
|  |     </template> | ||||||
|  |     <template #content> | ||||||
|  |       <ai-search-bar> | ||||||
|  |         <template #left> | ||||||
|  |           <el-button type="primary" icon="iconfont iconAdd" @click="toAdd('')">添加</el-button> | ||||||
|  |         </template> | ||||||
|  |       </ai-search-bar> | ||||||
|  |       <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" | ||||||
|  |                 @getList="getTableData" show-overflow-tooltip :col-configs="colConfigs" :dict="dict"> | ||||||
|  |         <!-- <el-table-column slot="type" width="240px" label="消息内容" align="center"> | ||||||
|  |           <template slot-scope="{ row }"> | ||||||
|  |             <el-popover | ||||||
|  |               placement="bottom" | ||||||
|  |               width="400" | ||||||
|  |               :visible-arrow="false" | ||||||
|  |               popper-class="wechat-message__container" | ||||||
|  |               trigger="hover"> | ||||||
|  |               <div class="count row-content" slot="reference" v-if="row.content">{{ row.content }}</div> | ||||||
|  |               <div class="message-info"> | ||||||
|  |                 <h2 :style="{marginBottom: row.accessUrl ? '16px' : '0'}">{{ row.content }}</h2> | ||||||
|  |                 <div class="message-info__wrapper" v-if="row.accessUrl"> | ||||||
|  |                   <img v-if="row.contentType == 'image'" :src="row.accessUrl"> | ||||||
|  |                   <video style="width:40px; height: 40px;" v-if="row.contentType == 'video'" :src="row.accessUrl"></video> | ||||||
|  |                   <img src="../../../../examples/assets/file.png" v-if="row.contentType == 'file'" width="40" height="40"/> | ||||||
|  |                   <div class="message-info__wrapper--right"> | ||||||
|  |                     <h3 v-if="row.contentType === 'image'">{{ row.media.file.name }}</h3> | ||||||
|  |                     <h3 v-if="row.contentType === 'video'">{{ row.media.file.name }}</h3> | ||||||
|  |                     <p v-if="row.contentType === 'image'">{{ row.media.file.fileSizeStr }}</p> | ||||||
|  |                     <p v-if="row.contentType === 'video'">{{ row.media.file.fileSizeStr }}</p> | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </el-popover> | ||||||
|  |           </template> | ||||||
|  |         </el-table-column>         --> | ||||||
|  |         <el-table-column slot="options" label="操作" align="center"> | ||||||
|  |           <template slot-scope="{ row }"> | ||||||
|  |             <el-button type="text" @click="toAdd(row.id)">详情</el-button> | ||||||
|  |             <!-- <el-button type="text" @click="handleDelete(row.id)">删除</el-button> --> | ||||||
|  |           </template> | ||||||
|  |         </el-table-column> | ||||||
|  |       </ai-table> | ||||||
|  |     </template> | ||||||
|  |   </ai-list> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import {mapState} from 'vuex' | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "List", | ||||||
|  |   props: { | ||||||
|  |     dict: Object, | ||||||
|  |     instance: Function, | ||||||
|  |     params: Object, | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       tableData: [], | ||||||
|  |       page: {current: 1, size: 10, total: 0, pages: 0}, | ||||||
|  |       id: '', | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getTableData() | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     colConfigs() { | ||||||
|  |       let conType = { | ||||||
|  |         text: "文本", | ||||||
|  |         image: "图片", | ||||||
|  |         video: "视频", | ||||||
|  |         file: "附件" | ||||||
|  |       } | ||||||
|  |       return [ | ||||||
|  |         // { prop: "fileList", label: '消息类型', align: "center", width: "250px", formart: v => v?.map(e=> conType[e.contentType]).toString() }, | ||||||
|  |         { prop: "fileList", label: '消息内容', align: "center", width: "250px", formart: v => v?.filter(e=> e.contentType == 'text')[0].content }, | ||||||
|  |         // { prop: "fileList", label: '消息内容', align: "center", width: "250px", formart: v => v?.filter(e => e.contentType == 'text')[0].content}, | ||||||
|  |         // { slot: 'type' }, | ||||||
|  |         { prop: "messageSource", label: '消息类型', align: "center", formart: v => v==1? '居民': '居民群'}, | ||||||
|  |         { prop: "createTime", label: '创建时间', align: "center", width: "250px"}, | ||||||
|  |         { prop: "userName", label: '创建人', align: "center", width: "250px", }, | ||||||
|  |         { slot: "options" ,}, | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     ...mapState(['user']) | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   methods: { | ||||||
|  |     getTableData() { | ||||||
|  |       this.instance.post(`/app/pushmessage/list?`, null, { | ||||||
|  |         params: { | ||||||
|  |           ...this.page, | ||||||
|  |         } | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.tableData = res.data.records | ||||||
|  |           this.page.total = res.data.total | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     mapType(type) { | ||||||
|  |       return { | ||||||
|  |         'image': '图片', | ||||||
|  |         'video': '视频', | ||||||
|  |         'file': '文件', | ||||||
|  |         'text': '文本' | ||||||
|  |       }[type] | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     toAdd(id) { | ||||||
|  |       this.$emit('change', { | ||||||
|  |         type: 'Add', | ||||||
|  |         params: { | ||||||
|  |           id: id || '', | ||||||
|  |         }, | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .List { | ||||||
|  |   height: 100%; | ||||||
|  |   background: #f3f4f5; | ||||||
|  |  | ||||||
|  |   .count { | ||||||
|  |     cursor: pointer; | ||||||
|  |     color: #2266FF; | ||||||
|  |     font-size: 14px; | ||||||
|  |  | ||||||
|  |     &:hover { | ||||||
|  |       opacity: 0.6; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | img, video { | ||||||
|  |   width: 40px; | ||||||
|  |   height: 40px; | ||||||
|  |   margin-right: 10px; | ||||||
|  |   object-fit: cover; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .message-info { | ||||||
|  |   padding: 8px; | ||||||
|  |   min-height: 116px; | ||||||
|  |  | ||||||
|  |   h2 { | ||||||
|  |     color: #222222; | ||||||
|  |     font-weight: 500; | ||||||
|  |     font-size: 14px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .message-info__wrapper { | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  |     width: 368px; | ||||||
|  |     height: 60px; | ||||||
|  |     padding: 10px; | ||||||
|  |     background: #FFFFFF; | ||||||
|  |     border-radius: 2px; | ||||||
|  |     border: 1px solid #D0D4DC; | ||||||
|  |  | ||||||
|  |     .message-info__wrapper--right { | ||||||
|  |       flex: 1; | ||||||
|  |       overflow: hidden; | ||||||
|  |       text-overflow: ellipsis; | ||||||
|  |       white-space: nowrap; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     h3 { | ||||||
|  |       width: 100%; | ||||||
|  |       color: #222222; | ||||||
|  |       font-size: 14px; | ||||||
|  |       overflow: hidden; | ||||||
|  |       text-overflow: ellipsis; | ||||||
|  |       white-space: nowrap; | ||||||
|  |       font-weight: normal; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     img, video { | ||||||
|  |       width: 40px; | ||||||
|  |       height: 40px; | ||||||
|  |       margin-right: 10px; | ||||||
|  |       object-fit: cover; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     p { | ||||||
|  |       margin-top: 6px; | ||||||
|  |       font-size: 14px; | ||||||
|  |       color: #888888; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .row-content { | ||||||
|  |   white-space: nowrap; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -0,0 +1,195 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="SelectDeptUser"> | ||||||
|  |     <el-input :value="selectText" disabled size="small" @click.native="dialog=true"> | ||||||
|  |       <el-button type="text" slot="append">开始选择</el-button> | ||||||
|  |     </el-input> | ||||||
|  |     <ai-dialog :visible.sync="dialog" title="选择部门/人员" width="700px" @onConfirm="handleSubmit" @close="selected=[],getDepts()"> | ||||||
|  |       <el-breadcrumb separator="/"> | ||||||
|  |         <el-breadcrumb-item v-for="(item, index) in selectDeptPath" :key="index"> | ||||||
|  |           <el-button type="text" @click="deptNameClick(item)">{{ item.name }}</el-button> | ||||||
|  |         </el-breadcrumb-item> | ||||||
|  |       </el-breadcrumb> | ||||||
|  |       <div class="optionsItem" v-for="(row, index) in options" :key="index"> | ||||||
|  |         <el-row type="flex"> | ||||||
|  |           <el-checkbox class="fill" :label="row.uid" v-model="row.checked" @change="handleCheck(row,index)">{{ row.name }}</el-checkbox> | ||||||
|  |           <el-button type="text" v-if="!row.parentid&&row.kind=='dept'" @click="openDialogTag(row)">添加标签</el-button> | ||||||
|  |           <el-button type="text" v-if="row.kind=='dept'" @click="itemClick(row)">更多</el-button> | ||||||
|  |         </el-row> | ||||||
|  |         <el-tag effect="dark" size="small" v-for="tag in row.selectedTags" :key="tag.id" class="mar-4">{{ tag.name }}</el-tag> | ||||||
|  |       </div> | ||||||
|  |       <ai-empty v-if="!options.length"/> | ||||||
|  |       <ai-dialog :visible.sync="dialogTag" title="选择标签" width="500px" @onConfirm="handleSelectTag" @close="selectedTags=[]" append-to-body> | ||||||
|  |         <el-checkbox-group v-model="selectedTags"> | ||||||
|  |           <div class="optionsItem" v-for="(cls, index) in tagOps" :key="index"> | ||||||
|  |             <ai-title :title="cls.name"/> | ||||||
|  |             <el-checkbox class="fill" v-for="(op, i) in cls.tagList" :key="i" :label="op.id">{{ op.name }}</el-checkbox> | ||||||
|  |           </div> | ||||||
|  |         </el-checkbox-group> | ||||||
|  |         <ai-empty v-if="!tagOps.length"/> | ||||||
|  |       </ai-dialog> | ||||||
|  |     </ai-dialog> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "SelectDeptUser", | ||||||
|  |   model: { | ||||||
|  |     event: "change", | ||||||
|  |     prop: "value" | ||||||
|  |   }, | ||||||
|  |   props: { | ||||||
|  |     value: {default: ""}, | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     source: {default: 1} | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     selectText: v => v.value?.length > 0 ? "已选择" : "请选择", | ||||||
|  |     tagAction: v => v.source == 2 ? '/app/wxcp/wxgroupchattag/listAllByCorp' : '/app/wxcp/wxcorptag/listAllByCorp' | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       dialog: false, | ||||||
|  |       dialogTag: false, | ||||||
|  |       currentCorp: {}, | ||||||
|  |       selected: [], | ||||||
|  |       selectDeptPath: [], | ||||||
|  |       selectedTags: [], | ||||||
|  |       options: [], | ||||||
|  |       tagOps: [], | ||||||
|  |       allData: [], | ||||||
|  |       tags: {} | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getDepts() { | ||||||
|  |       this.instance.post('/app/wxcp/wxdepartment/listAllByCorp').then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           let parents = res.data.map(e => e.parentid) | ||||||
|  |           this.allData = res.data.map(e => ({ | ||||||
|  |             ...e, | ||||||
|  |             hasChildren: parents.includes(e.id), | ||||||
|  |             uid: [e.corpId, e.id].join("_"), | ||||||
|  |             kind: 'dept', | ||||||
|  |             checked: false | ||||||
|  |           })) | ||||||
|  |           this.deptInit() | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     getTagsByCorp(dvcpCorpId) { | ||||||
|  |       return this.instance.post(this.tagAction, null, { | ||||||
|  |         params: { | ||||||
|  |           dvcpCorpId, | ||||||
|  |           size: 9999 | ||||||
|  |         } | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           return this.tagOps = res.data.records || [] | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     deptInit() { | ||||||
|  |       this.options = this.allData.filter(e => !e.parentid) | ||||||
|  |       this.selectDeptPath = [{name: "可选范围", id: ''}] | ||||||
|  |     }, | ||||||
|  |     itemClick(row) { | ||||||
|  |       let index = this.selectDeptPath.findIndex(e => e.id == row.id) | ||||||
|  |       if (index == -1) { | ||||||
|  |         this.selectDeptPath.push(row) | ||||||
|  |         this.getDeptsAndUsersByParent(row) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     getDeptsAndUsersByParent(row) { | ||||||
|  |       let {id: departmentId, corpId: cid} = row | ||||||
|  |       this.options = this.allData.filter(e => e.parentid == departmentId && e.corpId == cid) || [] | ||||||
|  |       this.instance.post(`/app/wxcp/wxuser/listByDeptId`, null, { | ||||||
|  |         params: {departmentId, status: 1, cid} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           res.data = res.data.map(e => ({ | ||||||
|  |             ...e, kind: "user", checked: this.selected.some(s => { | ||||||
|  |               if (e.id == s.id) return true | ||||||
|  |             }) | ||||||
|  |           })) | ||||||
|  |           this.options = [this.options, res.data].flat() | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     deptNameClick(row, index) { | ||||||
|  |       if (!index) { //第一级别 | ||||||
|  |         this.deptInit() | ||||||
|  |       } else { | ||||||
|  |         let length = this.selectDeptPath.length - index | ||||||
|  |         this.selectDeptPath.splice(index + 1, length) | ||||||
|  |         this.getDeptsAndUsersByParent(row.id) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     openDialogTag(row) { | ||||||
|  |       this.getTagsByCorp(row.corpId).then(() => { | ||||||
|  |         this.currentCorp = row | ||||||
|  |         this.dialogTag = true | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     handleSelectTag() { | ||||||
|  |       let {corpId} = this.currentCorp | ||||||
|  |       this.currentCorp.selectedTags = this.$copy(this.tagOps.map(e => e.tagList).flat().filter(e => this.selectedTags.includes(e.id))) | ||||||
|  |       this.tags[corpId] = this.$copy(this.currentCorp.selectedTags) | ||||||
|  |       this.dialogTag = false | ||||||
|  |     }, | ||||||
|  |     handleSubmit() { | ||||||
|  |       let result = {} | ||||||
|  |       this.selected?.map(e => { | ||||||
|  |         let {kind, id} = e | ||||||
|  |         result[e.corpId] = [result[e.corpId], {kind, id}].flat() | ||||||
|  |       }) | ||||||
|  |       let selected = Object.keys(result).map(corpId => { | ||||||
|  |         let res | ||||||
|  |         if (result[corpId]) { | ||||||
|  |           res = { | ||||||
|  |             corpId, | ||||||
|  |             objList: result[corpId].filter(e => !!e) | ||||||
|  |           } | ||||||
|  |           if (this.tags[corpId]?.length > 0) { | ||||||
|  |             res.tagId = this.tags[corpId]?.map(e => e.id) | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         return res | ||||||
|  |       }).filter(e => !!e) | ||||||
|  |       this.$emit("change", selected) | ||||||
|  |       this.dialog = false | ||||||
|  |     }, | ||||||
|  |     isSelected(uid) { | ||||||
|  |       return !!this.selected.find(e => e.uid == uid) | ||||||
|  |     }, | ||||||
|  |     handleCheck(row, i) { | ||||||
|  |       if (row.checked) { | ||||||
|  |         this.selected.push(row) | ||||||
|  |       } else { | ||||||
|  |         this.selected.splice(i, 1) | ||||||
|  |       } | ||||||
|  |       this.$forceUpdate() | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getDepts() | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .SelectDeptUser { | ||||||
|  |   ::v-deep.optionsItem { | ||||||
|  |     border: 1px solid #eee; | ||||||
|  |     margin-bottom: 8px; | ||||||
|  |     padding: 8px; | ||||||
|  |     border-radius: 4px; | ||||||
|  |  | ||||||
|  |     .mar-4 { | ||||||
|  |       margin-right: 4px; | ||||||
|  |       margin-bottom: 4px; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -1,157 +0,0 @@ | |||||||
| <template> |  | ||||||
|   <section class="AppDVDemo"> |  | ||||||
|     <ai-list> |  | ||||||
|       <ai-title slot="title" title="数据大屏草稿板" isShowBottomBorder/> |  | ||||||
|       <template #content> |  | ||||||
|         <div class="showPanel"> |  | ||||||
|           <ai-dv-wrapper :views="views" v-model="active"> |  | ||||||
|             <ai-echart :ops="ops" :data="views" theme="1"></ai-echart> |  | ||||||
|           </ai-dv-wrapper> |  | ||||||
|         </div> |  | ||||||
|       </template> |  | ||||||
|     </ai-list> |  | ||||||
|   </section> |  | ||||||
| </template> |  | ||||||
|  |  | ||||||
| <script> |  | ||||||
|  |  | ||||||
| import AiDvWrapper from "./layout/AiDvWrapper/AiDvWrapper"; |  | ||||||
| import ops from './components/AiEchart/template/pie/pieChart3' |  | ||||||
| import AiDvPanel from "./layout/AiDvPanel/AiDvPanel"; |  | ||||||
| import AiDvDisplay from "./layout/AiDvDisplay/AiDvDisplay"; |  | ||||||
| import AiDvSummary from "./layout/AiDvSummary/AiDvSummary"; |  | ||||||
| import AiMonitor from "./components/AiMonitor/AiMonitor"; |  | ||||||
|  |  | ||||||
| export default { |  | ||||||
|   name: "AppDVDemo", |  | ||||||
|   label: "数据大屏草稿板", |  | ||||||
|   components: {AiMonitor, AiDvPanel, AiDvWrapper, AiDvDisplay, AiDvSummary}, |  | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       ops, |  | ||||||
|       active: '', |  | ||||||
|       views: [ |  | ||||||
|         { |  | ||||||
|           "name": "阿斯达", |  | ||||||
|           "v1": 23, |  | ||||||
|           "v2": 33 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "name": "水电费", |  | ||||||
|           "v1": 12, |  | ||||||
|           "v2": 34 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "name": "凡哥", |  | ||||||
|           "v1": 67, |  | ||||||
|           "v2": 25 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "name": "党费", |  | ||||||
|           "v1": 98, |  | ||||||
|           "v2": 85 |  | ||||||
|         } |  | ||||||
|       ], |  | ||||||
|       list: [ |  | ||||||
|         {name: '阿斯达', v1: 23, v2: 33}, |  | ||||||
|         {name: '水电费', v1: 12, v2: 34}, |  | ||||||
|         {name: '凡哥', v1: 67, v2: 25}, |  | ||||||
|         {name: '党费', v1: 98, v2: 85}, |  | ||||||
|         {name: '阿萨德', v1: 98, v2: 85}, |  | ||||||
|         {name: '电饭锅', v1: 98, v2: 85}, |  | ||||||
|         {name: '户籍科', v1: 98, v2: 85}, |  | ||||||
|       ], |  | ||||||
|       data: [ |  | ||||||
|         { |  | ||||||
|           "key": "阿斯达", |  | ||||||
|           "value": '22', |  | ||||||
|           "percentage": 33, |  | ||||||
|           text: '同比上月' |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "key": "阿斯达", |  | ||||||
|           "value": '22', |  | ||||||
|           "percentage": -33, |  | ||||||
|           text: '同比上月' |  | ||||||
|         } |  | ||||||
|       ], |  | ||||||
|       value: [ |  | ||||||
|         { |  | ||||||
|           "key": "宅基地 ", |  | ||||||
|           "value": 1252292, |  | ||||||
|           "value1": 12592, |  | ||||||
|           "value2": 12592, |  | ||||||
|           "value3": 12592, |  | ||||||
|           "value4": 12592 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "key": "人数", |  | ||||||
|           "value": 12592, |  | ||||||
|           "value1": 12592, |  | ||||||
|           "value2": 12592, |  | ||||||
|           "value3": 12592, |  | ||||||
|           "value4": 12592 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "key": "户数 ", |  | ||||||
|           "value": 12592, |  | ||||||
|           "value1": 12592, |  | ||||||
|           "value2": 12592, |  | ||||||
|           "value3": 12592, |  | ||||||
|           "value4": 12592 |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "key": "村社区", |  | ||||||
|           "value": 12592, |  | ||||||
|           "value1": 12592, |  | ||||||
|           "value2": 12592, |  | ||||||
|           "value3": 12592, |  | ||||||
|           "value4": 12592 |  | ||||||
|         } |  | ||||||
|       ], |  | ||||||
|       markers: [] |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getMarkers() { |  | ||||||
|       this.$request.post('/app/appcommunitybuildinginfo/listByBuildingAndHomestead', null, { |  | ||||||
|         params: {current: 1, size: 1000000}, |  | ||||||
|         withoutToken: true |  | ||||||
|       }).then(res => { |  | ||||||
|         if (res?.data) { |  | ||||||
|           this.markers = res.data.map(e => ({ |  | ||||||
|             ...e, |  | ||||||
|             icon: "https://cdn.cunwuyun.cn/dvcp/dv/monitor.svg", |  | ||||||
|             label: e.communityName |  | ||||||
|           })) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     // this.getMarkers() |  | ||||||
|     setTimeout(() => { |  | ||||||
|       this.list = this.list.map(e => ({name: e.name, '电费': e.v1, '水费': e.v2 * 2})) |  | ||||||
|     }, 2000) |  | ||||||
|   }, |  | ||||||
|   mounted() { |  | ||||||
|     this.$initWxOpenData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> |  | ||||||
|  |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| @import "./lib/animation"; |  | ||||||
|  |  | ||||||
| .AppDVDemo { |  | ||||||
|   height: 100%; |  | ||||||
|  |  | ||||||
|   .showPanel { |  | ||||||
|     height: 600px; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .AiDvPanel { |  | ||||||
|     width: 600px; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
							
								
								
									
										88
									
								
								project/dvui/components/AiDataPanel.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								project/dvui/components/AiDataPanel.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AiDataPanel"> | ||||||
|  |     <b class="item-title" v-text="label"/> | ||||||
|  |     <div class="num-bg"> | ||||||
|  |       <span ref="num" class="num" v-text="num"/> | ||||||
|  |     </div> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import {gsap} from 'gsap' | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "AiDataPanel", | ||||||
|  |   props: { | ||||||
|  |     label: {default: "标题"}, | ||||||
|  |     value: {default: 0} | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       num: 0 | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     animation() { | ||||||
|  |       let demo = {num: Math.max(this.value - 30, 0)} | ||||||
|  |       gsap.to(demo, 1, { | ||||||
|  |         num: this.value, onUpdate: () => { | ||||||
|  |           this.num = demo.num?.toFixed(0) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   mounted() { | ||||||
|  |     this.animation() | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AiDataPanel { | ||||||
|  |   flex: 1; | ||||||
|  |   width: 172px; | ||||||
|  |   height: 160px; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   align-items: center; | ||||||
|  |   background: #000; | ||||||
|  |  | ||||||
|  |   & + .AiDataPanel { | ||||||
|  |     margin-left: 16px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .item-title { | ||||||
|  |     font-size: 24px; | ||||||
|  |     line-height: 32px; | ||||||
|  |     background-image: -webkit-linear-gradient(bottom, #35BEFF, #EBF9FF, #FFFFFF); | ||||||
|  |     -webkit-background-clip: text; | ||||||
|  |     -webkit-text-fill-color: transparent; | ||||||
|  |     margin-top: 30px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .num-bg { | ||||||
|  |     width: 100%; | ||||||
|  |     height: 160px; | ||||||
|  |     background-image: url(https://cdn.cunwuyun.cn/dvcp/dv/dianjiang/number-bg.png); | ||||||
|  |     background-size: 100% 100%; | ||||||
|  |     position: relative; | ||||||
|  |     margin-top: -76px; | ||||||
|  |  | ||||||
|  |     .num { | ||||||
|  |       position: absolute; | ||||||
|  |       left: 0; | ||||||
|  |       bottom: 30px; | ||||||
|  |       width: 100%; | ||||||
|  |       text-align: center; | ||||||
|  |       height: 50px; | ||||||
|  |       font-size: 40px; | ||||||
|  |       font-family: D-DIN-Bold, D-DIN; | ||||||
|  |       font-weight: bold; | ||||||
|  |       line-height: 54px; | ||||||
|  |       background-image: -webkit-linear-gradient(bottom, #35BEFF, #EBF9FF, #FFFFFF); | ||||||
|  |       -webkit-background-clip: text; | ||||||
|  |       -webkit-text-fill-color: transparent; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										357
									
								
								project/dvui/components/AiDvRender.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										357
									
								
								project/dvui/components/AiDvRender.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,357 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="AiDvRender" style="width: 100%; height: 100%;"> | ||||||
|  |     <ai-dv-display v-if="data.type === 'display'" :title="data.title" :list="values"></ai-dv-display> | ||||||
|  |     <ai-dv-panel | ||||||
|  |         style="height: 100%; width: 100%;" | ||||||
|  |         v-if="data.type !== 'display'" | ||||||
|  |         :title="data.title" | ||||||
|  |         :border="data.border || ''"> | ||||||
|  |       <AiDvSummary v-if="data.type === 'summary'" :summaryTitle="data.summaryTitle" :key="`summary${index}`" :type="data.display" :data="values"/> | ||||||
|  |       <AiSwiper v-else-if="data.type === 'swiper'" :heigth="'100%'" :data="values"/> | ||||||
|  |       <dv-scroll-board | ||||||
|  |           v-if="data.type === 'table'" | ||||||
|  |           :class="'dvScrollBoard' + theme" | ||||||
|  |           :config="formatTable(values, data.isShowIndex, data.rowNum)" | ||||||
|  |           :key="data.height" | ||||||
|  |           :theme="theme" | ||||||
|  |           :style="{height: data.height + 'px', width: '100%'}"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'barChart1'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="data.config"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'barChart2'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :theme="theme" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="data.config"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'barChart3'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="data.config"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'barChart5'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="data.config"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'barChart7'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="data.config"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'barChart8'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="data.config"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'barChart9'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="data.config"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'lineChart1'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="lineChart1"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'lineChart2'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="lineChart2"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'lineChart3'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="data.config"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'lineChart4'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="data.config"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'lineChart5'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="lineChart5"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'pieChart'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="pieChart"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'pieChart1'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="pieChart1"/> | ||||||
|  |       <ai-echart | ||||||
|  |           v-else-if="data.type === 'pieChart3'" | ||||||
|  |           style="height: 100%; width: 100%;" | ||||||
|  |           :ref="'chart' + index" | ||||||
|  |           :key="`chart${index}`" | ||||||
|  |           :theme="theme" | ||||||
|  |           :data="values" | ||||||
|  |           :ops="pieChart3"/> | ||||||
|  |       <ai-map :markers="values" v-else-if="data.type=='map'" :mask="data.mask === '1'" :areaId="data.areaId || user.info.areaId" | ||||||
|  |               :map-style="`amap://styles/${data.mapStyle}`" :pulseLines="data.pulseLines==1" :map.sync="map" :lib.sync="lib"/> | ||||||
|  |       <ai-monitor :src="data.src" v-else-if="data.type === 'monitor'" :type="data.monitorType"/> | ||||||
|  |       <video style="width: 100%; height: 100%; object-fit: fill;" loop :src="data.src" autoplay v-else-if="data.type === 'video'"/> | ||||||
|  |       <AiDvPartyOrg style="width: 100%; height: 100%;" v-else-if="data.type === 'partyOrg'" :instance="instance"/> | ||||||
|  |     </ai-dv-panel> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import {mapState} from 'vuex' | ||||||
|  | import AiSwiper from './AiSwiper.vue' | ||||||
|  | import pieChart from './AiEchart/template/pie/pieChart2' | ||||||
|  | import pieChart1 from './AiEchart/template/pie/pieChart1' | ||||||
|  | import pieChart3 from './AiEchart/template/pie/pieChart3' | ||||||
|  | import lineChart1 from './AiEchart/template/line/lineChart1' | ||||||
|  | import lineChart2 from './AiEchart/template/line/lineChart2' | ||||||
|  | import lineChart5 from './AiEchart/template/line/lineChart5' | ||||||
|  | import AiMonitor from "./AiMonitor/AiMonitor"; | ||||||
|  | import AiDvPanel from "../layout/AiDvPanel/AiDvPanel"; | ||||||
|  | import AiDvDisplay from "../layout/AiDvDisplay/AiDvDisplay"; | ||||||
|  | import AiDvSummary from "../layout/AiDvSummary/AiDvSummary"; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: 'AiDvRender', | ||||||
|  |   props: ['data', 'index', 'theme', 'instance'], | ||||||
|  |   components: { | ||||||
|  |     AiDvSummary, | ||||||
|  |     AiDvDisplay, | ||||||
|  |     AiDvPanel, | ||||||
|  |     AiMonitor, | ||||||
|  |     AiSwiper | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       lineChart1, | ||||||
|  |       lineChart2, | ||||||
|  |       lineChart5, | ||||||
|  |       pieChart, | ||||||
|  |       pieChart1, | ||||||
|  |       pieChart3, | ||||||
|  |       map: null, | ||||||
|  |       lib: null | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   computed: { | ||||||
|  |     ...mapState(['user']), | ||||||
|  |  | ||||||
|  |     values() { | ||||||
|  |       if (!this.data) { | ||||||
|  |         return [] | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       return this.data.type === 'map' ? this.data[this.data.dataType].map(e => { | ||||||
|  |         return {...e, lng: e['经度'], lat: e['纬度'], label: e['地区名称']} | ||||||
|  |       }) : this.data[this.data.dataType] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     formatTable(data, isShowIndex, rowNum) { | ||||||
|  |       if (!data.length) { | ||||||
|  |         return { | ||||||
|  |           header: [], | ||||||
|  |           data: [] | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       let rows = [] | ||||||
|  |       const header = data.map(v => { | ||||||
|  |         return v[Object.keys(v)[0]] | ||||||
|  |       }) | ||||||
|  |       Object.keys(data[0]).forEach((item, index) => { | ||||||
|  |         if (index !== 0) { | ||||||
|  |           rows.push(item) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |       return { | ||||||
|  |         header: header, | ||||||
|  |         data: rows.map(item => { | ||||||
|  |           return data.map(v => { | ||||||
|  |             return v[item] | ||||||
|  |           }) | ||||||
|  |         }), | ||||||
|  |         headerBGC: 'transparent', | ||||||
|  |         evenRowBGC: 'transparent', | ||||||
|  |         oddRowBGC: 'rgba(0, 133, 255, 0.2)', | ||||||
|  |         headerHeight: 42, | ||||||
|  |         rowNum: rowNum || 7, | ||||||
|  |         index: isShowIndex === '1', | ||||||
|  |         waitTime: 8000, | ||||||
|  |         carousel: 'page', | ||||||
|  |         indexHeader: '排名', | ||||||
|  |         align: ['center', 'center', 'center', 'center', 'center'] | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     handleMapClick(count = 0) { | ||||||
|  |       let {lib: AMap, map} = this | ||||||
|  |       if (AMap) { | ||||||
|  |         let infoWin = new AMap.InfoWindow({content: ""}) | ||||||
|  |         map.clearMap() | ||||||
|  |         let markers = this.values.filter(e => e.lng).map(e => { | ||||||
|  |           return new AMap.Marker({ | ||||||
|  |             map, | ||||||
|  |             label: e.label, | ||||||
|  |             icon: e.icon, | ||||||
|  |             position: [e.lng, e.lat] | ||||||
|  |           }).on('click', ({target}) => { | ||||||
|  |             map.clearInfoWindow() | ||||||
|  |             markers?.map(m => m.getIcon() == e.selectedIcon && m.setIcon(e.icon)) | ||||||
|  |             target.setIcon(e.selectedIcon) | ||||||
|  |             infoWin.setContent([ | ||||||
|  |               `<div class="infoWin">`, | ||||||
|  |               `<b>${e.label}</b>`, | ||||||
|  |               `<div>累计成交金额:${e['累计成交金额(万)']}万元</div>`, | ||||||
|  |               `<div>金融产品:${e['金融产品(万)']}万元</div>`, | ||||||
|  |               `<div>融资需求:${e['融资需求(万)']}万元</div>`, | ||||||
|  |               '</div>' | ||||||
|  |             ].join('')) | ||||||
|  |             infoWin.open(map, [e.lng, e.lat]) | ||||||
|  |           }) | ||||||
|  |         }) | ||||||
|  |         map.setFitView(markers) | ||||||
|  |       } else if (count < 10) { | ||||||
|  |         console.log("正在加载...%s", count) | ||||||
|  |         setTimeout(() => this.handleMapClick(++count), 1000) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   mounted() { | ||||||
|  |     if (this.data.type == 'map') { | ||||||
|  |       this.handleMapClick() | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AiDvRender { | ||||||
|  |   ::v-deep .dvScrollBoard1 { | ||||||
|  |  | ||||||
|  |     .header { | ||||||
|  |       background: rgba(0, 0, 0, 0.1) !important; | ||||||
|  |  | ||||||
|  |       .header-item { | ||||||
|  |         color: #FFBB73 !important; | ||||||
|  |         font-size: 16px !important; | ||||||
|  |         font-weight: 600; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     .rows { | ||||||
|  |       font-size: 16px; | ||||||
|  |       font-weight: 600; | ||||||
|  |       color: #FFFFFF; | ||||||
|  |       line-height: 21px; | ||||||
|  |       text-shadow: 0px 2px 4px rgba(117, 9, 9, 0.5); | ||||||
|  |       background: linear-gradient(180deg, #FFF6C7 0%, #FF9A02 100%); | ||||||
|  |       -webkit-background-clip: text; | ||||||
|  |       -webkit-text-fill-color: transparent; | ||||||
|  |  | ||||||
|  |       & > div:nth-of-type(2n - 1) { | ||||||
|  |         background-color: transparent !important; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       & > div:nth-of-type(2n) { | ||||||
|  |         background-color: rgba(0, 0, 0, 0.1) !important; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .index { | ||||||
|  |         color: #fff; | ||||||
|  |         text-shadow: none; | ||||||
|  |         background: #BD4921 !important; | ||||||
|  |         -webkit-background-clip: inherit; | ||||||
|  |         -webkit-text-fill-color: #fff; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ::v-deep.amap-info-contentContainer { | ||||||
|  |     .amap-info-content { | ||||||
|  |       background: #0A3257; | ||||||
|  |       border: 1px solid #7BE5FF; | ||||||
|  |       padding: 16px; | ||||||
|  |       font-family: PingFangSC-Semibold, PingFang SC; | ||||||
|  |  | ||||||
|  |       .infoWin { | ||||||
|  |         & > b { | ||||||
|  |           display: block; | ||||||
|  |           font-size: 18px; | ||||||
|  |           font-weight: 600; | ||||||
|  |           color: #FFFFFF; | ||||||
|  |           margin-bottom: 13px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         & > div { | ||||||
|  |           font-size: 16px; | ||||||
|  |           font-weight: 400; | ||||||
|  |           color: #7BE5FF; | ||||||
|  |  | ||||||
|  |           & + div { | ||||||
|  |             margin-top: 8px; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .amap-info-sharp { | ||||||
|  |       border-top-color: #0A3257; | ||||||
|  |  | ||||||
|  |       &:after { | ||||||
|  |         border-top-color: #7BE5FF; | ||||||
|  |         filter: none; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										30
									
								
								project/dvui/components/AiStaData.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								project/dvui/components/AiStaData.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AiStaData"> | ||||||
|  |     <ai-data-panel v-for="op in data" :key="op[key]" | ||||||
|  |                    :label="op[label]" :value="op[key]"/> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import AiDataPanel from "./AiDataPanel"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "AiStaData", | ||||||
|  |   components: {AiDataPanel}, | ||||||
|  |   props: { | ||||||
|  |     data: {default: () => []}, | ||||||
|  |     key: {default: "id"}, | ||||||
|  |     label: {default: "label"}, | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AiStaData { | ||||||
|  |   width: 100%; | ||||||
|  |   display: flex; | ||||||
|  |   align-items: center; | ||||||
|  |   flex-wrap: wrap; | ||||||
|  |   justify-content: center; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										92
									
								
								project/dvui/components/AiSwiper.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								project/dvui/components/AiSwiper.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="swiper"> | ||||||
|  |     <el-carousel height="100%" indicator-position="none"> | ||||||
|  |       <el-carousel-item v-for="(item, index) in data" :key="index"> | ||||||
|  |         <img :src="item.img"> | ||||||
|  |         <div class="swiper-content" v-if="item.title"> | ||||||
|  |           <h2>{{ item.title }}</h2> | ||||||
|  |           <p>{{ item.content }}</p> | ||||||
|  |         </div> | ||||||
|  |       </el-carousel-item> | ||||||
|  |     </el-carousel> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |   export default { | ||||||
|  |     name: 'AiSwiper', | ||||||
|  |  | ||||||
|  |     props: { | ||||||
|  |       data: { | ||||||
|  |         type: Array, | ||||||
|  |         default: () => [] | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       width: { | ||||||
|  |         type: String, | ||||||
|  |         default: '100%' | ||||||
|  |       }, | ||||||
|  |       heigth: { | ||||||
|  |         type: String, | ||||||
|  |         default: '100%' | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     data () { | ||||||
|  |       return { | ||||||
|  |  | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     mounted () { | ||||||
|  |  | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     methods: { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  |   .swiper { | ||||||
|  |     width: 100%; | ||||||
|  |     height: 100%; | ||||||
|  |     padding: 20px 0 0; | ||||||
|  |  | ||||||
|  |     ::v-deep .el-carousel { | ||||||
|  |       height: 100%; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     img { | ||||||
|  |       width: 100%; | ||||||
|  |       height: 100%; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .swiper-content { | ||||||
|  |       position: absolute; | ||||||
|  |       bottom: 0; | ||||||
|  |       left: 0; | ||||||
|  |       z-index: 1; | ||||||
|  |       width: 100%; | ||||||
|  |       padding: 10px; | ||||||
|  |       text-align: center; | ||||||
|  |       background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, #000000 100%); | ||||||
|  |  | ||||||
|  |       h2 { | ||||||
|  |         margin-bottom: 4px; | ||||||
|  |         color: #fff; | ||||||
|  |         text-align: center; | ||||||
|  |         font-size: 18px; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       p { | ||||||
|  |         line-height: 22px; | ||||||
|  |         white-space: pre-line; | ||||||
|  |         color: #B6DFFF; | ||||||
|  |         font-size: 14px; | ||||||
|  |         text-align: center; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </style> | ||||||
							
								
								
									
										62
									
								
								project/oms/apps/develop/AppAiCode/AppAiCode.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								project/oms/apps/develop/AppAiCode/AppAiCode.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AppAiCode"> | ||||||
|  |     <component :is="currentPage" v-bind="$props"/> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import AcList from "./acList"; | ||||||
|  | import AcAdd from "./acAdd"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "AppAiCode", | ||||||
|  |   components: {AcAdd, AcList}, | ||||||
|  |   label: "低代码生成平台", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     permissions: Function | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     currentPage() { | ||||||
|  |       let {hash} = this.$route | ||||||
|  |       return hash == "#add" ? AcAdd : AcList | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   provide() { | ||||||
|  |     return { | ||||||
|  |       top: this | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     handleGetCode(id) { | ||||||
|  |       id && this.instance.post("/node/aicode/getCode", null, { | ||||||
|  |         params: {id}, | ||||||
|  |         responseType: "blob" | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.code == 1) { | ||||||
|  |           this.$message.error(res.err) | ||||||
|  |         } else { | ||||||
|  |           const link = document.createElement('a') | ||||||
|  |           let blob = new Blob([res], {type: 'application/zip'}) | ||||||
|  |           link.style.display = 'none' | ||||||
|  |           link.href = URL.createObjectURL(blob) | ||||||
|  |           link.setAttribute('download', 'aicode.zip') | ||||||
|  |           document.body.appendChild(link) | ||||||
|  |           link.click() | ||||||
|  |           document.body.removeChild(link) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.dict.load("detailType") | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AppAiCode { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										185
									
								
								project/oms/apps/develop/AppAiCode/acAdd.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								project/oms/apps/develop/AppAiCode/acAdd.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,185 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="acAdd"> | ||||||
|  |     <ai-detail list> | ||||||
|  |       <ai-title slot="title" :title="pageTitle"> | ||||||
|  |         <template #rightBtn> | ||||||
|  |           <el-button type="primary" v-if="isEdit" @click="top.handleGetCode($route.query.id)">生成代码</el-button> | ||||||
|  |         </template> | ||||||
|  |       </ai-title> | ||||||
|  |       <template #content> | ||||||
|  |         <el-form ref="AcForm" :model="form" size="small" label-width="120px" :rules="rules"> | ||||||
|  |           <el-tabs tab-position="left" @tab-click="handleSyncProps"> | ||||||
|  |             <el-tab-pane label="基本信息" lazy> | ||||||
|  |               <ai-card title="基本信息"> | ||||||
|  |                 <template #content> | ||||||
|  |                   <el-row type="flex"> | ||||||
|  |                     <div class="fill"> | ||||||
|  |                       <el-form-item label="应用名称" prop="name"> | ||||||
|  |                         <el-input v-model="form.name" clearable placeholder="请输入"/> | ||||||
|  |                       </el-form-item> | ||||||
|  |                       <el-form-item label="应用模块" prop="appName"> | ||||||
|  |                         <el-input v-model="form.appName" clearable placeholder="请输入"/> | ||||||
|  |                       </el-form-item> | ||||||
|  |                     </div> | ||||||
|  |                     <div class="fill"> | ||||||
|  |                       <el-form-item label="核心码" prop="rightCode"> | ||||||
|  |                         <el-input v-model="form.rightCode" clearable placeholder="请输入"/> | ||||||
|  |                       </el-form-item> | ||||||
|  |                       <el-form-item label="详情方式" prop="detailType"> | ||||||
|  |                         <ai-select v-model="form.detailType" :selectList="dict.getDict('detailType')"/> | ||||||
|  |                       </el-form-item> | ||||||
|  |                     </div> | ||||||
|  |                   </el-row> | ||||||
|  |                   <el-form-item label="按钮配置" prop="btns"> | ||||||
|  |                     <el-checkbox-group v-model="form.btns"> | ||||||
|  |                       <el-checkbox label="insertEnable">添加</el-checkbox> | ||||||
|  |                       <el-checkbox label="importEnable">导入</el-checkbox> | ||||||
|  |                       <el-checkbox label="exportEnalbe">导出</el-checkbox> | ||||||
|  |                       <el-checkbox label="editEnable">编辑</el-checkbox> | ||||||
|  |                       <el-checkbox label="deleteEnable">删除</el-checkbox> | ||||||
|  |                       <el-checkbox label="batchDelEnable">批量删除</el-checkbox> | ||||||
|  |                     </el-checkbox-group> | ||||||
|  |                   </el-form-item> | ||||||
|  |                 </template> | ||||||
|  |               </ai-card> | ||||||
|  |               <ai-card title="字段设置"> | ||||||
|  |                 <template #right> | ||||||
|  |                   <el-button type="text" @click="handleAddProps">批量添加</el-button> | ||||||
|  |                   <el-button type="text" @click="form.props.push({})">添加</el-button> | ||||||
|  |                 </template> | ||||||
|  |                 <template #content> | ||||||
|  |                   <ai-table :tableData="form.props" :isShowPagination="false" :colConfigs="colConfigs"> | ||||||
|  |                     <el-table-column v-for="col in colConfigs" :key="col.slot" v-bind="col"> | ||||||
|  |                       <template slot-scope="{row}"> | ||||||
|  |                         <el-checkbox v-if="col.type=='checkBox'" v-model="row[col.slot]"/> | ||||||
|  |                         <span v-else-if="col.type=='chbShow'" v-text="row[col.slot]==true?'✔':''"/> | ||||||
|  |                         <el-input v-else size="small" v-model="row[col.slot]" placeholder="请输入" clearable/> | ||||||
|  |                       </template> | ||||||
|  |                     </el-table-column> | ||||||
|  |                     <el-table-column label="操作" slot="options" align="center"> | ||||||
|  |                       <template slot-scope="{row,$index}"> | ||||||
|  |                         <el-button type="text" @click="form.props.splice($index,1)">删除</el-button> | ||||||
|  |                       </template> | ||||||
|  |                     </el-table-column> | ||||||
|  |                   </ai-table> | ||||||
|  |                 </template> | ||||||
|  |               </ai-card> | ||||||
|  |             </el-tab-pane> | ||||||
|  |             <el-tab-pane label="详情设计" lazy> | ||||||
|  |               <detail-layout v-bind="$props" :form="form" v-model="form.detailConfig"/> | ||||||
|  |             </el-tab-pane> | ||||||
|  |           </el-tabs> | ||||||
|  |         </el-form> | ||||||
|  |       </template> | ||||||
|  |       <template #footer> | ||||||
|  |         <el-button @click="back">取消</el-button> | ||||||
|  |         <el-button type="primary" @click="submit">提交</el-button> | ||||||
|  |       </template> | ||||||
|  |     </ai-detail> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import DetailLayout from "./detailLayout"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "acAdd", | ||||||
|  |   components: {DetailLayout}, | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     permissions: Function | ||||||
|  |   }, | ||||||
|  |   inject: { | ||||||
|  |     top: {} | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     isEdit: v => !!v.$route.query.id, | ||||||
|  |     pageTitle: v => v.isEdit ? "编辑应用" : "新增应用" | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       form: {props: [], btns: []}, | ||||||
|  |       rules: { | ||||||
|  |         name: {required: true, message: "请输入应用名称"}, | ||||||
|  |         appName: {required: true, message: "请输入应用模块"}, | ||||||
|  |         btns: {required: true, message: '请输入按钮配置', trigger: 'change'} | ||||||
|  |       }, | ||||||
|  |       colConfigs: [ | ||||||
|  |         {slot: 'prop', label: "字段"}, | ||||||
|  |         {slot: 'label', label: "名称"}, | ||||||
|  |         {slot: 'dict', label: "字典"}, | ||||||
|  |         {slot: 'isSearch', label: "搜索字段", align: 'center', type: 'checkBox'}, | ||||||
|  |         {slot: 'isTable', label: "表格字段", align: 'center', type: 'checkBox'}, | ||||||
|  |         {slot: 'isDetail', label: "详情字段", align: 'center', type: 'chbShow'}, | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getDetail() { | ||||||
|  |       let {id} = this.$route.query | ||||||
|  |       id && this.instance.post("/node/aicode/detail", null, { | ||||||
|  |         params: {id} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.form = res.data | ||||||
|  |           this.handleSyncProps() | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     back() { | ||||||
|  |       this.$router.push({}) | ||||||
|  |     }, | ||||||
|  |     submit() { | ||||||
|  |       this.$refs.AcForm.validate(v => { | ||||||
|  |         if (v) { | ||||||
|  |           this.instance.post("/node/aicode/addOrUpdate", this.form).then(res => { | ||||||
|  |             if (res?.code == 0) { | ||||||
|  |               this.$message.success("提交成功!") | ||||||
|  |               this.back() | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     handleSyncProps() { | ||||||
|  |       let detailPorps = this.form.detailConfig?.map(e => e.column)?.flat()?.map(e => e.prop) | ||||||
|  |       this.form.props = this.form.props.map(e => ({...e, isDetail: !!detailPorps?.includes(e.prop)})) | ||||||
|  |     }, | ||||||
|  |     handleAddProps() { | ||||||
|  |       this.$prompt("请输入swagger示例JSON字符串", { | ||||||
|  |         type: 'warning', | ||||||
|  |         title: "批量添加字段", | ||||||
|  |         dangerouslyUseHTMLString: true, | ||||||
|  |         center: true, | ||||||
|  |       }).then(({value}) => { | ||||||
|  |         if (this.$checkJson(value)) { | ||||||
|  |           Object.keys(JSON.parse(value)).map(prop => { | ||||||
|  |             this.form.props.push({prop}) | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }).catch(() => 0) | ||||||
|  |     }, | ||||||
|  |     $checkJson(str) { | ||||||
|  |       if (typeof str == 'string') { | ||||||
|  |         try { | ||||||
|  |           let obj = JSON.parse(str); | ||||||
|  |           return !!(typeof obj == 'object' && obj); | ||||||
|  |         } catch (e) { | ||||||
|  |           return false; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       return false; | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getDetail() | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .acAdd { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										90
									
								
								project/oms/apps/develop/AppAiCode/acList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								project/oms/apps/develop/AppAiCode/acList.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="acList"> | ||||||
|  |     <ai-list> | ||||||
|  |       <ai-title slot="title" title="低代码生成平台" isShowBottomBorder/> | ||||||
|  |       <template #content> | ||||||
|  |         <ai-search-bar> | ||||||
|  |           <template #left> | ||||||
|  |             <el-button type="primary" icon="iconfont iconAdd" @click="handleAdd()">添加</el-button> | ||||||
|  |           </template> | ||||||
|  |           <template #right> | ||||||
|  |             <el-input size="small" placeholder="搜索应用" v-model="search.name" clearable | ||||||
|  |                       @change="page.current=1,getTableData()"/> | ||||||
|  |           </template> | ||||||
|  |         </ai-search-bar> | ||||||
|  |         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" | ||||||
|  |                   @getList="getTableData" :col-configs="colConfigs" :dict="dict"> | ||||||
|  |           <el-table-column slot="options" label="操作" fixed="right" align="center" width="300"> | ||||||
|  |             <template slot-scope="{row}"> | ||||||
|  |               <el-button type="text" @click="handleAdd(row.id)">编辑</el-button> | ||||||
|  |               <el-button type="text" @click="handleDelete(row.id)">删除</el-button> | ||||||
|  |               <el-button type="text" @click="top.handleGetCode(row.id)">下载</el-button> | ||||||
|  |             </template> | ||||||
|  |           </el-table-column> | ||||||
|  |         </ai-table> | ||||||
|  |       </template> | ||||||
|  |     </ai-list> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "acList", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     permissions: Function | ||||||
|  |   }, | ||||||
|  |   inject: { | ||||||
|  |     top: {} | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       search: {name: ""}, | ||||||
|  |       page: {current: 1, size: 10, total: 0}, | ||||||
|  |       tableData: [], | ||||||
|  |       colConfigs: [ | ||||||
|  |         {label: "应用名称", prop: "name", width: 200}, | ||||||
|  |         {label: "应用模块", prop: "appName"}, | ||||||
|  |         {label: "权限码", prop: "rightCode"}, | ||||||
|  |         {label: "详情展示方式", prop: "detailType", dict: "detailType"}, | ||||||
|  |       ], | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getTableData() { | ||||||
|  |       this.instance.post("/node/aicode/list", null, { | ||||||
|  |         params: {...this.page, ...this.search} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.tableData = res.data.records | ||||||
|  |           this.page.total = res.data.total | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     handleAdd(id) { | ||||||
|  |       this.$router.push({hash: "#add", query: {id}}) | ||||||
|  |     }, | ||||||
|  |     handleDelete(ids) { | ||||||
|  |       this.$confirm("是否要删除该应用?").then(() => { | ||||||
|  |         this.instance.post("/node/aicode/delete", null, { | ||||||
|  |           params: {ids} | ||||||
|  |         }).then(res => { | ||||||
|  |           if (res?.code == 0) { | ||||||
|  |             this.$message.success("删除成功") | ||||||
|  |             this.getTableData() | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }).catch(() => 0) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getTableData() | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .acList { | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										274
									
								
								project/oms/apps/develop/AppAiCode/config.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								project/oms/apps/develop/AppAiCode/config.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,274 @@ | |||||||
|  | { | ||||||
|  |   "config": [ | ||||||
|  |     { | ||||||
|  |       "type": "info", | ||||||
|  |       "tips": "(不能重复添加同一元素)", | ||||||
|  |       "label": "信息", | ||||||
|  |       "children": [ | ||||||
|  |         { | ||||||
|  |           "type": "name", | ||||||
|  |           "fieldName": "姓名", | ||||||
|  |           "fieldTips": "请输入姓名", | ||||||
|  |           "fixedLabel": "姓名", | ||||||
|  |           "disable": "0", | ||||||
|  |           "grid": 0.5, | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "icon": "icontext_box", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "maxLength": 20 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "idNumber", | ||||||
|  |           "fieldName": "身份证号", | ||||||
|  |           "fixedLabel": "身份证号", | ||||||
|  |           "fieldTips": "请输入身份证号", | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "icon": "icontext_area", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "maxLength": 20, | ||||||
|  |           "disable": "0", | ||||||
|  |           "grid": 0.5 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "phone", | ||||||
|  |           "fieldName": "联系方式", | ||||||
|  |           "fixedLabel": "联系方式", | ||||||
|  |           "fieldTips": "请输入联系方式", | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "icon": "icontext_area", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "maxLength": 20, | ||||||
|  |           "disable": "0", | ||||||
|  |           "grid": 0.5 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "area", | ||||||
|  |           "fieldName": "地区", | ||||||
|  |           "fixedLabel": "地区", | ||||||
|  |           "fieldTips": "请选择地区", | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "icon": "icontext_area", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "areaPattern": "", | ||||||
|  |           "disable": "0", | ||||||
|  |           "grid": 0.5 | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "type": "options", | ||||||
|  |       "tips": "(可重复添加)", | ||||||
|  |       "label": "选项", | ||||||
|  |       "children": [ | ||||||
|  |         { | ||||||
|  |           "type": "radio", | ||||||
|  |           "fieldName": "单选", | ||||||
|  |           "fixedLabel": "单选", | ||||||
|  |           "fieldTips": "请选择", | ||||||
|  |           "grid": 0.5, | ||||||
|  |           "icon": "iconradio", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "disable": "0", | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "options": [ | ||||||
|  |             { | ||||||
|  |               "label": "选项1", | ||||||
|  |               "value": "" | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               "label": "选项2", | ||||||
|  |               "value": "" | ||||||
|  |             } | ||||||
|  |           ], | ||||||
|  |           "title": "" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "checkbox", | ||||||
|  |           "fieldName": "多选", | ||||||
|  |           "fixedLabel": "多选", | ||||||
|  |           "fieldTips": "请选择", | ||||||
|  |           "icon": "iconcheck_box", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "grid": 0.5, | ||||||
|  |           "disable": "0", | ||||||
|  |           "defaultValue": [], | ||||||
|  |           "options": [ | ||||||
|  |             { | ||||||
|  |               "label": "选项1", | ||||||
|  |               "value": "" | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               "label": "选项2", | ||||||
|  |               "value": "" | ||||||
|  |             } | ||||||
|  |           ], | ||||||
|  |           "title": "" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "select", | ||||||
|  |           "fieldName": "单下拉框", | ||||||
|  |           "fixedLabel": "单下拉框", | ||||||
|  |           "grid": 0.5, | ||||||
|  |           "fieldTips": "请选择", | ||||||
|  |           "icon": "iconSelect", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "disable": "0", | ||||||
|  |           "options": [ | ||||||
|  |             { | ||||||
|  |               "label": "选项1", | ||||||
|  |               "value": "" | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               "label": "选项2", | ||||||
|  |               "value": "" | ||||||
|  |             } | ||||||
|  |           ], | ||||||
|  |           "title": "" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "onOff", | ||||||
|  |           "fieldName": "开关", | ||||||
|  |           "fixedLabel": "开关", | ||||||
|  |           "grid": 0.5, | ||||||
|  |           "fieldTips": "请选择开关", | ||||||
|  |           "icon": "iconSelect", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "defaultValue": "0", | ||||||
|  |           "disable": "0", | ||||||
|  |           "title": "" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "date", | ||||||
|  |           "fieldName": "日期", | ||||||
|  |           "fixedLabel": "日期", | ||||||
|  |           "grid": 0.5, | ||||||
|  |           "datetimePattern": "yyyy-MM-dd", | ||||||
|  |           "fieldTips": "请选择日期", | ||||||
|  |           "icon": "iconSelect", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "disable": "0", | ||||||
|  |           "title": "" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "time", | ||||||
|  |           "fieldName": "时间", | ||||||
|  |           "fixedLabel": "时间", | ||||||
|  |           "grid": 0.5, | ||||||
|  |           "datetimePattern": "HH:mm:ss", | ||||||
|  |           "fieldTips": "请选择时间", | ||||||
|  |           "icon": "iconSelect", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "disable": "0", | ||||||
|  |           "title": "" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "datetime", | ||||||
|  |           "fieldName": "日期时间", | ||||||
|  |           "fixedLabel": "日期时间", | ||||||
|  |           "grid": 0.5, | ||||||
|  |           "datetimePattern": "yyyy-MM-dd HH:mm:ss", | ||||||
|  |           "fieldTips": "请选择日期时间", | ||||||
|  |           "icon": "iconSelect", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "disable": "0", | ||||||
|  |           "title": "" | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "type": "input", | ||||||
|  |       "tips": "(可重复添加)", | ||||||
|  |       "label": "填空", | ||||||
|  |       "children": [ | ||||||
|  |         { | ||||||
|  |           "type": "input", | ||||||
|  |           "fieldName": "单行填空", | ||||||
|  |           "fieldTips": "请输入", | ||||||
|  |           "fixedLabel": "单行填空", | ||||||
|  |           "disable": "0", | ||||||
|  |           "grid": 0.5, | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "icon": "icontext_box", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "maxLength": 50 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "textarea", | ||||||
|  |           "fieldName": "多行填空", | ||||||
|  |           "fixedLabel": "多行填空", | ||||||
|  |           "fieldTips": "请输入", | ||||||
|  |           "lineNumber": 4, | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "icon": "icontext_area", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "maxLength": 500, | ||||||
|  |           "disable": "0", | ||||||
|  |           "grid": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "number", | ||||||
|  |           "fieldName": "数字输入", | ||||||
|  |           "fixedLabel": "数字输入", | ||||||
|  |           "fieldTips": "请输入数字", | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "icon": "icontext_area", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "maxValue": 10000, | ||||||
|  |           "decimalPlaces": 0, | ||||||
|  |           "minValue": 0, | ||||||
|  |           "maxLength": 500, | ||||||
|  |           "disable": "0", | ||||||
|  |           "grid": 0.5 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "type": "rtf", | ||||||
|  |           "fieldName": "富文本", | ||||||
|  |           "fixedLabel": "富文本", | ||||||
|  |           "fieldTips": "请输入", | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "icon": "icontext_area", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "maxLength": 5000, | ||||||
|  |           "disable": "0", | ||||||
|  |           "grid": 1 | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "type": "annex", | ||||||
|  |       "tips": "(可重复添加)", | ||||||
|  |       "label": "附件", | ||||||
|  |       "children": [ | ||||||
|  |         { | ||||||
|  |           "type": "upload", | ||||||
|  |           "fieldTips": "请上传", | ||||||
|  |           "fieldName": "上传附件", | ||||||
|  |           "fixedLabel": "上传附件", | ||||||
|  |           "disable": "0", | ||||||
|  |           "fileChoseSize": 10, | ||||||
|  |           "fileMaxCount": 9, | ||||||
|  |           "defaultValue": "", | ||||||
|  |           "icon": "iconpic", | ||||||
|  |           "mustFill": "1", | ||||||
|  |           "grid": 1 | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "type": "layout", | ||||||
|  |       "tips": "(可重复添加)", | ||||||
|  |       "label": "分组", | ||||||
|  |       "children": [ | ||||||
|  |         { | ||||||
|  |           "type": "group", | ||||||
|  |           "fieldName": "卡片", | ||||||
|  |           "fixedLabel": "卡片", | ||||||
|  |           "icon": "iconpic", | ||||||
|  |           "groupName": "分组标题", | ||||||
|  |           "column": [] | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										1049
									
								
								project/oms/apps/develop/AppAiCode/detailLayout.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1049
									
								
								project/oms/apps/develop/AppAiCode/detailLayout.vue
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -14,6 +14,14 @@ | |||||||
|         </ai-search-bar> |         </ai-search-bar> | ||||||
|         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" |         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" | ||||||
|                   @getList="getTableData" :col-configs="colConfigs" :dict="dict"> |                   @getList="getTableData" :col-configs="colConfigs" :dict="dict"> | ||||||
|  |           <el-table-column type="expand" slot="expand"> | ||||||
|  |             <template slot-scope="{row}"> | ||||||
|  |               <ai-wrapper> | ||||||
|  |                 <ai-info-item labelWidth="200px" v-for="op in desConfigs" :key="op.prop" :value="row[op.prop]" | ||||||
|  |                               v-bind="op"/> | ||||||
|  |               </ai-wrapper> | ||||||
|  |             </template> | ||||||
|  |           </el-table-column> | ||||||
|           <el-table-column slot="process" label="打包进度"> |           <el-table-column slot="process" label="打包进度"> | ||||||
|             <template slot-scope="{row}"> |             <template slot-scope="{row}"> | ||||||
|               <span v-if="row.count==0" v-text="getProcessMsg(row)"/> |               <span v-if="row.count==0" v-text="getProcessMsg(row)"/> | ||||||
| @@ -24,27 +32,40 @@ | |||||||
|             <template slot-scope="{row}"> |             <template slot-scope="{row}"> | ||||||
|               <el-button type="text" @click="handleEdit(row)">编辑</el-button> |               <el-button type="text" @click="handleEdit(row)">编辑</el-button> | ||||||
|               <el-button type="text" @click="handleDelete(row.id)">删除</el-button> |               <el-button type="text" @click="handleDelete(row.id)">删除</el-button> | ||||||
|               <el-button type="text" @click="handleZip(row)">打包更新</el-button> |               <el-button type="text" @click="handleZip(row)" v-if="row.count==0">打包更新</el-button> | ||||||
|               <el-button type="text" v-if="row.download&&row.target" @click="handleDownload(row)">下载</el-button> |               <el-button type="text" @click="handleCancelZip(row)" v-else>停止打包</el-button> | ||||||
|  |               <el-button type="text" v-if="row.target" @click="handleDownload(row)">下载</el-button> | ||||||
|             </template> |             </template> | ||||||
|           </el-table-column> |           </el-table-column> | ||||||
|         </ai-table> |         </ai-table> | ||||||
|       </template> |       </template> | ||||||
|     </ai-list> |     </ai-list> | ||||||
|     <ai-dialog :visible.sync="dialog" title="部署任务设置" width="700px" @close="form={}" @onConfirm="submit"> |     <ai-dialog :visible.sync="dialog" title="部署任务设置" width="700px" @close="form={}" @onConfirm="submit"> | ||||||
|       <el-form ref="DialogForm" :model="form" size="small" label-width="120px" :rules="rules"> |       <el-form ref="DialogForm" :model="form" size="small" label-width="100px" :rules="rules"> | ||||||
|         <el-form-item label="项目/系统" prop="name"> |         <el-form-item label="项目/系统" prop="name"> | ||||||
|           <el-input v-model="form.name" clearable placeholder="请输入"/> |           <el-input v-model="form.name" clearable placeholder="请输入"/> | ||||||
|         </el-form-item> |         </el-form-item> | ||||||
|  |         <el-form-item label="系统类型" prop="type"> | ||||||
|  |           <ai-select v-model="form.type" :selectList="dict.getDict('systemType')"/> | ||||||
|  |         </el-form-item> | ||||||
|         <el-form-item label="打包脚本" prop="libShell"> |         <el-form-item label="打包脚本" prop="libShell"> | ||||||
|           <el-input v-model="form.libShell" clearable placeholder="请输入"/> |           <el-input v-model="form.libShell" clearable placeholder="请输入"/> | ||||||
|         </el-form-item> |         </el-form-item> | ||||||
|         <el-form-item label="更新脚本" prop="updateShell"> |         <el-form-item label="更新脚本" prop="updateShell"> | ||||||
|           <el-input v-model="form.updateShell" clearable placeholder="请输入"/> |           <el-input v-model="form.updateShell" clearable placeholder="请输入"/> | ||||||
|         </el-form-item> |         </el-form-item> | ||||||
|         <el-form-item label="开发环境nginx" prop="target"> |         <el-form-item label="项目URL" prop="webUrl"> | ||||||
|  |           <el-input v-model="form.webUrl" clearable placeholder="请输入"/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <el-form-item label="打包地址" prop="webUrl"> | ||||||
|  |           <el-input v-model="form.zipPath" clearable placeholder="请输入"/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <el-form-item label="nginx路径" prop="target"> | ||||||
|           <el-input v-model="form.target" clearable placeholder="请输入"/> |           <el-input v-model="form.target" clearable placeholder="请输入"/> | ||||||
|         </el-form-item> |         </el-form-item> | ||||||
|  |         <el-form-item label="node版本" prop="nodeVersion"> | ||||||
|  |           <el-input v-model="form.nodeVersion" clearable placeholder="请输入"/> | ||||||
|  |         </el-form-item> | ||||||
|       </el-form> |       </el-form> | ||||||
|     </ai-dialog> |     </ai-dialog> | ||||||
|   </section> |   </section> | ||||||
| @@ -62,7 +83,18 @@ export default { | |||||||
|     permissions: Function |     permissions: Function | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
|     ...mapState(['user']) |     ...mapState(['user']), | ||||||
|  |     desConfigs() { | ||||||
|  |       let isLine = true | ||||||
|  |       return [ | ||||||
|  |         {prop: "libShell", label: "打包脚本", width: 100}, | ||||||
|  |         {prop: "updateShell", label: "更新脚本", width: 100}, | ||||||
|  |         {prop: "zipPath", label: "打包地址", width: 100, isLine}, | ||||||
|  |         {prop: "target", label: "nginx路径", width: 100, isLine}, | ||||||
|  |         {prop: "webUrl", label: "项目URL", width: 100}, | ||||||
|  |         {prop: "nodeVersion", label: "node打包版本", width: 100}, | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
| @@ -70,10 +102,10 @@ export default { | |||||||
|       page: {current: 1, size: 10, total: 0}, |       page: {current: 1, size: 10, total: 0}, | ||||||
|       tableData: [], |       tableData: [], | ||||||
|       colConfigs: [ |       colConfigs: [ | ||||||
|  |         {slot: "expand"}, | ||||||
|         {label: "项目/系统名称", prop: "name", width: 200}, |         {label: "项目/系统名称", prop: "name", width: 200}, | ||||||
|         {label: "打包脚本", prop: "libShell"}, |         {label: "系统类型", prop: "type", dict: "systemType", width: 80}, | ||||||
|         {label: "更新脚本", prop: "updateShell"}, |         {label: "nginx路径", prop: "target"}, | ||||||
|         {label: "nginx地址", prop: "target"}, |  | ||||||
|         {slot: "process"}, |         {slot: "process"}, | ||||||
|         {slot: "options"} |         {slot: "options"} | ||||||
|       ], |       ], | ||||||
| @@ -81,9 +113,8 @@ export default { | |||||||
|       form: {}, |       form: {}, | ||||||
|       rules: { |       rules: { | ||||||
|         name: {required: true, message: "请输入项目/系统名称"}, |         name: {required: true, message: "请输入项目/系统名称"}, | ||||||
|         libShell: {required: true, message: "请输入 打包脚本"}, |       }, | ||||||
|         updateShell: {required: true, message: "请输入 更新脚本"}, |       timer: {} | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
| @@ -118,29 +149,28 @@ export default { | |||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|     handleZip(row) { |     handleZip(row) { | ||||||
|       let {id} = row |       let {id} = row, {timer} = this | ||||||
|       this.instance.post("/node/autodeploy/getZip", null, { |       this.instance.post("/node/autodeploy/getZip", null, { | ||||||
|         params: {id} |         params: {id} | ||||||
|       }).then(res => { |       }).then(res => { | ||||||
|         if (res?.code == 0) { |         if (res?.code == 0) { | ||||||
|           row.count = 1 |           row.count = 1 | ||||||
|           let timer = setInterval(() => { |           timer[id] = setInterval(() => { | ||||||
|             if (row.count >= 100) { |             if (row.count >= 100) { | ||||||
|               clearInterval(timer) |               clearInterval(timer[id]) | ||||||
|  |               row.count = 0 | ||||||
|               this.$message.error("打包失败!") |               this.$message.error("打包失败!") | ||||||
|             } else if (row.count <= 20 && row.target) { |             } else if (row.count <= 10 && row.target) { | ||||||
|               row.count++ |               row.count++ | ||||||
|             } else this.handleConfirmZip(row).then(v => { |             } else this.handleConfirmZip(row).then(v => { | ||||||
|               if (v.error) { |               if (v.error) { | ||||||
|                 clearInterval(timer) |                 clearInterval(timer[id]) | ||||||
|                 this.$message.error("打包失败!") |                 this.$message.error("打包失败!") | ||||||
|                 row.download = v.download |                 this.refreshRow(row, v) | ||||||
|                 row.error = v.error |  | ||||||
|                 row.count = 0 |                 row.count = 0 | ||||||
|               } else if (v.download) { |               } else if (v.download) { | ||||||
|                 clearInterval(timer) |                 clearInterval(timer[id]) | ||||||
|                 row.download = v.download |                 this.refreshRow(row, v) | ||||||
|                 row.error = v.error |  | ||||||
|                 row.count = 0 |                 row.count = 0 | ||||||
|               } else row.count++ |               } else row.count++ | ||||||
|             }) |             }) | ||||||
| @@ -148,6 +178,23 @@ export default { | |||||||
|         } |         } | ||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|  |     refreshRow(row, v) { | ||||||
|  |       row.error = v.error | ||||||
|  |       row.download = v.download | ||||||
|  |       row.zipTime = v.zipTime | ||||||
|  |     }, | ||||||
|  |     handleCancelZip(row) { | ||||||
|  |       let {id} = row | ||||||
|  |       return this.instance.post("/node/autodeploy/cancelZip", null, { | ||||||
|  |         params: {id} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.code == 0) { | ||||||
|  |           clearInterval(this.timer[id]) | ||||||
|  |           row.count = 0 | ||||||
|  |           this.handleConfirmZip(row).then(v => this.refreshRow(row, v)) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|     handleEdit(row) { |     handleEdit(row) { | ||||||
|       this.form = JSON.parse(JSON.stringify(row)) |       this.form = JSON.parse(JSON.stringify(row)) | ||||||
|       this.dialog = true |       this.dialog = true | ||||||
| @@ -186,11 +233,17 @@ export default { | |||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|     getProcessMsg(row) { |     getProcessMsg(row) { | ||||||
|       return row.error || (row.download ? `最近打包时间:${row.download}` : `暂无打包`) |       let time = row.zipTime ? this.$moment(row.download).diff(row.zipTime, 's', true) : "" | ||||||
|  |       return row.error || (row.download ? `最近打包时间:${row.download}(用时:${time}秒)` : | ||||||
|  |           row.zipTime ? `正在打包,开始于:${row.zipTime}` : `暂无打包`) | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   created() { |   created() { | ||||||
|  |     this.dict.load("systemType") | ||||||
|     this.getTableData() |     this.getTableData() | ||||||
|  |   }, | ||||||
|  |   beforeDestroy() { | ||||||
|  |     Object.values(this.timer).map(t => clearInterval(t)) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
| @@ -228,5 +228,6 @@ export default { | |||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
| .AppDeployWxmp { | .AppDeployWxmp { | ||||||
|  |   height: 100%; | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
							
								
								
									
										66
									
								
								project/oms/apps/develop/AppForm/AppForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								project/oms/apps/develop/AppForm/AppForm.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="doc-circulation"> | ||||||
|  |     <keep-alive :include="['List']"> | ||||||
|  |       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"/> | ||||||
|  |     </keep-alive> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |   import List from './components/List' | ||||||
|  |   import Add from './components/Add' | ||||||
|  |  | ||||||
|  |   export default { | ||||||
|  |     name: 'AppForm', | ||||||
|  |     label: '配置表单', | ||||||
|  |  | ||||||
|  |     props: { | ||||||
|  |       instance: Function, | ||||||
|  |       dict: Object | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     data () { | ||||||
|  |       return { | ||||||
|  |         component: 'List', | ||||||
|  |         params: {}, | ||||||
|  |         include: [] | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     components: { | ||||||
|  |       Add, | ||||||
|  |       List | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     mounted () { | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     methods: { | ||||||
|  |       onChange (data) { | ||||||
|  |         if (data.type === 'Add') { | ||||||
|  |           this.component = 'Add' | ||||||
|  |           this.params = data.params | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (data.type === 'list') { | ||||||
|  |           this.component = 'List' | ||||||
|  |           this.params = data.params | ||||||
|  |  | ||||||
|  |           this.$nextTick(() => { | ||||||
|  |             if (data.isRefresh) { | ||||||
|  |               this.$refs.component.getList() | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss"> | ||||||
|  |   .doc-circulation { | ||||||
|  |     height: 100%; | ||||||
|  |     background: #F3F6F9; | ||||||
|  |     overflow: auto; | ||||||
|  |   } | ||||||
|  | </style> | ||||||
							
								
								
									
										281
									
								
								project/oms/apps/develop/AppForm/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								project/oms/apps/develop/AppForm/components/Add.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,281 @@ | |||||||
|  | <template> | ||||||
|  |   <ai-detail class="form-add" :class="[currIndex === 1 ? 'form-add__active' : '']"> | ||||||
|  |     <ai-title title="表单配置" slot="title" isShowBottomBorder isShowBack  @onBackClick="cancel(false)"></ai-title> | ||||||
|  |     <template #content> | ||||||
|  |       <div class="ai-step"> | ||||||
|  |         <div class="ai-step__item" | ||||||
|  |           :class="[currIndex >= index ? 'ai-step__item--active' : '']" | ||||||
|  |           v-for="(item, index) in statusList" | ||||||
|  |           :key="index"> | ||||||
|  |           <div class="ai-step__item--icon" v-if="currIndex <= index"> | ||||||
|  |             <i v-if="currIndex === index"></i> | ||||||
|  |           </div> | ||||||
|  |           <div class="el-icon-success" v-if="currIndex > index"> | ||||||
|  |           </div> | ||||||
|  |           <span>{{ item }}</span> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <basic-info ref="basicInfo" v-model="basicInfo" v-show="currIndex === 0" :dict="dict" :instance="instance"></basic-info> | ||||||
|  |       <form-layout :appType="basicInfo.appType" :currIndex="currIndex" class="form-config__wrapper" v-model="tableInfos" ref="form" v-show="currIndex === 1" :dict="dict" :instance="instance"></form-layout> | ||||||
|  |       <form-config | ||||||
|  |         ref="config" | ||||||
|  |         :showListFields="showListFields" | ||||||
|  |         :btns="btns" | ||||||
|  |         :fuzzyQueryFields="fuzzyQueryFields" | ||||||
|  |         :tableInfos="tableInfos" | ||||||
|  |         :orderFields="orderFields" | ||||||
|  |         v-if="currIndex === 2"> | ||||||
|  |       </form-config> | ||||||
|  |     </template> | ||||||
|  |     <template #footer> | ||||||
|  |       <el-button @click="cancel">取消</el-button> | ||||||
|  |       <el-button @click="back" v-if="currIndex > 0">上一步</el-button> | ||||||
|  |       <el-button @click="next" type="primary">{{ currIndex === 2 ? '完成' : '下一步' }}</el-button> | ||||||
|  |     </template> | ||||||
|  |   </ai-detail> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |   import BasicInfo from './BasicInfo.vue' | ||||||
|  |   import FormLayout from './FormLayout.vue' | ||||||
|  |   import FormConfig from './FormConfig.vue' | ||||||
|  |   export default { | ||||||
|  |     name: 'add', | ||||||
|  |  | ||||||
|  |     props: { | ||||||
|  |       instance: Function, | ||||||
|  |       dict: Object, | ||||||
|  |       params: Object, | ||||||
|  |       type: String | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     components: { | ||||||
|  |       FormLayout, | ||||||
|  |       BasicInfo, | ||||||
|  |       FormConfig | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     data () { | ||||||
|  |       return { | ||||||
|  |         currIndex: 0, | ||||||
|  |         basicInfo: { | ||||||
|  |           saasPlatformId: '', | ||||||
|  |           menuLeve1Style: '', | ||||||
|  |           saasPlatformName: '', | ||||||
|  |           menuLevel1Name: '', | ||||||
|  |           menuLevel3Name: '', | ||||||
|  |           menuLevel2Name: '', | ||||||
|  |           appType: '' | ||||||
|  |         }, | ||||||
|  |         orderFields: [], | ||||||
|  |         showListFields: [], | ||||||
|  |         fuzzyQueryFields: [], | ||||||
|  |         btns: [], | ||||||
|  |         btnKeys: ['insertEnable', 'importEnable', 'exportEnalbe', 'editEnable', 'deleteEnable', 'batchDelEnable'], | ||||||
|  |         configInfo: { | ||||||
|  |           btns: [], | ||||||
|  |           orderType: '0', | ||||||
|  |           fieldName: '' | ||||||
|  |         }, | ||||||
|  |         info: {}, | ||||||
|  |         tableInfos: [], | ||||||
|  |         statusList: ['基础设置', '表单设计', '列表设计'] | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     mounted () { | ||||||
|  |       if (this.params.id) { | ||||||
|  |         this.getInfo() | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     methods: { | ||||||
|  |       cancel (isRefresh) { | ||||||
|  |         this.$emit('change', { | ||||||
|  |           type: 'list', | ||||||
|  |           isRefresh: isRefresh ? true : false, | ||||||
|  |           isQuote: this.params.isQuote ? true : false | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       confirm () { | ||||||
|  |  | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       back () { | ||||||
|  |         this.currIndex = this.currIndex - 1 | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       confirmBasicInfo () { | ||||||
|  |         return this.$refs.basicInfo.validate() | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       getInfo () { | ||||||
|  |         this.instance.post(`/app/appapplicationinfo/queryDetailById?id=${this.params.id}`).then(res => { | ||||||
|  |           if (res.code === 0) { | ||||||
|  |             this.info = res.data | ||||||
|  |             this.basicInfo = { | ||||||
|  |               saasPlatformId: res.data.saasPlatformId, | ||||||
|  |               menuLeve1Style: res.data.menuLeve1Style, | ||||||
|  |               saasPlatformName: res.data.saasPlatformName, | ||||||
|  |               menuLevel1Name: res.data.menuLevel1Name, | ||||||
|  |               menuLevel3Name: res.data.menuLevel3Name, | ||||||
|  |               menuLevel2Name: res.data.menuLevel2Name, | ||||||
|  |               appType: res.data.appType, | ||||||
|  |               corpId: res.data.corpId, | ||||||
|  |               corpName: res.data.corpName | ||||||
|  |             } | ||||||
|  |             this.fuzzyQueryFields = res.data.fuzzyQueryFields | ||||||
|  |             this.tableInfos = res.data.tableInfos | ||||||
|  |             this.showListFields = res.data.showListFields | ||||||
|  |             this.orderFields = res.data.orderFields | ||||||
|  |             this.btns = Object.keys(res.data).filter(v => { | ||||||
|  |               return this.btnKeys.indexOf(v) > -1 && res.data[v] === '1' | ||||||
|  |             }) | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       submit (info) { | ||||||
|  |         this.instance.post(`/app/appapplicationinfo/addOrUpdate`, { | ||||||
|  |           ...this.info, | ||||||
|  |           ...this.basicInfo, | ||||||
|  |           tableInfos: this.tableInfos, | ||||||
|  |           ...info.btns, | ||||||
|  |           id: this.params.id, | ||||||
|  |           applicationName: this.basicInfo.menuLevel3Name || this.basicInfo.menuLevel2Name, | ||||||
|  |           fuzzyQueryFields: info.fuzzyQueryFields, | ||||||
|  |           orderType: info.orderType, | ||||||
|  |           orderFields: info.orderFields, | ||||||
|  |           showListFields: info.showListFields | ||||||
|  |         }).then(res => { | ||||||
|  |           if (res.code === 0) { | ||||||
|  |             this.$message.success(this.params.id ? '编辑成功' : '添加成功') | ||||||
|  |             this.cancel(true) | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       next () { | ||||||
|  |         if (this.currIndex === 0) { | ||||||
|  |           if (!this.$refs.basicInfo.validate()) return | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (this.currIndex === 1) { | ||||||
|  |           this.$refs.form.onConfirm() | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (this.currIndex === 2) { | ||||||
|  |           const info = this.$refs.config.validate() | ||||||
|  |           if (!info) return | ||||||
|  |  | ||||||
|  |           this.submit(info) | ||||||
|  |  | ||||||
|  |           return false | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.currIndex = this.currIndex + 1 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  |   .form-add { | ||||||
|  |     &.form-add__active { | ||||||
|  |       ::v-deep .ai-detail__content--wrapper { | ||||||
|  |         max-width: 100%!important; | ||||||
|  |         height: 100%!important; | ||||||
|  |         background: #F5F6F9; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .form-config__wrapper { | ||||||
|  |         height: calc(100% - 52px); | ||||||
|  |         overflow-y: hidden; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       ::v-deep .ai-detail__content { | ||||||
|  |         height: calc(100% - 114px)!important; | ||||||
|  |         padding: 0!important; | ||||||
|  |         overflow: hidden!important; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .ai-step { | ||||||
|  |       display: flex; | ||||||
|  |       align-items: center; | ||||||
|  |       justify-content: center; | ||||||
|  |       margin-top: 4px; | ||||||
|  |       margin-bottom: 24px; | ||||||
|  |  | ||||||
|  |       .ai-step__item { | ||||||
|  |         display: flex; | ||||||
|  |         position: relative; | ||||||
|  |         align-items: center; | ||||||
|  |         margin-right: 216px; | ||||||
|  |  | ||||||
|  |         &.ai-step__item--active { | ||||||
|  |           span { | ||||||
|  |             color: #2266FF; | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           .ai-step__item--icon { | ||||||
|  |             display: flex; | ||||||
|  |             align-items: center; | ||||||
|  |             justify-content: center; | ||||||
|  |             border-color: #2266FF; | ||||||
|  |  | ||||||
|  |             i { | ||||||
|  |               width: 12px; | ||||||
|  |               height: 12px; | ||||||
|  |               border-radius: 50%; | ||||||
|  |               background: #2266FF; | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         &:after { | ||||||
|  |           position: absolute; | ||||||
|  |           top: 50%; | ||||||
|  |           right: -208px; | ||||||
|  |           width: 200px; | ||||||
|  |           height: 2px; | ||||||
|  |           background: #D0D4DC; | ||||||
|  |           content: ' '; | ||||||
|  |           transform: translateY(-50%); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         &:last-child { | ||||||
|  |           margin-right: 0; | ||||||
|  |  | ||||||
|  |           &::after { | ||||||
|  |             display: none; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .ai-step__item--icon { | ||||||
|  |           width: 24px; | ||||||
|  |           height: 24px; | ||||||
|  |           margin-right: 8px; | ||||||
|  |           border-radius: 50%; | ||||||
|  |           background: #FFFFFF; | ||||||
|  |           border: 2px solid #D0D4DC; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         .el-icon-success { | ||||||
|  |           width: 24px; | ||||||
|  |           height: 24px; | ||||||
|  |           font-size: 24px; | ||||||
|  |           margin-right: 8px; | ||||||
|  |           color: #2266FF; | ||||||
|  |           border-radius: 50%; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         span { | ||||||
|  |           color: #666666; | ||||||
|  |           font-size: 14px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </style> | ||||||
							
								
								
									
										151
									
								
								project/oms/apps/develop/AppForm/components/BasicInfo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								project/oms/apps/develop/AppForm/components/BasicInfo.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="basicInfo"> | ||||||
|  |     <el-form ref="form" :model="form" label-width="110px" label-position="right"> | ||||||
|  |       <ai-card title="基本信息"> | ||||||
|  |         <template #content> | ||||||
|  |           <div class="ai-form"> | ||||||
|  |             <el-form-item label="所属平台" prop="saasPlatformId" style="width: 100%;" :rules="[{ required: true, message: '请选择所属平台', trigger: 'change' }]"> | ||||||
|  |               <el-select | ||||||
|  |                 size="small" | ||||||
|  |                 style="width: 100%;" | ||||||
|  |                 placeholder="请选择所属平台" | ||||||
|  |                 clearable | ||||||
|  |                 @change="onChange" | ||||||
|  |                 v-model="form.saasPlatformId"> | ||||||
|  |                 <el-option | ||||||
|  |                   v-for="(item, index) in sassList" | ||||||
|  |                   :key="index" | ||||||
|  |                   :label="item.name" | ||||||
|  |                   :value="item.id"> | ||||||
|  |                 </el-option> | ||||||
|  |               </el-select> | ||||||
|  |             </el-form-item> | ||||||
|  |             <el-form-item v-if="form.saasPlatformId" style="width: 100%;" label="所属企业" prop="corpId" :rules="[{ required: true, message: '请选择所属企业', trigger: 'change' }]"> | ||||||
|  |               <ai-select | ||||||
|  |                 v-model="form.corpId" | ||||||
|  |                 placeholder="请选择所属企业" | ||||||
|  |                 clearable | ||||||
|  |                 @change="onCompanyChange" | ||||||
|  |                 :selectList="companyList"> | ||||||
|  |               </ai-select> | ||||||
|  |             </el-form-item> | ||||||
|  |             <el-form-item  style="width: 100%;" label="一级菜单名称" prop="menuLevel1Name" :rules="[{ required: true, message: '请输入一级菜单名称', trigger: 'change' }]"> | ||||||
|  |               <el-input size="small" placeholder="请输入一级菜单名称" :maxlength="8" v-model="form.menuLevel1Name"></el-input> | ||||||
|  |             </el-form-item> | ||||||
|  |             <el-form-item style="width: 100%;" label="二级菜单名称" prop="menuLevel2Name" :rules="[{ required: true, message: '请输入二级菜单名称', trigger: 'change' }]"> | ||||||
|  |               <el-input size="small" placeholder="请输入二级菜单名称" :maxlength="8" v-model="form.menuLevel2Name"></el-input> | ||||||
|  |             </el-form-item> | ||||||
|  |             <el-form-item style="width: 100%;" label="三级菜单名称" prop="menuLevel3Name"> | ||||||
|  |               <el-input size="small" placeholder="请输入三级菜单名称" :maxlength="8" v-model="form.menuLevel3Name"></el-input> | ||||||
|  |             </el-form-item> | ||||||
|  |             <el-form-item style="width: 100%;" label="应用类型" prop="appType"> | ||||||
|  |               <ai-select | ||||||
|  |                 v-model="form.appType" | ||||||
|  |                 placeholder="请选择应用类型" | ||||||
|  |                 clearable | ||||||
|  |                 :selectList="dict.getDict('diyAppType')"> | ||||||
|  |               </ai-select> | ||||||
|  |             </el-form-item> | ||||||
|  |           </div> | ||||||
|  |         </template> | ||||||
|  |       </ai-card> | ||||||
|  |     </el-form> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |   export default { | ||||||
|  |     name: 'basicInfo', | ||||||
|  |  | ||||||
|  |     model: { | ||||||
|  |       prop: 'value', | ||||||
|  |       event: 'change', | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     props: { | ||||||
|  |       instance: Function, | ||||||
|  |       dict: Object, | ||||||
|  |       value: Object | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     data () { | ||||||
|  |       return { | ||||||
|  |         form: { | ||||||
|  |           saasPlatformId: '', | ||||||
|  |           menuLeve1Style: '', | ||||||
|  |           saasPlatformName: '', | ||||||
|  |           menuLevel1Name: '', | ||||||
|  |           menuLevel2Name: '', | ||||||
|  |           menuLevel3Name: '', | ||||||
|  |           appType: '', | ||||||
|  |           corpId: '', | ||||||
|  |           corpName: '' | ||||||
|  |         }, | ||||||
|  |         companyList: [], | ||||||
|  |         sassList: [] | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     watch: { | ||||||
|  |       value (v) { | ||||||
|  |         this.form = JSON.parse(JSON.stringify(v)) | ||||||
|  |         if (this.form.saasPlatformId) { | ||||||
|  |           this.getCompanyList() | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     created () { | ||||||
|  |       this.dict.load('diyAppType') | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     mounted () { | ||||||
|  |       this.getSassList() | ||||||
|  |       this.form = JSON.parse(JSON.stringify(this.value)) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     methods: { | ||||||
|  |       onChange (e) { | ||||||
|  |         this.form.saasPlatformName = this.sassList.filter(v => v.id === e)[0].name | ||||||
|  |         this.form.saasPlatformId && this.getCompanyList() | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       validate () { | ||||||
|  |         let result = false | ||||||
|  |         this.$refs.form.validate(valid => { | ||||||
|  |           result = valid | ||||||
|  |         }) | ||||||
|  |         this.$emit('change', this.form) | ||||||
|  |         return result  | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       onCompanyChange (e) { | ||||||
|  |         this.form.corpName = this.companyList.filter(v => v.dictValue === e)[0].dictName | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       getCompanyList () { | ||||||
|  |         this.instance.post(`/app/appCorp/page?current=1&size=1000&saasId=${this.form.saasPlatformId}`).then(res => { | ||||||
|  |           if (res.data.records.length) { | ||||||
|  |             this.companyList = res.data.records.map(v => { | ||||||
|  |               return { | ||||||
|  |                 dictValue: v.corpId, | ||||||
|  |                 dictName: v.name | ||||||
|  |               } | ||||||
|  |             }) | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       getSassList () { | ||||||
|  |         this.instance.post(`/app/appSaas/listAll`).then(res => { | ||||||
|  |           if (res.data) { | ||||||
|  |             this.sassList = res.data | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | </style> | ||||||
							
								
								
									
										244
									
								
								project/oms/apps/develop/AppForm/components/FormConfig.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								project/oms/apps/develop/AppForm/components/FormConfig.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="basicInfo"> | ||||||
|  |     <ai-card title="搜索字段" class="search-wrapper"> | ||||||
|  |       <template #content> | ||||||
|  |         <el-checkbox-group v-model="queryFields"> | ||||||
|  |           <el-checkbox | ||||||
|  |             :label="`${item.fieldDbName}~${item.fieldName}`" | ||||||
|  |             v-for="(item, index) in tableInfos" | ||||||
|  |             :key="index"> | ||||||
|  |             {{ item.fieldName }} | ||||||
|  |           </el-checkbox> | ||||||
|  |         </el-checkbox-group> | ||||||
|  |       </template> | ||||||
|  |     </ai-card> | ||||||
|  |     <ai-card title="表格字段"> | ||||||
|  |       <template #content> | ||||||
|  |         <div class="ai-table"> | ||||||
|  |           <div class="el-table el-table--border ai-header__border"> | ||||||
|  |             <el-scrollbar> | ||||||
|  |               <table cellspacing="0" cellpadding="0" border="0" class="el-table__body"> | ||||||
|  |                 <draggable element="thead" animation="500" class="el-table__header is-leaf ai-table__header" :sort="true" v-model="showFields"> | ||||||
|  |                   <th v-for="(item, index) in showFields" style="background: #f3f4f5; text-align: center;" class="ai-table__header" :key="index">{{ item.fieldName }}</th> | ||||||
|  |                 </draggable>  | ||||||
|  |                 <tbody element="tbody"> | ||||||
|  |                   <tr> | ||||||
|  |                     <td @click="handleShow(index, item.isShow)" v-for="(item, index) in showFields" :key="index">{{ item.isShow ? '已显示' : '已隐藏' }}</td> | ||||||
|  |                   </tr> | ||||||
|  |                 </tbody>  | ||||||
|  |               </table> | ||||||
|  |             </el-scrollbar> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </template> | ||||||
|  |     </ai-card> | ||||||
|  |     <ai-card title="排序和操作按钮"> | ||||||
|  |       <template #content> | ||||||
|  |         <el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right"> | ||||||
|  |           <el-form-item label="排序字段" prop="field"> | ||||||
|  |             <el-select | ||||||
|  |               size="small" | ||||||
|  |               placeholder="默认按创建时间排序" | ||||||
|  |               clearable | ||||||
|  |               v-model="form.field"> | ||||||
|  |               <el-option | ||||||
|  |                 v-for="(filed, index) in tableInfos" | ||||||
|  |                 :key="index" | ||||||
|  |                 :label="filed.fieldName" | ||||||
|  |                 :value="`${filed.fieldDbName}~${filed.fieldName}`"> | ||||||
|  |               </el-option> | ||||||
|  |             </el-select> | ||||||
|  |           </el-form-item> | ||||||
|  |           <el-form-item label="排序类型" prop="orderType" :rules="[{ required: true, message: '请输入排序类型', trigger: 'change' }]"> | ||||||
|  |             <el-radio-group v-model="form.orderType"> | ||||||
|  |               <el-radio label="asc">升序</el-radio> | ||||||
|  |               <el-radio label="desc">降序</el-radio> | ||||||
|  |             </el-radio-group> | ||||||
|  |           </el-form-item> | ||||||
|  |           <el-form-item label="按钮配置" prop="btns" style="width: 100%;" :rules="[{ required: true, message: '请输入按钮配置', trigger: 'change' }]"> | ||||||
|  |             <el-checkbox-group v-model="form.btns"> | ||||||
|  |               <el-checkbox label="insertEnable">添加</el-checkbox> | ||||||
|  |               <el-checkbox label="importEnable">导入</el-checkbox> | ||||||
|  |               <el-checkbox label="exportEnalbe">导出</el-checkbox> | ||||||
|  |               <el-checkbox label="editEnable">编辑</el-checkbox> | ||||||
|  |               <el-checkbox label="deleteEnable">删除</el-checkbox> | ||||||
|  |               <el-checkbox label="batchDelEnable">批量删除</el-checkbox> | ||||||
|  |             </el-checkbox-group> | ||||||
|  |           </el-form-item> | ||||||
|  |         </el-form> | ||||||
|  |       </template> | ||||||
|  |     </ai-card> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |   import draggable from 'vuedraggable' | ||||||
|  |   export default { | ||||||
|  |     name: 'configForm', | ||||||
|  |  | ||||||
|  |     props: { | ||||||
|  |       tableInfos: Array, | ||||||
|  |       btns: Array, | ||||||
|  |       showListFields: Array, | ||||||
|  |       orderFields: Array, | ||||||
|  |       fuzzyQueryFields: Array | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     components: { | ||||||
|  |       draggable | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     data () { | ||||||
|  |       return { | ||||||
|  |         queryFields: [], | ||||||
|  |         tableData: [{}], | ||||||
|  |         btnKeys: ['insertEnable', 'importEnable', 'exportEnalbe', 'editEnable', 'deleteEnable', 'batchDelEnable'], | ||||||
|  |         form: { | ||||||
|  |           btns: [], | ||||||
|  |           orderType: 'asc', | ||||||
|  |           field: '' | ||||||
|  |         }, | ||||||
|  |         showFields: [] | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     mounted () { | ||||||
|  |       const showIds = this.showListFields.map(v => v.fieldDbName) | ||||||
|  |       this.showFields = JSON.parse(JSON.stringify(this.tableInfos)).map(item => { | ||||||
|  |         item.isShow = showIds.indexOf(item.fieldDbName) > -1 ? true : false | ||||||
|  |  | ||||||
|  |         return item | ||||||
|  |       }) | ||||||
|  |  | ||||||
|  |       if (!this.showListFields.length) { | ||||||
|  |         this.showFields.map(v => { | ||||||
|  |           v.isShow = true | ||||||
|  |           return v | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       this.tableInfos.map(item => { | ||||||
|  |         this.tableData[0][item.fieldDbName] = '删除' | ||||||
|  |       }) | ||||||
|  |  | ||||||
|  |       if (this.btns.length) { | ||||||
|  |         this.form.btns = this.btns | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       const tableInfosIds = this.tableInfos.map(v => v.fieldDbName) | ||||||
|  |  | ||||||
|  |       if (this.orderFields.length) { | ||||||
|  |         let arr = this.orderFields.filter(v => { | ||||||
|  |           return tableInfosIds.indexOf(v.fieldDbName) > -1 | ||||||
|  |         }).map(item => { | ||||||
|  |           return `${item.fieldDbName}~${item.fieldName}` | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         if (arr.length) { | ||||||
|  |           this.form.field = arr[0] | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       if (this.fuzzyQueryFields.length) { | ||||||
|  |         this.queryFields = this.fuzzyQueryFields.filter(v => { | ||||||
|  |           return tableInfosIds.indexOf(v.fieldDbName) > -1 | ||||||
|  |         }).map(item => { | ||||||
|  |           return `${item.fieldDbName}~${item.fieldName}` | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     methods: { | ||||||
|  |       validate () { | ||||||
|  |         let result = false | ||||||
|  |         this.$refs.form.validate(valid => { | ||||||
|  |           result = valid | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         if (!result) { | ||||||
|  |           return false | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         const btns = {} | ||||||
|  |         this.btnKeys.forEach(item => { | ||||||
|  |           btns[item] = this.form.btns.indexOf(item) > -1 ? 1 : 0  | ||||||
|  |         }) | ||||||
|  |  | ||||||
|  |         return { | ||||||
|  |           btns, | ||||||
|  |           orderFields: [{ | ||||||
|  |             fieldName: this.form.field.split('~')[1], | ||||||
|  |             fieldDbName: this.form.field.split('~')[0], | ||||||
|  |             orderType: this.form.orderType | ||||||
|  |           }], | ||||||
|  |           showListFields: this.showFields.filter(v => v.isShow).map((v, index) => { | ||||||
|  |             return { | ||||||
|  |               fieldName: v.fieldName, | ||||||
|  |               fieldDbName: v.fieldDbName, | ||||||
|  |               showListIndex: index | ||||||
|  |             } | ||||||
|  |           }), | ||||||
|  |           fuzzyQueryFields: this.queryFields.map(v => { | ||||||
|  |             return { | ||||||
|  |               fieldName: v.split('~')[1], | ||||||
|  |               fieldDbName: v.split('~')[0] | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       handleShow (index, isShow) { | ||||||
|  |         const total = this.showFields.map(v => v.isShow).filter(v => !!v) | ||||||
|  |         if (total.length <= 1 && isShow) { | ||||||
|  |           return this.$message.error('表格列数不能小于1') | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         this.$set(this.showFields[index], 'isShow', !isShow) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style scoped lang="scss"> | ||||||
|  |   .basicInfo { | ||||||
|  |     .search-wrapper { | ||||||
|  |       ::v-deep .el-checkbox-group { | ||||||
|  |         display: flex; | ||||||
|  |         flex-wrap: wrap; | ||||||
|  |  | ||||||
|  |         .el-checkbox { | ||||||
|  |           width: 16.66%; | ||||||
|  |           margin-bottom: 10px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .ai-table { | ||||||
|  |     .el-table--border { | ||||||
|  |       border: 1px solid #d0d4dc; | ||||||
|  |       border-bottom: none; | ||||||
|  |       border-right: none; | ||||||
|  |     } | ||||||
|  |     table { | ||||||
|  |       min-width: 100%; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     th, tr { | ||||||
|  |       min-width: 100px; | ||||||
|  |       cursor: move; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     tr { | ||||||
|  |       td { | ||||||
|  |         cursor: pointer; | ||||||
|  |         color: #26f; | ||||||
|  |         text-align: center; | ||||||
|  |         user-select: none; | ||||||
|  |  | ||||||
|  |         &:hover { | ||||||
|  |           opacity: 0.7; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </style> | ||||||
							
								
								
									
										1198
									
								
								project/oms/apps/develop/AppForm/components/FormLayout.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1198
									
								
								project/oms/apps/develop/AppForm/components/FormLayout.vue
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										272
									
								
								project/oms/apps/develop/AppForm/components/config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								project/oms/apps/develop/AppForm/components/config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,272 @@ | |||||||
|  | export const components = [ | ||||||
|  | 	{ | ||||||
|  | 		type: 'info', | ||||||
|  | 		tips: '(不能重复添加同一元素)', | ||||||
|  | 		label: '信息', | ||||||
|  | 		children: [ | ||||||
|  | 			{ | ||||||
|  | 				type: 'name', | ||||||
|  | 				fieldName: '姓名', | ||||||
|  | 				fieldTips: '请输入姓名', | ||||||
|  | 				fixedLabel: '姓名', | ||||||
|  | 				disable: '0', | ||||||
|  | 				grid: 0.5, | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				icon: 'icontext_box', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				maxLength: 20 | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'idNumber', | ||||||
|  | 				fieldName: '身份证号', | ||||||
|  | 				fixedLabel: '身份证号', | ||||||
|  | 				fieldTips: '请输入身份证号', | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				icon: 'icontext_area', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				maxLength: 20, | ||||||
|  | 				disable: '0', | ||||||
|  | 				grid: 0.5 | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'phone', | ||||||
|  | 				fieldName: '联系方式', | ||||||
|  | 				fixedLabel: '联系方式', | ||||||
|  | 				fieldTips: '请输入联系方式', | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				icon: 'icontext_area', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				maxLength: 20, | ||||||
|  | 				disable: '0', | ||||||
|  | 				grid: 0.5 | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'area', | ||||||
|  | 				fieldName: '地区', | ||||||
|  | 				fixedLabel: '地区', | ||||||
|  | 				fieldTips: '请选择地区', | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				icon: 'icontext_area', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				areaPattern: '', | ||||||
|  | 				disable: '0', | ||||||
|  | 				grid: 0.5 | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		type: 'options', | ||||||
|  | 		tips: '(可重复添加)', | ||||||
|  | 		label: '选项', | ||||||
|  | 		children: [ | ||||||
|  | 			{ | ||||||
|  | 				type: 'radio', | ||||||
|  | 				fieldName: '单选', | ||||||
|  | 				fixedLabel: '单选', | ||||||
|  | 				fieldTips: '请选择', | ||||||
|  | 				grid: 0.5, | ||||||
|  | 				icon: 'iconradio', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				disable: '0', | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				options: [ | ||||||
|  | 					{ | ||||||
|  | 						label: '选项1', | ||||||
|  | 						value: '' | ||||||
|  | 					}, | ||||||
|  | 					{ | ||||||
|  | 						label: '选项2', | ||||||
|  | 						value: '' | ||||||
|  | 					} | ||||||
|  | 				], | ||||||
|  | 				title: '' | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'checkbox', | ||||||
|  | 				fieldName: '多选', | ||||||
|  | 				fixedLabel: '多选', | ||||||
|  | 				fieldTips: '请选择', | ||||||
|  | 				icon: 'iconcheck_box', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				grid: 0.5, | ||||||
|  | 				disable: '0', | ||||||
|  | 				defaultValue: [], | ||||||
|  | 				options: [ | ||||||
|  | 					{ | ||||||
|  | 						label: '选项1', | ||||||
|  | 						value: '' | ||||||
|  | 					}, | ||||||
|  | 					{ | ||||||
|  | 						label: '选项2', | ||||||
|  | 						value: '' | ||||||
|  | 					} | ||||||
|  | 				], | ||||||
|  | 				title: '' | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'select', | ||||||
|  | 				fieldName: '单下拉框', | ||||||
|  | 				fixedLabel: '单下拉框', | ||||||
|  | 				grid: 0.5, | ||||||
|  | 				fieldTips: '请选择', | ||||||
|  | 				icon: 'iconSelect', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				disable: '0', | ||||||
|  | 				options: [ | ||||||
|  | 					{ | ||||||
|  | 						label: '选项1', | ||||||
|  | 						value: '' | ||||||
|  | 					}, | ||||||
|  | 					{ | ||||||
|  | 						label: '选项2', | ||||||
|  | 						value: '' | ||||||
|  | 					} | ||||||
|  | 				], | ||||||
|  | 				title: '' | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'onOff', | ||||||
|  | 				fieldName: '开关', | ||||||
|  | 				fixedLabel: '开关', | ||||||
|  | 				grid: 0.5, | ||||||
|  | 				fieldTips: '请选择开关', | ||||||
|  | 				icon: 'iconSelect', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				defaultValue: '0', | ||||||
|  | 				disable: '0', | ||||||
|  | 				title: '' | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'date', | ||||||
|  | 				fieldName: '日期', | ||||||
|  | 				fixedLabel: '日期', | ||||||
|  | 				grid: 0.5, | ||||||
|  | 				datetimePattern: 'yyyy-MM-dd', | ||||||
|  | 				fieldTips: '请选择日期', | ||||||
|  | 				icon: 'iconSelect', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				disable: '0', | ||||||
|  | 				title: '' | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'time', | ||||||
|  | 				fieldName: '时间', | ||||||
|  | 				fixedLabel: '时间', | ||||||
|  | 				grid: 0.5, | ||||||
|  | 				datetimePattern: 'HH:mm:ss', | ||||||
|  | 				fieldTips: '请选择时间', | ||||||
|  | 				icon: 'iconSelect', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				disable: '0', | ||||||
|  | 				title: '' | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'datetime', | ||||||
|  | 				fieldName: '日期时间', | ||||||
|  | 				fixedLabel: '日期时间', | ||||||
|  | 				grid: 0.5, | ||||||
|  | 				datetimePattern: 'yyyy-MM-dd HH:mm:ss', | ||||||
|  | 				fieldTips: '请选择日期时间', | ||||||
|  | 				icon: 'iconSelect', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				disable: '0', | ||||||
|  | 				title: '' | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		type: 'input', | ||||||
|  | 		tips: '(可重复添加)', | ||||||
|  | 		label: '填空', | ||||||
|  | 		children: [ | ||||||
|  | 			{ | ||||||
|  | 				type: 'input', | ||||||
|  | 				fieldName: '单行填空', | ||||||
|  | 				fieldTips: '请输入', | ||||||
|  | 				fixedLabel: '单行填空', | ||||||
|  | 				disable: '0', | ||||||
|  | 				grid: 0.5, | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				icon: 'icontext_box', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				maxLength: 50 | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'textarea', | ||||||
|  | 				fieldName: '多行填空', | ||||||
|  | 				fixedLabel: '多行填空', | ||||||
|  | 				fieldTips: '请输入', | ||||||
|  | 				lineNumber: 4, | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				icon: 'icontext_area', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				maxLength: 500, | ||||||
|  | 				disable: '0', | ||||||
|  | 				grid: 1 | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'number', | ||||||
|  | 				fieldName: '数字输入', | ||||||
|  | 				fixedLabel: '数字输入', | ||||||
|  | 				fieldTips: '请输入数字', | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				icon: 'icontext_area', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				maxValue: 10000, | ||||||
|  | 				decimalPlaces: 0, | ||||||
|  | 				minValue: 0, | ||||||
|  | 				maxLength: 500, | ||||||
|  | 				disable: '0', | ||||||
|  | 				grid: 0.5 | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				type: 'rtf', | ||||||
|  | 				fieldName: '富文本', | ||||||
|  | 				fixedLabel: '富文本', | ||||||
|  | 				fieldTips: '请输入', | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				icon: 'icontext_area', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				maxLength: 5000, | ||||||
|  | 				disable: '0', | ||||||
|  | 				grid: 1 | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		type: 'annex', | ||||||
|  | 		tips: '(可重复添加)', | ||||||
|  | 		label: '附件', | ||||||
|  | 		children: [ | ||||||
|  | 			{ | ||||||
|  | 				type: 'upload', | ||||||
|  | 				fieldTips: '请上传', | ||||||
|  | 				fieldName: '上传附件', | ||||||
|  | 				fixedLabel: '上传附件', | ||||||
|  | 				disable: '0', | ||||||
|  | 				fileChoseSize: 10, | ||||||
|  | 				fileMaxCount: 9, | ||||||
|  | 				defaultValue: '', | ||||||
|  | 				icon: 'iconpic', | ||||||
|  | 				mustFill: '1', | ||||||
|  | 				grid: 1 | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		type: 'layout', | ||||||
|  | 		tips: '(可重复添加)', | ||||||
|  | 		label: '分组', | ||||||
|  | 		children: [ | ||||||
|  | 			{ | ||||||
|  | 				type: 'group', | ||||||
|  | 				fieldName: '卡片', | ||||||
|  | 				fixedLabel: '卡片', | ||||||
|  | 				icon: 'iconpic', | ||||||
|  | 				groupName: '分组标题', | ||||||
|  | 				column: [] | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	} | ||||||
|  | ]; | ||||||
							
								
								
									
										62
									
								
								project/sanjianxi/apps/AppIntegralAudit/AppIntegralAudit.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								project/sanjianxi/apps/AppIntegralAudit/AppIntegralAudit.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="AppHealthReport"> | ||||||
|  |     <keep-alive :include="['List']"> | ||||||
|  |       <component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component> | ||||||
|  |     </keep-alive> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |   import List from './components/List.vue' | ||||||
|  |   import Detail from './components/Detail.vue' | ||||||
|  |  | ||||||
|  |   export default { | ||||||
|  |     name: 'AppIntegralAudit', | ||||||
|  |     label: '积分审核(三涧溪)', | ||||||
|  |  | ||||||
|  |     components: { | ||||||
|  |       List, | ||||||
|  |       Detail | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     props: { | ||||||
|  |       instance: Function, | ||||||
|  |       dict: Object, | ||||||
|  |       permissions: Function | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     data () { | ||||||
|  |       return { | ||||||
|  |         component: 'List', | ||||||
|  |         params: {} | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     methods: { | ||||||
|  |       onChange (data) { | ||||||
|  |         if (data.type === 'Detail') { | ||||||
|  |           this.component = 'Detail' | ||||||
|  |           this.isShowDetail = true | ||||||
|  |           this.params = data.params | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (data.type === 'list') { | ||||||
|  |           this.component = 'List' | ||||||
|  |           this.params = data.params | ||||||
|  |  | ||||||
|  |           this.$nextTick(() => { | ||||||
|  |             if (data.isRefresh) { | ||||||
|  |               this.$refs.component.getList() | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  |   .AppHealthReport { | ||||||
|  |     height: 100%; | ||||||
|  |   } | ||||||
|  | </style> | ||||||
							
								
								
									
										269
									
								
								project/sanjianxi/apps/AppIntegralAudit/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								project/sanjianxi/apps/AppIntegralAudit/components/Detail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,269 @@ | |||||||
|  | <template> | ||||||
|  |   <ai-detail class="audit"> | ||||||
|  |     <template slot="title"> | ||||||
|  |       <ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(true)"> | ||||||
|  |       </ai-title> | ||||||
|  |     </template> | ||||||
|  |     <template slot="content"> | ||||||
|  |       <ai-card title="基本信息"> | ||||||
|  |         <template #content> | ||||||
|  |           <ai-wrapper | ||||||
|  |               label-width="120px"> | ||||||
|  |             <ai-info-item label="申请人" :value="info.residentName"></ai-info-item> | ||||||
|  |             <ai-info-item label="申请时间" :value="info.createTime"></ai-info-item> | ||||||
|  |             <ai-info-item label="积分类型" :value="dict.getLabel('atWillReportType', info.applyIntegralType)"></ai-info-item> | ||||||
|  |             <ai-info-item label="规则类型" :value="info.residentName"></ai-info-item> | ||||||
|  |             <ai-info-item label="申请描述" :value="info.description" isLine></ai-info-item> | ||||||
|  |             <!-- <ai-info-item label="联系电话" isLine :value="info.residentPhone"></ai-info-item> --> | ||||||
|  |             <ai-info-item label="图片资料" isLine v-show="info.applyFiles"> | ||||||
|  |               <ai-uploader v-model="info.applyFiles" disabled></ai-uploader> | ||||||
|  |             </ai-info-item> | ||||||
|  |           </ai-wrapper> | ||||||
|  |         </template> | ||||||
|  |       </ai-card> | ||||||
|  |       <ai-card title="审核详情" v-if="info.auditStatus !== '0'"> | ||||||
|  |         <div slot="content" style="margin-top: 16px;margin-bottom:24px"> | ||||||
|  |           <ai-wrapper | ||||||
|  |               label-width="120px"> | ||||||
|  |             <ai-info-item label="审核结果" :value="info.auditStatus === '1' ? '通过' : '拒绝'"></ai-info-item> | ||||||
|  |             <ai-info-item label="积分调整" isLine v-if="info.auditStatus === '1'" | ||||||
|  |                           :value="(info.auditIntegral >= 0 ? info.auditIntegral : info.auditIntegral) + '分'"></ai-info-item> | ||||||
|  |             <ai-info-item label="审核人" :value="info.auditUserName"></ai-info-item> | ||||||
|  |             <ai-info-item label="审核时间" :value="info.auditTime"></ai-info-item> | ||||||
|  |             <ai-info-item label="审核意见" v-if="info.auditStatus === '2'" isLine :value="info.auditOpinion"></ai-info-item> | ||||||
|  |             <!-- <ai-info-item label="积分规则类别" v-if="info.auditStatus === '1'" :value="dict.getLabel('atWillReportType', info.auditIntegralType)"></ai-info-item> --> | ||||||
|  |             <!-- <ai-info-item label="积分规则事项" v-if="info.auditStatus === '1'" :value="info.auditRuleName"></ai-info-item> --> | ||||||
|  |           </ai-wrapper> | ||||||
|  |         </div> | ||||||
|  |       </ai-card> | ||||||
|  |       <ai-dialog | ||||||
|  |           :visible.sync="isShow" | ||||||
|  |           width="800px" | ||||||
|  |           @close="onClose" | ||||||
|  |           title="事件审核" | ||||||
|  |           @onConfirm="onConfirm"> | ||||||
|  |         <el-form class="ai-form" label-width="120px" :model="form" ref="form"> | ||||||
|  |  | ||||||
|  |           <el-form-item label="是否通过审核" prop="pass" style="width: 100%;" :rules="[{ required: true, message: '请选择是否通过审核' }]"> | ||||||
|  |             <el-radio-group v-model="form.pass" @change="onStatusChange"> | ||||||
|  |               <el-radio label="0">否</el-radio> | ||||||
|  |               <el-radio label="1">是</el-radio> | ||||||
|  |             </el-radio-group> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <el-form-item label="积分分值" prop="pass" style="width: 100%;" :rules="[{ required: true, message: '请输入积分分值' }]"> | ||||||
|  |             <el-input v-model="num" placeholder="请输入1-10的整数"></el-input> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <el-form-item label="积分分值" prop="pass" style="width: 100%;" :rules="[{ required: true, message: '请输入积分分值' }]"> | ||||||
|  |             <el-input v-model="num" placeholder="请输入1-10的整数"></el-input> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <el-form-item label="加分项" prop="pass" style="width: 100%;" :rules="[{ required: true, message: '请选择加分项' }]"> | ||||||
|  |             <!-- <ai-select v-model="form.integralCalcType" :selectList="dict.getDict('integralCalcType')"/> --> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <el-form-item label="积分分值" prop="pass" style="width: 100%;" :rules="[{ required: true, message: '请输入积分分值' }]"> | ||||||
|  |             <el-input v-model="num" placeholder="请输入1-10的整数"></el-input> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <!-- <el-form-item v-if="form.pass === '1'" label="积分调整" prop="auditIntegral" style="width: 100%;" :rules="[{ required: true, message: '请输入积分调整' }]"> | ||||||
|  |             <el-input v-model.number="form.auditIntegral" clearable placeholder="请输入积分调整" @keyup.native="form.auditIntegral=Math.abs(form.auditIntegral)"/> | ||||||
|  |           </el-form-item> --> | ||||||
|  |  | ||||||
|  |           <!-- <el-form-item v-if="form.pass === '1'" label="积分规则类别" prop="auditRuleId" style="width: 100%;" :rules="[{ required: true, message: '' }]"> | ||||||
|  |             <div class="flex-warpper"> | ||||||
|  |               <el-form-item  label-width="0" prop="auditIntegralType" :rules="[{ required: true, message: '请选择积分规则类别' }]"> | ||||||
|  |                 <ai-select | ||||||
|  |                   v-model="form.auditIntegralType" clearable | ||||||
|  |                   style="width: 180px;" | ||||||
|  |                   placeholder="请选择积分规则类别" | ||||||
|  |                   :selectList="dict.getDict('atWillReportType')" | ||||||
|  |                   @change="onChange"> | ||||||
|  |                 </ai-select> | ||||||
|  |               </el-form-item> | ||||||
|  |               <el-form-item style="margin: 0 10px;" prop="auditRuleId" :rules="[{ required: true, message: '请选择积分规则事项' }]"> | ||||||
|  |                 <ai-select | ||||||
|  |                   v-model="form.auditRuleId" | ||||||
|  |                   clearable | ||||||
|  |                   style="width: 180px;" | ||||||
|  |                   placeholder="请选择积分规则事项" | ||||||
|  |                   :selectList="ruleList"> | ||||||
|  |                 </ai-select> | ||||||
|  |               </el-form-item> | ||||||
|  |               <span>{{ integralText }}</span> | ||||||
|  |             </div> | ||||||
|  |           </el-form-item> --> | ||||||
|  |  | ||||||
|  |           <el-form-item label="审核意见" v-if="form.pass === '0'" prop="opinion" style="width: 100%;" :rules="[{ required: true, message: '请输入审核意见' }]"> | ||||||
|  |             <el-input type="textarea" :rows="5" :maxlength="200" v-model="form.opinion" clearable placeholder="请输入审核意见" show-word-limit></el-input> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |         </el-form> | ||||||
|  |       </ai-dialog> | ||||||
|  |     </template> | ||||||
|  |  | ||||||
|  |     <template #footer v-if="info.auditStatus === '0'"> | ||||||
|  |       <el-button @click="cancel">取消</el-button> | ||||||
|  |       <el-button type="primary" @click="isShow = true">审核</el-button> | ||||||
|  |     </template> | ||||||
|  |  | ||||||
|  |   </ai-detail> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: 'Detail', | ||||||
|  |  | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     params: Object | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   data() { | ||||||
|  |     const validatorRules = function (rule, value, callback) { | ||||||
|  |       if (value === '') { | ||||||
|  |         callback(new Error('请输入联系方式')) | ||||||
|  |       } else if (!/^1\d{10}$/.test(value)) { | ||||||
|  |         callback(new Error('手机号格式错误')) | ||||||
|  |       } else { | ||||||
|  |         callback() | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return { | ||||||
|  |       total: 0, | ||||||
|  |       info: { | ||||||
|  |         auditStatus: '0' | ||||||
|  |       }, | ||||||
|  |       id: '', | ||||||
|  |       isShow: true, | ||||||
|  |       form: { | ||||||
|  |         auditIntegralType: '', | ||||||
|  |         auditRuleId: '', | ||||||
|  |         opinion: '', | ||||||
|  |         pass: '' | ||||||
|  |       }, | ||||||
|  |       ruleList: [], | ||||||
|  |       num: '' | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   computed: { | ||||||
|  |     integralText() { | ||||||
|  |       if (!this.form.auditRuleId) { | ||||||
|  |         return '' | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       const integral = this.ruleList.filter(v => v.dictValue === this.form.auditRuleId)[0].integral | ||||||
|  |  | ||||||
|  |       return integral >= 0 ? `+${integral}分` : `${integral}分` | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   created() { | ||||||
|  |     let loading = this.$loading({ | ||||||
|  |       text: 'Loading', | ||||||
|  |     }); | ||||||
|  |     if (this.params && this.params.id) { | ||||||
|  |       this.id = this.params.id | ||||||
|  |       this.dict.load(['atWillReportType', 'auditStatus']).then(() => { | ||||||
|  |         this.getInfo(this.params.id) | ||||||
|  |         this.$nextTick(() => { | ||||||
|  |           loading.close() | ||||||
|  |         }) | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   methods: { | ||||||
|  |     getInfo(id) { | ||||||
|  |       this.instance.post(`/app/appvillagerintegraldeclare/queryDetailById?id=${id}`).then(res => { | ||||||
|  |         if (res.code === 0) { | ||||||
|  |           this.info = res.data | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     onStatusChange() { | ||||||
|  |       this.$refs.form.clearValidate() | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     onClose() { | ||||||
|  |       this.form.auditIntegralType = '' | ||||||
|  |       this.form.auditRuleId = '' | ||||||
|  |       this.form.pass = '' | ||||||
|  |       this.form.opinion = '' | ||||||
|  |       this.id = '' | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     onConfirm() { | ||||||
|  |       this.$refs.form.validate(v => { | ||||||
|  |         if (v) { | ||||||
|  |           this.instance.post('/app/appvillagerintegraldeclare/examine', null, { | ||||||
|  |             params: { | ||||||
|  |               ...this.form, | ||||||
|  |               id: this.params.id, | ||||||
|  |             } | ||||||
|  |           }).then(res => { | ||||||
|  |             if (res.code == 0) { | ||||||
|  |               this.isShow = false | ||||||
|  |               this.getInfo(this.params.id) | ||||||
|  |               this.$message.success('审核成功!') | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     onChange(e) { | ||||||
|  |       this.form.auditRuleId = '' | ||||||
|  |       this.instance.post(`/app/appvillagerintegralrule/list?size=1000&classification=${e}`).then(res => { | ||||||
|  |         if (res?.code == 0) { | ||||||
|  |           this.ruleList = res.data.records.filter(v => v.ruleStatus === '1').map(v => { | ||||||
|  |             return { | ||||||
|  |               dictName: v.ruleName, | ||||||
|  |               dictValue: v.id, | ||||||
|  |               ruleName: v.ruleName, | ||||||
|  |               integral: v.integral | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     cancel(isRefresh) { | ||||||
|  |       this.$emit('change', { | ||||||
|  |         type: 'list', | ||||||
|  |         isRefresh: !!isRefresh | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style scoped lang="scss"> | ||||||
|  | .audit { | ||||||
|  |   .flex-warpper { | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  |  | ||||||
|  |     ::v-deep .el-form-item .el-form-item__content { | ||||||
|  |       margin-left: 0 !important; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ::v-deep .ai-select { | ||||||
|  |       margin: 0 !important; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ::v-deep .el-form-item { | ||||||
|  |       width: auto; | ||||||
|  |       margin-bottom: 0; | ||||||
|  |  | ||||||
|  |       &:last-child { | ||||||
|  |         margin-right: 10px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										236
									
								
								project/sanjianxi/apps/AppIntegralAudit/components/List.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								project/sanjianxi/apps/AppIntegralAudit/components/List.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,236 @@ | |||||||
|  | <template> | ||||||
|  |   <ai-list class="list"> | ||||||
|  |     <ai-title | ||||||
|  |       slot="title" | ||||||
|  |       title="积分审核" | ||||||
|  |       v-if="search.areaId" | ||||||
|  |       isShowBottomBorder | ||||||
|  |       :instance="instance" | ||||||
|  |       :disabledLevel="disabledLevel" | ||||||
|  |       isShowArea | ||||||
|  |       v-model="search.areaId" | ||||||
|  |       @change="changeArea"> | ||||||
|  |     </ai-title> | ||||||
|  |     <template slot="content"> | ||||||
|  |       <div class="content"> | ||||||
|  |         <ai-search-bar> | ||||||
|  |           <template #left> | ||||||
|  |             <!-- <ai-select | ||||||
|  |               v-model="search.applyIntegralType" | ||||||
|  |               clearable | ||||||
|  |               placeholder="请选择积分类型" | ||||||
|  |               :selectList="dict.getDict('atWillReportType')" | ||||||
|  |               @change="search.current = 1, getList()"> | ||||||
|  |             </ai-select> --> | ||||||
|  |             <ai-select | ||||||
|  |               v-model="search.auditStatus" | ||||||
|  |               clearable | ||||||
|  |               placeholder="请选择审核状态" | ||||||
|  |               :selectList="dict.getDict('auditStatus')" | ||||||
|  |               @change="search.current = 1, getList()"> | ||||||
|  |             </ai-select> | ||||||
|  |             <el-date-picker | ||||||
|  |               value-format="yyyy-MM-dd" | ||||||
|  |               v-model="search.createTimeStart" | ||||||
|  |               type="date" | ||||||
|  |               size="small" | ||||||
|  |               unlink-panels | ||||||
|  |               placeholder="选择开始日期" | ||||||
|  |               @change="search.current = 1, getList()" /> | ||||||
|  |             <el-date-picker | ||||||
|  |               value-format="yyyy-MM-dd" | ||||||
|  |               v-model="search.createTimeEnd" | ||||||
|  |               type="date" | ||||||
|  |               size="small" | ||||||
|  |               unlink-panels | ||||||
|  |               placeholder="选择结束日期" | ||||||
|  |               @change="search.current = 1, getList()" /> | ||||||
|  |           </template> | ||||||
|  |           <template #right> | ||||||
|  |             <el-input | ||||||
|  |               v-model="search.residentName" | ||||||
|  |               size="small" | ||||||
|  |               placeholder="请输入姓名/事件类型" | ||||||
|  |               clearable | ||||||
|  |               v-throttle="() => {search.current = 1, getList()}" | ||||||
|  |               @clear="search.current = 1, search.residentName = '', getList()" | ||||||
|  |               suffix-icon="iconfont iconSearch"> | ||||||
|  |             </el-input> | ||||||
|  |           </template> | ||||||
|  |         </ai-search-bar> | ||||||
|  |         <ai-table | ||||||
|  |           :tableData="tableData" | ||||||
|  |           :col-configs="colConfigs" | ||||||
|  |           :total="total" | ||||||
|  |           v-loading="loading" | ||||||
|  |           style="margin-top: 8px;" | ||||||
|  |           :current.sync="search.current" | ||||||
|  |           :size.sync="search.size" | ||||||
|  |           @getList="getList"> | ||||||
|  |           <el-table-column slot="options" width="120px" fixed="right" label="操作" align="center"> | ||||||
|  |             <template slot-scope="{ row }"> | ||||||
|  |               <div class="table-options"> | ||||||
|  |                 <el-button type="text" @click="toDetail(row.id)">详情</el-button> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </el-table-column> | ||||||
|  |         </ai-table> | ||||||
|  |       </div> | ||||||
|  |     </template> | ||||||
|  |   </ai-list> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |   import { mapState } from 'vuex' | ||||||
|  |   export default { | ||||||
|  |     name: 'List', | ||||||
|  |     props: { | ||||||
|  |       instance: Function, | ||||||
|  |       dict: Object | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     data () { | ||||||
|  |       return { | ||||||
|  |         search: { | ||||||
|  |           current: 1, | ||||||
|  |           size: 10, | ||||||
|  |           residentName: '', | ||||||
|  |           applyIntegralType: '', | ||||||
|  |           areaId: '', | ||||||
|  |           auditStatus: '', | ||||||
|  |           createTimeStart: '', | ||||||
|  |           createTimeEnd: '' | ||||||
|  |         }, | ||||||
|  |         dictList: [{ | ||||||
|  |           dictName: '否', | ||||||
|  |           dictValue: '0' | ||||||
|  |         }, { | ||||||
|  |           dictName: '是', | ||||||
|  |           dictValue: '1' | ||||||
|  |         }], | ||||||
|  |         info: {}, | ||||||
|  |         colConfigs: [ | ||||||
|  |           { prop: 'residentName', label: '申请人' }, | ||||||
|  |           { prop: 'residentPhone', align: 'center', label: '联系电话' }, | ||||||
|  |           { prop: 'createTime', align: 'center', label: '申请时间' }, | ||||||
|  |           { prop: 'applyIntegralType', align: 'center', label: '积分类型', formart: v => this.dict.getLabel('atWillReportType', v) },  | ||||||
|  |           { prop: 'auditStatus', align: 'center', label: '状态', formart: v => v ? this.dict.getLabel('auditStatus', v) : '-' },  | ||||||
|  |           { prop: 'auditUserName', align: 'center', label: '审批人' },  | ||||||
|  |           { prop: 'auditTime', align: 'center', label: '审批时间' } | ||||||
|  |         ], | ||||||
|  |         tableData: [], | ||||||
|  |         total: 0, | ||||||
|  |         loading: false, | ||||||
|  |         disabledLevel: 0 | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     computed: { | ||||||
|  |       ...mapState(['user']), | ||||||
|  |  | ||||||
|  |       param () { | ||||||
|  |         return { | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     created () { | ||||||
|  |       this.disabledLevel = this.user.info.areaList.length - 1 | ||||||
|  |       this.search.areaId = this.user.info.areaId | ||||||
|  |       this.loading = true | ||||||
|  |       this.dict.load(['atWillReportType', 'auditStatus']).then(() => { | ||||||
|  |         this.getList() | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     methods: { | ||||||
|  |       getList () { | ||||||
|  |         this.instance.post(`/app/appvillagerintegraldeclare/list`, null, { | ||||||
|  |           params: { | ||||||
|  |             ...this.search | ||||||
|  |           } | ||||||
|  |         }).then(res => { | ||||||
|  |           if (res.code == 0) { | ||||||
|  |             this.tableData = res.data.records | ||||||
|  |             this.total = res.data.total | ||||||
|  |             this.loading = false | ||||||
|  |           } else { | ||||||
|  |             this.loading = false | ||||||
|  |           } | ||||||
|  |         }).catch(() => { | ||||||
|  |           this.loading = false | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       toDetail (id) { | ||||||
|  |         this.$emit('change', { | ||||||
|  |           type: 'Detail', | ||||||
|  |           params: { | ||||||
|  |             id: id || '' | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }, | ||||||
|  |  | ||||||
|  |       changeArea () { | ||||||
|  |         this.search.current = 1 | ||||||
|  |  | ||||||
|  |         this.$nextTick(() => { | ||||||
|  |           this.getList() | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style scoped lang="scss"> | ||||||
|  |   .list { | ||||||
|  |     ::v-deep .ai-list__content { | ||||||
|  |       padding: 0!important; | ||||||
|  |  | ||||||
|  |       .ai-list__content--right-wrapper { | ||||||
|  |         background: transparent!important; | ||||||
|  |         box-shadow: none!important; | ||||||
|  |         margin: 0!important; | ||||||
|  |         padding: 12px 16px 12px!important; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     .statistics-top { | ||||||
|  |       display: flex; | ||||||
|  |       align-items: center; | ||||||
|  |       margin-bottom: 20px; | ||||||
|  |  | ||||||
|  |       & > div { | ||||||
|  |         flex: 1; | ||||||
|  |         height: 96px; | ||||||
|  |         line-height: 1; | ||||||
|  |         margin-right: 20px; | ||||||
|  |         padding: 16px 24px; | ||||||
|  |         background: #FFFFFF; | ||||||
|  |         box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); | ||||||
|  |         border-radius: 4px; | ||||||
|  |  | ||||||
|  |         &:last-child { | ||||||
|  |           margin-right: 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         h3 { | ||||||
|  |           font-size: 24px; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         span { | ||||||
|  |           display: block; | ||||||
|  |           margin-bottom: 16px; | ||||||
|  |           color: #888888; | ||||||
|  |           font-size: 16px; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .content { | ||||||
|  |       padding: 16px; | ||||||
|  |       background: #FFFFFF; | ||||||
|  |       box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </style> | ||||||
							
								
								
									
										35
									
								
								project/sanjianxi/apps/AppPartyScore/AppPartyScore.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								project/sanjianxi/apps/AppPartyScore/AppPartyScore.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AppPartyScore"> | ||||||
|  |     <component :is="currentPage" v-bind="$props"/> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import PsList from "./psList"; | ||||||
|  | import PsDetail from "./psDetail"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "AppPartyScore", | ||||||
|  |   components: {PsDetail, PsList}, | ||||||
|  |   label: "党员积分(三涧溪)", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     permissions: Function | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     currentPage() { | ||||||
|  |       return this.$route.query.id ? PsDetail : PsList | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.dict.load("partyIntegralType") | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AppPartyScore { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										162
									
								
								project/sanjianxi/apps/AppPartyScore/psDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								project/sanjianxi/apps/AppPartyScore/psDetail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="psDetail"> | ||||||
|  |     <ai-detail> | ||||||
|  |       <ai-title slot="title" title="积分详情" isShowBottomBorder isShowBack @onBackClick="back"/> | ||||||
|  |       <template #content> | ||||||
|  |         <el-row type="flex"> | ||||||
|  |           <ai-card hideTitle class="staCard fill"> | ||||||
|  |             <template #content> | ||||||
|  |               <div class="color-999" v-text="`姓名`"/> | ||||||
|  |               <b v-text="detail.name"/> | ||||||
|  |             </template> | ||||||
|  |           </ai-card> | ||||||
|  |           <ai-card hideTitle class="staCard fill"> | ||||||
|  |             <template slot="content"> | ||||||
|  |               <div class="color-999" v-text="`党员积分`"/> | ||||||
|  |               <b class="color-26f" v-text="detail.integral||0"/> | ||||||
|  |             </template> | ||||||
|  |           </ai-card> | ||||||
|  |           <!-- <ai-card hideTitle class="staCard fill"> | ||||||
|  |             <template #content> | ||||||
|  |               <div class="color-999" v-text="`学习强国`"/> | ||||||
|  |               <el-button type="text" @click="handleEditLearningIntergral(detail.id)">编辑</el-button> | ||||||
|  |               <b class="color-26f" v-text="detail.learningIntegral||0"/> | ||||||
|  |             </template> | ||||||
|  |           </ai-card> | ||||||
|  |           <ai-card hideTitle class="staCard fill"> | ||||||
|  |             <template slot="content"> | ||||||
|  |               <div class="color-999" v-text="`个人积分`"/> | ||||||
|  |               <b class="color-26f" v-text="detail.integral||0"/> | ||||||
|  |             </template> | ||||||
|  |           </ai-card> | ||||||
|  |           <ai-card hideTitle class="staCard fill"> | ||||||
|  |             <template #content> | ||||||
|  |               <div class="color-999" v-text="`家庭积分`"/> | ||||||
|  |               <b class="color-26f" v-text="detail.familySurplusIntegral||0"/> | ||||||
|  |             </template> | ||||||
|  |           </ai-card> --> | ||||||
|  |         </el-row> | ||||||
|  |         <ai-card title="余额变动明细"> | ||||||
|  |           <template #content> | ||||||
|  |             <ai-table :tableData="detail.integralInfoList" :isShowPagination="false" :col-configs="colConfigs" | ||||||
|  |                       :dict="dict"/> | ||||||
|  |           </template> | ||||||
|  |         </ai-card> | ||||||
|  |       </template> | ||||||
|  |     </ai-detail> | ||||||
|  |     <ai-dialog :visible.sync="dialog" title="学习强国设置" width="500px" @close="form={}" @onConfirm="submit"> | ||||||
|  |       <el-form :model="form" size="small" ref="DialogForm" :rules="rules" label-width="110px"> | ||||||
|  |         <el-form-item label="学习强国积分" prop="learningIntegral"> | ||||||
|  |           <el-input v-model.number="form.learningIntegral" placeholder="请输入正整数" clearable/> | ||||||
|  |         </el-form-item> | ||||||
|  |       </el-form> | ||||||
|  |     </ai-dialog> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "psDetail", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       detail: {}, | ||||||
|  |       colConfigs: [ | ||||||
|  |         {label: "时间", prop: "createTime"}, | ||||||
|  |         {label: "类型", prop: "integralType", align: 'center', dict: "partyIntegralType"}, | ||||||
|  |         {label: "变动积分", prop: "integral", align: 'center'}, | ||||||
|  |         {label: "剩余积分", prop: "residualIntegral", align: 'center'}, | ||||||
|  |         {label: "调整说明", prop: "remark"}, | ||||||
|  |       ], | ||||||
|  |       dialog: false, | ||||||
|  |       form: {}, | ||||||
|  |       rules: { | ||||||
|  |         learningIntegral: [ | ||||||
|  |           {required: true, message: "请输入学习强国积分"}, | ||||||
|  |           {pattern: /^\d+$/g, message: "请输入正整数"} | ||||||
|  |         ] | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getDetail() { | ||||||
|  |       let {id} = this.$route.query | ||||||
|  |       this.instance.post("/app/appparty/getPartyIntegralDetail", null, { | ||||||
|  |         params: {id} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.detail = res.data | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     back() { | ||||||
|  |       this.$router.push({}) | ||||||
|  |     }, | ||||||
|  |     submit() { | ||||||
|  |       this.$refs.DialogForm.validate(v => { | ||||||
|  |         if (v) { | ||||||
|  |           this.instance.post("/app/appparty/editLearningIntegral", null,{ | ||||||
|  |             params:this.form | ||||||
|  |           }).then(res => { | ||||||
|  |             if (res?.code == 0) { | ||||||
|  |               this.$message.success("提交成功!") | ||||||
|  |               this.dialog = false | ||||||
|  |               this.getDetail() | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     handleEditLearningIntergral(partyMemberId) { | ||||||
|  |       this.dialog = true | ||||||
|  |       this.form = {partyMemberId} | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getDetail() | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .psDetail { | ||||||
|  |   height: 100%; | ||||||
|  |  | ||||||
|  |   .color-999 { | ||||||
|  |     color: #999; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .color-26f { | ||||||
|  |     color: #26f; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ::v-deep .staCard { | ||||||
|  |     font-size: 14px; | ||||||
|  |     width: 25%; | ||||||
|  |  | ||||||
|  |     b { | ||||||
|  |       font-size: 24px; | ||||||
|  |       line-height: 40px; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     & + .staCard { | ||||||
|  |       margin-left: 16px; | ||||||
|  |       width: 25%; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .ai-card__body { | ||||||
|  |       position: relative; | ||||||
|  |  | ||||||
|  |       .el-button { | ||||||
|  |         position: absolute; | ||||||
|  |         right: 32px; | ||||||
|  |         top: 6px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										175
									
								
								project/sanjianxi/apps/AppPartyScore/psList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								project/sanjianxi/apps/AppPartyScore/psList.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,175 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="psList"> | ||||||
|  |     <ai-list> | ||||||
|  |       <ai-title slot="title" title="党员积分" isShowBottomBorder/> | ||||||
|  |       <template #left> | ||||||
|  |  | ||||||
|  |         <ai-tree-menu title="组织目录" searchPlaceholder="请输入党组织名称" @search="onSearch"> | ||||||
|  |           <ai-party-tree | ||||||
|  |               :filter-node-method="filterNode" | ||||||
|  |               ref="tree" | ||||||
|  |               :instance="instance" | ||||||
|  |               :root="user.info.organizationId" | ||||||
|  |               :current-node-key="user.info.id" | ||||||
|  |               @select="onTreeChange"/> | ||||||
|  |         </ai-tree-menu> | ||||||
|  |       </template> | ||||||
|  |       <template #content> | ||||||
|  |         <ai-search-bar> | ||||||
|  |           <template #left> | ||||||
|  |             <div>统计周期</div> | ||||||
|  |             <el-date-picker type="daterange" placeholder="日期" size="small" clearable v-model="createTime" | ||||||
|  |                         @change="handleSearchTime" start-placeholder="开始时间" end-placeholder="结束时间" | ||||||
|  |                         value-format="yyyy-MM-dd HH:mm:ss" :default-time="['00:00:00','23:59:59']"/> | ||||||
|  |           </template> | ||||||
|  |           <template #right> | ||||||
|  |             <el-input size="small" placeholder="党员姓名" v-model="search.partyName" clearable | ||||||
|  |                       @change="page.current=1,getTableData()" suffix-icon="iconfont iconSearch"/> | ||||||
|  |             <ai-download :instance="instance" url="/app/apppartyintegralinfo/downloadTemplate" :params="search" fileName="党员积分" :disabled="tableData.length == 0"> | ||||||
|  |               <el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button> | ||||||
|  |             </ai-download> | ||||||
|  |           </template> | ||||||
|  |         </ai-search-bar> | ||||||
|  |         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" | ||||||
|  |                   @getList="getTableData" :col-configs="colConfigs" :dict="dict"> | ||||||
|  |           <el-table-column slot="options" label="操作" fixed="right" align="center"> | ||||||
|  |             <template slot-scope="{row}"> | ||||||
|  |               <el-button type="text" @click="getFamilyByPartyId(row.idNumber)">家庭成员</el-button> | ||||||
|  |               <el-button type="text" @click="showDetail(row.id)">详情</el-button> | ||||||
|  |             </template> | ||||||
|  |           </el-table-column> | ||||||
|  |         </ai-table> | ||||||
|  |       </template> | ||||||
|  |     </ai-list> | ||||||
|  |     <ai-dialog :visible.sync="dialog" title="家庭成员" :customFooter="true" width="780px" @close="familyList=[]"> | ||||||
|  |       <ai-table :tableData="familyList" :isShowPagination="false" :col-configs="familyCols" :dict="dict"/> | ||||||
|  |       <div class="dialog-footer" slot="footer"> | ||||||
|  |         <el-button @click="dialog=false">关 闭</el-button> | ||||||
|  |       </div> | ||||||
|  |     </ai-dialog> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import { mapState } from "vuex"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "psList", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     ...mapState(['user']), | ||||||
|  |     colConfigs() { | ||||||
|  |       return [ | ||||||
|  |         {label: "排行榜", prop: "name", align: "center"}, | ||||||
|  |         {label: "党员姓名", prop: "name", align: "center"}, | ||||||
|  |         {label: "党员类型", prop: "name", align: "center"}, | ||||||
|  |         {label: "获得积分", prop: "name", align: "center"}, | ||||||
|  |         // {label: "个人积分", prop: "integral", align: "center"}, | ||||||
|  |         // {label: "家庭积分", prop: "familySurplusIntegral", align: "center"}, | ||||||
|  |         // {label: "学习强国", prop: "learningIntegral", align: "center"}, | ||||||
|  |         {slot: "options"} | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     familyCols() { | ||||||
|  |       return [ | ||||||
|  |         { | ||||||
|  |           label: '与户主关系', prop: 'householdRelation', align: 'center', width: 165, | ||||||
|  |           render: (h, {row}) => h('p', this.dict.getLabel('householdRelation', row.householdRelation || "户主")) | ||||||
|  |         }, | ||||||
|  |         {label: '类型', prop: 'residentType', align: 'center', dict: "residentType"}, | ||||||
|  |         {label: '姓名', prop: 'name', align: 'center'}, | ||||||
|  |         {label: '身份证号', render: (h, {row}) => h('p', this.idCardNoUtil.hideId(row.idNumber)), width: 165}, | ||||||
|  |         {label: '联系电话', prop: 'phone', align: 'center', width: 120} | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       search: { | ||||||
|  |         createTime: '', | ||||||
|  |       }, | ||||||
|  |       page: {current: 1, size: 10, total: 0}, | ||||||
|  |       tableData: [], | ||||||
|  |       dialog: false, | ||||||
|  |       familyList: [], | ||||||
|  |       organizationName: '', | ||||||
|  |       organizationTree: [], | ||||||
|  |       defaultExpanded: [], | ||||||
|  |       defaultChecked: [], | ||||||
|  |       areaTree: [], | ||||||
|  |       defaultProps: { | ||||||
|  |         children: 'children', | ||||||
|  |         label: 'name' | ||||||
|  |       }, | ||||||
|  |       createTime: '', | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     back() { | ||||||
|  |       this.$router.push({}) | ||||||
|  |     }, | ||||||
|  |     getTableData() { | ||||||
|  |       this.instance.post("/app/appparty/listByPartyIntegral", null, { | ||||||
|  |         params: {...this.page, ...this.search} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.tableData = res.data?.records | ||||||
|  |           this.page.total = res.data.total | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |      | ||||||
|  |     onSearch(v) { | ||||||
|  |       this.orgTree.filter(v) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     onTreeChange(e) { | ||||||
|  |       this.search.areaId = e.id | ||||||
|  |       this.areaName = e.name | ||||||
|  |       this.search.current = 1 | ||||||
|  |  | ||||||
|  |       this.$nextTick(() => { | ||||||
|  |         this.getList() | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     filterNode(value, data) { | ||||||
|  |       if (!value) return true | ||||||
|  |       return data.name.indexOf(value) !== -1 | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     handleSearchTime(v) { | ||||||
|  |       // this.page.current = 1 | ||||||
|  |       // this.search.startTime = v?.[0] | ||||||
|  |       // this.search.endTime = v?.[1] | ||||||
|  |       // this.getTableData() | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     showDetail(id) { | ||||||
|  |       this.$router.push({query: {id}}) | ||||||
|  |     }, | ||||||
|  |     getFamilyByPartyId(idNumber) { | ||||||
|  |       this.instance.post("/app/appresident/queryHomeMember", null, { | ||||||
|  |         params: {idNumber} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.familyList = res.data?.family || [] | ||||||
|  |           this.dialog = true | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getTableData() | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .psList { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -0,0 +1,34 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AppPartyScoreFlow"> | ||||||
|  |     <component :is="currentPage" v-bind="$props"/> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import PsfList from "./psfList"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "AppPartyScoreFlow", | ||||||
|  |   components: {PsfList}, | ||||||
|  |   label: "积分明细(三涧溪)", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     permissions: Function | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     currentPage() { | ||||||
|  |       return PsfList | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.dict.load("partyIntegralType") | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AppPartyScoreFlow { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										156
									
								
								project/sanjianxi/apps/AppPartyScoreFlow/psfList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								project/sanjianxi/apps/AppPartyScoreFlow/psfList.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="psfList"> | ||||||
|  |     <ai-list> | ||||||
|  |       <ai-title slot="title" title="党员积分明细" isShowBottomBorder/> | ||||||
|  |       <template #content> | ||||||
|  |         <ai-search-bar> | ||||||
|  |           <template #left> | ||||||
|  |             <el-button type="primary" icon="iconfont iconAdd" @click="dialog=true">添加</el-button> | ||||||
|  |             <el-date-picker type="daterange" placeholder="日期" size="small" clearable v-model="createTime" | ||||||
|  |                             @change="handleSearchTime" start-placeholder="开始时间" end-placeholder="结束时间" | ||||||
|  |                             value-format="yyyy-MM-dd HH:mm:ss" :default-time="['00:00:00','23:59:59']"/> | ||||||
|  |           </template> | ||||||
|  |           <template #right> | ||||||
|  |             <el-input size="small" placeholder="搜索党员" v-model="search.partyName" clearable | ||||||
|  |                       @change="page.current=1,getTableData()" suffix-icon="iconfont iconSearch"/> | ||||||
|  |             <ai-import :instance="instance" :dict="dict" importUrl="/appcollectiveeconomyequity/import" url="/appcollectiveeconomyequity/downloadTemplate" name="集体经济组织股权管理信息" @success="getTableData(), $message.success('导入成功!')"> | ||||||
|  |               <el-button size="small">导入</el-button> | ||||||
|  |             </ai-import> | ||||||
|  |           </template> | ||||||
|  |         </ai-search-bar> | ||||||
|  |         <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size" | ||||||
|  |                   @getList="getTableData" :col-configs="colConfigs" :dict="dict"> | ||||||
|  |           <el-table-column slot="options" label="操作" fixed="right" align="center"> | ||||||
|  |             <template slot-scope="{row}"> | ||||||
|  |               <el-button type="text" @click="showDetail(row)">详情</el-button> | ||||||
|  |             </template> | ||||||
|  |           </el-table-column> | ||||||
|  |         </ai-table> | ||||||
|  |       </template> | ||||||
|  |     </ai-list> | ||||||
|  |     <ai-dialog :visible.sync="dialog" title="积分对象" width="600px" @close="form={}" @onConfirm="submit" | ||||||
|  |                :customFooter="!isAdd"> | ||||||
|  |       <el-form v-if="isAdd" :model="form" size="small" ref="DialogForm" :rules="rules" label-width="80px"> | ||||||
|  |         <el-form-item label="选择人员" prop="partyId"> | ||||||
|  |           <ai-select v-model="form.partyId" action="/app/appparty/list" :instance="instance" | ||||||
|  |                      :prop="{label:'name'}"/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <el-form-item label="调整说明" prop="remark"> | ||||||
|  |           <el-input type="textarea" placeholder="请输入" v-model="form.remark" maxlength="100" show-word-limit rows="3" | ||||||
|  |                     clearable/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <el-form-item label="类型" prop="integralType"> | ||||||
|  |           <ai-select v-model="form.integralType" :selectList="dict.getDict('partyIntegralType')"/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <el-form-item label="积分" prop="integral"> | ||||||
|  |           <el-input v-model.number="form.integral" placeholder="请输入正整数" clearable/> | ||||||
|  |         </el-form-item> | ||||||
|  |       </el-form> | ||||||
|  |       <ai-wrapper v-else> | ||||||
|  |         <ai-info-item label="对象" :value="form.partyName"/> | ||||||
|  |         <ai-info-item label="调整说明" :value="form.remark" isLine/> | ||||||
|  |         <ai-info-item label="类型" :value="dict.getLabel('partyIntegralType',form.integralType)"/> | ||||||
|  |         <ai-info-item label="积分" :value="form.integral"/> | ||||||
|  |       </ai-wrapper> | ||||||
|  |     </ai-dialog> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import {mapState} from "vuex"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "psfList", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     ...mapState(['user']), | ||||||
|  |     colConfigs() { | ||||||
|  |       return [ | ||||||
|  |         {label: "对象", prop: "partyName"}, | ||||||
|  |         {label: "调整说明", prop: "remark", align: "center"}, | ||||||
|  |         {label: "时间", prop: "createTime"}, | ||||||
|  |         {label: "类型", prop: "integralType", align: "center", dict: "partyIntegralType"}, | ||||||
|  |         {label: "积分", prop: "integral", align: "center"}, | ||||||
|  |         {slot: "options"} | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     isAdd() { | ||||||
|  |       return !this.form.id | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       search: {}, | ||||||
|  |       page: {current: 1, size: 10, total: 0}, | ||||||
|  |       tableData: [], | ||||||
|  |       dialog: false, | ||||||
|  |       form: {}, | ||||||
|  |       rules: { | ||||||
|  |         partyId: {required: true, message: "请选择人员"}, | ||||||
|  |         remark: {required: true, message: "请输入调整说明"}, | ||||||
|  |         integralType: {required: true, message: "请选择类型"}, | ||||||
|  |         integral: [ | ||||||
|  |           {required: true, message: "请输入分数"}, | ||||||
|  |           {pattern: /^\d+$/g, message: "请输入正整数"} | ||||||
|  |         ], | ||||||
|  |       }, | ||||||
|  |       createTime: "", | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getTableData() { | ||||||
|  |       this.instance.post("/app/apppartyintegralinfo/list", null, { | ||||||
|  |         params: {...this.page, ...this.search} | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.tableData = res.data?.records?.map(e => ({ | ||||||
|  |             ...e, | ||||||
|  |             integral: (e.integralType == 0 ? "-" : '+') + e.integral | ||||||
|  |           })) | ||||||
|  |           this.page.total = res.data.total | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     showDetail(row) { | ||||||
|  |       this.form = JSON.parse(JSON.stringify(row)) | ||||||
|  |       this.dialog = true | ||||||
|  |     }, | ||||||
|  |     submit() { | ||||||
|  |       this.$refs.DialogForm.validate(v => { | ||||||
|  |         if (v) { | ||||||
|  |           let loading = this.$loading({text: "提交中..."}) | ||||||
|  |           this.instance.post("/app/apppartyintegralinfo/addOrUpdate", this.form).then(res => { | ||||||
|  |             loading.close() | ||||||
|  |             if (res?.code == 0) { | ||||||
|  |               this.$message.success("提交成功!") | ||||||
|  |               this.dialog = false | ||||||
|  |               this.getTableData() | ||||||
|  |             } | ||||||
|  |           }).catch(() => loading.close()) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     handleSearchTime(v) { | ||||||
|  |       this.page.current = 1 | ||||||
|  |       this.search.startTime = v?.[0] | ||||||
|  |       this.search.endTime = v?.[1] | ||||||
|  |       this.getTableData() | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getTableData() | ||||||
|  |      | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .psfList { | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										355
									
								
								project/sanjianxi/apps/AppScoreRules/AppScoreRules.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										355
									
								
								project/sanjianxi/apps/AppScoreRules/AppScoreRules.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,355 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AppScoreRules"> | ||||||
|  |     <ai-list v-if="permissions('app_appvillagerintegralrule_detail')"> | ||||||
|  |       <template slot="title"> | ||||||
|  |         <ai-title title="积分规则" isShowBottomBorder></ai-title> | ||||||
|  |       </template> | ||||||
|  |       <template slot="content"> | ||||||
|  |         <ai-search-bar bottomBorder> | ||||||
|  |           <template slot="left"> | ||||||
|  |             <!-- <el-cascader size="small" v-model="search.eventType" placeholder="请选择事件/类型" clearable | ||||||
|  |                          :props="{...etOps,checkStrictly:true}" @change="handleTypeSearch" ref="eventTypeSearch"/> --> | ||||||
|  |             <ai-select | ||||||
|  |                 v-model="search.status" | ||||||
|  |                 @change="page.current = 1, getList()" | ||||||
|  |                 placeholder="请选择状态" | ||||||
|  |                 :selectList="dict.getDict('integralRuleStatus')"> | ||||||
|  |             </ai-select> | ||||||
|  |           </template> | ||||||
|  |           <template slot="right"> | ||||||
|  |             <el-input size="small" placeholder="事件名称" v-model="search.partyName" clearable | ||||||
|  |                       @change="page.current=1,getTableData()" suffix-icon="iconfont iconSearch"/> | ||||||
|  |           </template> | ||||||
|  |         </ai-search-bar> | ||||||
|  |  | ||||||
|  |         <ai-search-bar style="margin-top: 16px;"> | ||||||
|  |           <template #left> | ||||||
|  |             <el-button type="primary" icon="iconfont iconAdd" @click="dialog=true">添加</el-button> | ||||||
|  |           </template> | ||||||
|  |         </ai-search-bar> | ||||||
|  |  | ||||||
|  |         <ai-table | ||||||
|  |             :tableData="tableData" | ||||||
|  |             :col-configs="colConfigs" | ||||||
|  |             :total="page.total" :dict="dict" | ||||||
|  |             :current.sync="page.current" | ||||||
|  |             :size.sync="page.size" | ||||||
|  |             @getList="getList"> | ||||||
|  |           <el-table-column slot="integral" label="分值" align="center"> | ||||||
|  |             <template slot-scope="{ row }"> | ||||||
|  |             <span | ||||||
|  |                 v-if="row.integralValueType == 1"> | ||||||
|  |               {{ row.integralStart > 0 ? '+' + row.integralStart : row.integralStart }} ~ {{ row.integralEnd > 0 ? '+' + row.integralEnd : row.integralEnd }} | ||||||
|  |             </span> | ||||||
|  |               <span v-else>{{ row.integral > 0 ? '+' : '' }}{{ row.integral }}</span> | ||||||
|  |             </template> | ||||||
|  |           </el-table-column> | ||||||
|  |           <el-table-column slot="options" label="操作" align="center" fixed="right" width="200"> | ||||||
|  |             <template slot-scope="{ row }"> | ||||||
|  |               <div class="table-options"> | ||||||
|  |                 <el-button type="text" :disabled="!permissions('app_appvillagerintegralrule_edit')" @click="changeStatus(row.id, 0)" v-if="row.status == 1"> | ||||||
|  |                   停用 | ||||||
|  |                 </el-button> | ||||||
|  |                 <el-button type="text" :disabled="!permissions('app_appvillagerintegralrule_edit')" @click="changeStatus(row.id, 1)" v-else>启用</el-button> | ||||||
|  |                 <el-button type="text" :disabled="!permissions('app_appvillagerintegralrule_edit')" @click="toEdit(row)">编辑</el-button> | ||||||
|  |                 <el-button type="text" :disabled="!permissions('app_appvillagerintegralrule_del')" @click="remove(row.id)">删除</el-button> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </el-table-column> | ||||||
|  |         </ai-table> | ||||||
|  |  | ||||||
|  |       </template> | ||||||
|  |     </ai-list> | ||||||
|  |  | ||||||
|  |     <ai-empty v-else>暂无应用权限</ai-empty> | ||||||
|  |  | ||||||
|  |     <ai-dialog :title="dialogTitle" :visible.sync="dialog" @onConfirm="onConfirm" @closed="form={ladderRule: []}" width="800px"> | ||||||
|  |       <div class="form_div"> | ||||||
|  |         <el-form ref="DialogForm" :model="form" :rules="formRules" size="small" label-suffix=":" label-width="100px"> | ||||||
|  |           <!-- <el-form-item label="事件/类型" prop="eventType"> | ||||||
|  |             <el-cascader v-model="form.eventType" :props="etOps" clearable placeholder="请选择" @change="handleTypeForm" | ||||||
|  |                          :options="cacheOps"/> | ||||||
|  |           </el-form-item> --> | ||||||
|  |           <el-form-item label="事件名称" prop="eventType"> | ||||||
|  |             <el-input v-model="form.name" clearable placeholder="请输入事件名称" type="text" maxlength="30" show-word-limit/> | ||||||
|  |           </el-form-item> | ||||||
|  |           <el-form-item label="简介说明" prop="eventType"> | ||||||
|  |             <el-input v-model="form.name" clearable placeholder="请输入简介说明" type="text" maxlength="100" show-word-limit/> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <el-form-item label="规则" prop="ruleType" required> | ||||||
|  |             <el-radio-group v-model.trim="form.pass" @change="typeChange"> | ||||||
|  |               <el-radio :label="0">常规</el-radio> | ||||||
|  |               <el-radio :label="1">区间</el-radio> | ||||||
|  |               <el-radio :label="2">阶梯</el-radio> | ||||||
|  |             </el-radio-group> | ||||||
|  |           </el-form-item> | ||||||
|  |           <el-form-item label="周期范围" prop="scoringCycle"> | ||||||
|  |             <ai-select v-model="form.scoringCycle" :selectList="dict.getDict('integralRuleScoringCycle')"/> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <el-form-item label="奖励次数"> | ||||||
|  |             <el-input placeholder="请输入,周期范围内,不填写表示不限制" v-model.number="form.numberLimit" clearable/> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <el-form-item label="积分分值" prop="integral" v-if="form.pass == 0"> | ||||||
|  |             <el-input placeholder="请输入" v-model="form.integral" clearable/> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <el-form-item label="积分分值" prop="integral" v-if="form.pass == 1"> | ||||||
|  |             <ai-range v-model="form.num" ref="resetagefoo" /> | ||||||
|  |           </el-form-item> | ||||||
|  |            | ||||||
|  |           <el-form-item label="积分分值" prop="integral" v-if="form.pass == 2"> | ||||||
|  |             <el-button type="text" @click="innerVisible  = true" style="float: right;">添加</el-button> | ||||||
|  |             <ai-table :tableData="integralData" :isShowPagination="false" :col-configs="integralConfigs" :dict="dict"> | ||||||
|  |               <el-table-column slot="options" align="center" label="操作" fixed="right" width="160px"> | ||||||
|  |                 <el-row type="flex" justify="center" align="middle" slot-scope="{row}"> | ||||||
|  |                   <el-button v-if="$permissions('admin_sysuser_distribute')&&!!row.sysUserId" | ||||||
|  |                             type="text" @click="appAllot(row)">删除 | ||||||
|  |                   </el-button> | ||||||
|  |                 </el-row> | ||||||
|  |               </el-table-column> | ||||||
|  |             </ai-table> | ||||||
|  |           </el-form-item> | ||||||
|  |  | ||||||
|  |           <el-dialog width="30%" title="添加积分分值" :visible.sync="innerVisible" append-to-body> | ||||||
|  |             <el-form ref="innerForm" :model="table" :rules="formRules" size="small" label-suffix=":" label-width="100px"> | ||||||
|  |               <el-form-item label="加分项" prop="integral"> | ||||||
|  |                 <el-input placeholder="请输入" v-model="form.integral" clearable/> | ||||||
|  |               </el-form-item> | ||||||
|  |               <el-form-item label="获得积分" prop="integral"> | ||||||
|  |                 <el-input placeholder="请输入" v-model="form.integral" clearable/> | ||||||
|  |               </el-form-item> | ||||||
|  |             </el-form> | ||||||
|  |  | ||||||
|  |             <div slot="footer" class="dialog-footer"> | ||||||
|  |               <el-button @click="innerVisible = false">取 消</el-button> | ||||||
|  |               <el-button type="primary" @click="save">保存</el-button> | ||||||
|  |             </div> | ||||||
|  |           </el-dialog> | ||||||
|  |         </el-form> | ||||||
|  |       </div> | ||||||
|  |  | ||||||
|  |        | ||||||
|  |  | ||||||
|  |     </ai-dialog> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "AppScoreRules", | ||||||
|  |   label: "积分规则(三涧溪)", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: Object, | ||||||
|  |     permissions: Function | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     isEdit() { | ||||||
|  |       return !!this.form.id | ||||||
|  |     }, | ||||||
|  |     dialogTitle() { | ||||||
|  |       return this.isEdit ? "编辑积分规则" : "添加积分规则" | ||||||
|  |     }, | ||||||
|  |     etOps() { | ||||||
|  |       return { | ||||||
|  |         lazy: true, | ||||||
|  |         value: "dictValue", | ||||||
|  |         label: "dictName", | ||||||
|  |         lazyLoad: (node, resolve) => { | ||||||
|  |           if (node.level == 0) resolve(this.dict.getDict('integralRuleEvent')) | ||||||
|  |           else if (node.level == 1) { | ||||||
|  |             let dict = 'integralRuleEvent' + node.value | ||||||
|  |             this.dict.load(dict).then(() => { | ||||||
|  |               let nodes = this.dict.getDict(dict).map(e => ({...e, leaf: true})) | ||||||
|  |               resolve(nodes) | ||||||
|  |             }) | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       search: {status: "", eventType: null}, | ||||||
|  |       page: {current: 1, size: 10, total: 0}, | ||||||
|  |       colConfigs: [ | ||||||
|  |         {prop: "event", label: "事件", dict: "integralRuleEvent"}, | ||||||
|  |         {prop: "type", label: "类型", dict: "integralRuleEventType"}, | ||||||
|  |         {prop: "ruleType", label: "规则", dict: "integralRuleRuleType"}, | ||||||
|  |         {prop: "scoringCycle", label: "周期范围", dict: "integralRuleScoringCycle"}, | ||||||
|  |         {prop: "status", label: "状态", align: "center", width: 96, dict: "integralRuleStatus"}, | ||||||
|  |         {slot: "options", label: "操作", align: "center"}, | ||||||
|  |       ], | ||||||
|  |       integralConfigs: [ | ||||||
|  |         {prop: "event", label: "加分项", dict: "integralRuleEvent"}, | ||||||
|  |         {prop: "event", label: "获得积分", dict: "integralRuleEvent"}, | ||||||
|  |         {slot: "options", label: "操作", align: "center"}, | ||||||
|  |       ], | ||||||
|  |       tableData: [], | ||||||
|  |       dialog: false, | ||||||
|  |       form: { | ||||||
|  |         ladderRule: [], | ||||||
|  |         pass: '0', | ||||||
|  |       }, | ||||||
|  |       formRules: { | ||||||
|  |         eventType: [{required: true, message: "请选择事件/类型", trigger: "change"}], | ||||||
|  |         scoringCycle: [{required: true, message: "请选择周期范围", trigger: "change"}], | ||||||
|  |         integral: [{required: true, pattern: /^\d*[.\d]\d?$/, message: "请输入积分分值,最多保留一位小数"}], | ||||||
|  |         numberLimit: [{pattern: /^\d*$/, message: "请输入正整数"}] | ||||||
|  |       }, | ||||||
|  |       cacheOps: [], | ||||||
|  |       integralFrom: '', | ||||||
|  |       integralTo: '', | ||||||
|  |       integralData: [], | ||||||
|  |       innerVisible: false, | ||||||
|  |       table: {}, | ||||||
|  |        | ||||||
|  |     }; | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.dict.load("integralRuleStatus", "integralRuleRuleType", 'integralRuleScoringCycle', 'integralRuleEvent', 'integralRuleEventType').then(() => { | ||||||
|  |       this.getList(); | ||||||
|  |     }); | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getList() { | ||||||
|  |       this.instance.post(`/app/appvillagerintegralrule/list`, null, { | ||||||
|  |         params: {...this.search, ...this.page}, | ||||||
|  |       }).then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.tableData = res.data.records; | ||||||
|  |           this.page.total = res.data.total; | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |     toEdit(row) { | ||||||
|  |       this.form = this.$copy(row) | ||||||
|  |       let {ladderRule, event, type} = this.form, | ||||||
|  |           dict = 'integralRuleEvent' + event | ||||||
|  |       this.dict.load(dict).then(() => { | ||||||
|  |         this.form.eventType = [event, type] | ||||||
|  |         this.form.ladderRule = JSON.parse(ladderRule || "[]") | ||||||
|  |         this.cacheOps = this.dict.getDict('integralRuleEvent').map(e => { | ||||||
|  |           if (e.dictValue == event) { | ||||||
|  |             e.children = this.dict.getDict(dict).map(d => ({...d, leaf: true})) | ||||||
|  |           } | ||||||
|  |           return e | ||||||
|  |         }) | ||||||
|  |         this.$nextTick(() => { | ||||||
|  |           this.dialog = true | ||||||
|  |         }) | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     // 保存 | ||||||
|  |     save() { | ||||||
|  |       this.$refs.innerForm.validate((valid)=>{ | ||||||
|  |         if (valid) { | ||||||
|  |           this.innerData.push(this.table) | ||||||
|  |         } | ||||||
|  |         this.innerVisible = false | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     typeChange(val) { | ||||||
|  |       this.form.pass = val | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     handleInputFrom(event) { | ||||||
|  |       this.$emit('focusfrom', event) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     handleInputTo(event) { | ||||||
|  |       this.$emit('blurto', event) | ||||||
|  |     }, | ||||||
|  |  | ||||||
|  |     remove(id) { | ||||||
|  |       this.$confirm("删除后不可恢复,是否要删除该事项?", { | ||||||
|  |         type: 'error' | ||||||
|  |       }).then(() => { | ||||||
|  |         this.instance | ||||||
|  |         .post(`/app/appvillagerintegralrule/delete?ids=${id}`) | ||||||
|  |         .then((res) => { | ||||||
|  |           if (res.code == 0) { | ||||||
|  |             this.$message.success("删除成功!"); | ||||||
|  |             this.getList(); | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |     changeStatus(id, status) { | ||||||
|  |       let text = status == 1 ? '启用' : '停用' | ||||||
|  |       this.$confirm(`确定${text}该条规则?`).then(() => { | ||||||
|  |         this.instance.post(`/app/appvillagerintegralrule/enableOrDisable?id=${id}`).then((res) => { | ||||||
|  |           if (res.code == 0) { | ||||||
|  |             this.$message.success(`${text}成功!`) | ||||||
|  |             this.getList(); | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |     onReset() { | ||||||
|  |       this.page.current = 1 | ||||||
|  |       this.search.classification = "" | ||||||
|  |       this.search.integralType = "" | ||||||
|  |       this.search.ruleStatus = "" | ||||||
|  |       this.getList(); | ||||||
|  |     }, | ||||||
|  |     onConfirm() { | ||||||
|  |       if(this.form.ruleType==1 && !this.form.ladderRule.length) { | ||||||
|  |         return this.$message.error('请添加规则') | ||||||
|  |       } | ||||||
|  |       this.$refs.DialogForm.validate((valid) => { | ||||||
|  |         if (valid) { | ||||||
|  |           let formData = this.$copy(this.form) | ||||||
|  |           formData.ladderRule = JSON.stringify(formData.ladderRule) | ||||||
|  |           formData.integral = formData.integral || 0 | ||||||
|  |           this.instance.post(`/app/appvillagerintegralrule/addOrUpdate`, formData).then((res) => { | ||||||
|  |             if (res.code == 0) { | ||||||
|  |               this.$message.success(`${this.isEdit ? '编辑成功' : '添加成功'}`) | ||||||
|  |               this.onReset() | ||||||
|  |               this.dialog = false; | ||||||
|  |             } | ||||||
|  |           }); | ||||||
|  |         } else { | ||||||
|  |           return false; | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |     handleTypeSearch(v) { | ||||||
|  |       this.search.event = v?.[0] | ||||||
|  |       this.search.type = v?.[1] | ||||||
|  |       this.page.current = 1 | ||||||
|  |       this.$refs.eventTypeSearch.dropDownVisible = false | ||||||
|  |       this.getList() | ||||||
|  |     }, | ||||||
|  |     handleTypeForm(v) { | ||||||
|  |       if (this.dialog) { | ||||||
|  |         this.form.event = v?.[0] | ||||||
|  |         this.form.type = v?.[1] | ||||||
|  |         this.form.ruleType = !this.form.event ? null : this.form.event == 3 ? 1 : 0 | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     handleDelete(i) { | ||||||
|  |       this.$confirm("是否要删除该规则?").then(() => { | ||||||
|  |         this.form.ladderRule.splice(i, 1) | ||||||
|  |       }).catch(() => 0) | ||||||
|  |     }, | ||||||
|  |     checkIntegral(v) { | ||||||
|  |       return /\.\d{2,}$/.test(v) ? Math.abs(v).toFixed(1) : Math.abs(v) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AppScoreRules { | ||||||
|  |   height: 100%; | ||||||
|  |   background: #f3f6f9; | ||||||
|  |  | ||||||
|  |    | ||||||
|  |  | ||||||
|  | } | ||||||
|  | </style> | ||||||
		Reference in New Issue
	
	Block a user