Area.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <script lang="ts" setup>
  2. import PaneModel from '@/components/splitpanes/PaneModel.vue'
  3. import { ElTree } from 'element-plus'
  4. import type { BasicForm, ICRUD } from '@/types/form'
  5. import { getAreaList } from '@/api/area'
  6. interface Tree {
  7. id: number
  8. label: string
  9. children?: Tree[]
  10. icon?: string
  11. }
  12. const config = {
  13. size: 20,
  14. lMinSize: 20
  15. }
  16. const filterText = ref('')
  17. const treeRef = ref<InstanceType<typeof ElTree>>()
  18. const defaultProps = {
  19. children: 'children',
  20. label: 'label'
  21. }
  22. const data = ref<any>([])
  23. getAreaList().then((res: any) => {
  24. data.value = res
  25. })
  26. const dialogVisible = ref(false)
  27. const areaType = ref([
  28. { label: '国家', value: 1 },
  29. { label: '省份、直辖市', value: 2 },
  30. { label: '地市', value: 3 },
  31. { label: '区县', value: 4 }
  32. ])
  33. watch(filterText, val => {
  34. treeRef.value?.filter(val)
  35. })
  36. const filterNode = (value: string, data: any) => {
  37. if (!value) return true
  38. return data.label.includes(value)
  39. }
  40. const menuId = ref('')
  41. const handleNodeClick = (val: any) => {
  42. console.log(val)
  43. formData.name = val.label
  44. formData.encoded = val.id
  45. formData.type = 2
  46. menuId.value = val.id
  47. }
  48. const create = (data: any) => {
  49. console.log(data)
  50. }
  51. const update = (data: any) => {
  52. console.log(data)
  53. }
  54. const formData = reactive<any>({})
  55. const formConfig = reactive<BasicForm>({
  56. span: 24,
  57. formItems: [
  58. {
  59. label: '区域名称',
  60. value: '',
  61. name: 'name',
  62. type: 'input',
  63. rules: [{ required: true, message: '请输入区域名称', trigger: 'blur' }]
  64. },
  65. {
  66. label: '区域编码',
  67. value: '',
  68. name: 'encoded',
  69. type: 'input'
  70. },
  71. {
  72. label: '区域类型',
  73. value: '',
  74. name: 'type',
  75. type: 'select',
  76. options: areaType.value
  77. }
  78. ]
  79. })
  80. const ruleFormRef = ref()
  81. const ruleForm = ref({
  82. id: '',
  83. type: 1,
  84. encoded: '',
  85. name: ''
  86. })
  87. const addArea = () => {
  88. dialogVisible.value = true
  89. }
  90. const submitForm = (data: any) => {
  91. dialogVisible.value = false
  92. }
  93. const resetForm = (data: any) => {
  94. dialogVisible.value = false
  95. }
  96. </script>
  97. <template>
  98. <PaneModel :config="config">
  99. <template #left>
  100. <el-card class="left">
  101. <el-container>
  102. <el-header>
  103. <el-input v-model="filterText" placeholder="输入关键字进行过滤" />
  104. </el-header>
  105. <el-main>
  106. <el-tree
  107. ref="treeRef"
  108. class="filter-tree"
  109. :data="data"
  110. :expand-on-click-node="false"
  111. :props="defaultProps"
  112. :filter-node-method="filterNode"
  113. show-checkbox
  114. @node-click="handleNodeClick"
  115. >
  116. </el-tree>
  117. </el-main>
  118. <el-footer>
  119. <el-button icon="plus" type="primary" size="small" @click="addArea"></el-button>
  120. <el-button icon="delete" type="danger" size="small"></el-button>
  121. <el-button icon="refresh" size="small"></el-button>
  122. </el-footer>
  123. </el-container>
  124. </el-card>
  125. </template>
  126. <template #right>
  127. <el-empty
  128. v-if="menuId == ''"
  129. description="请选择左侧菜单后操作"
  130. image="http://cloud.jeeplus.org/assets/empty.066d9fc7.svg"
  131. />
  132. <el-card>
  133. <template #header>
  134. <span>{{ formData.name }}</span>
  135. </template>
  136. <pro-form
  137. class="form-wrap"
  138. :formConfig="formConfig"
  139. :formData="formData"
  140. ref="proFormRef"
  141. :update="update"
  142. :create="create"
  143. >
  144. </pro-form>
  145. <div class="text-center">
  146. <el-button type="primary">保存</el-button>
  147. </div>
  148. </el-card>
  149. </template>
  150. </PaneModel>
  151. <el-dialog v-model="dialogVisible" title="新增" width="" destroy-on-close>
  152. <el-form
  153. ref="ruleFormRef"
  154. :model="ruleForm"
  155. label-position="right"
  156. label-width="100px"
  157. class="demo-ruleForm"
  158. status-icon
  159. size="large"
  160. >
  161. <div class="grid grid-cols-2 justify-items-center items-center gap-y-{20px}">
  162. <el-form-item class="w-full items-center" label="区域名称" prop="name">
  163. <el-input v-model="ruleForm.name" placeholder="请输入区域名称" />
  164. </el-form-item>
  165. <el-form-item class="w-full items-center" label="区域编码" prop="name">
  166. <el-input v-model="ruleForm.encoded" placeholder="请输入区域编码" />
  167. </el-form-item>
  168. <el-form-item class="w-full items-center" label="上级区域">
  169. <el-tree-select
  170. v-model="ruleForm.id"
  171. :data="[]"
  172. value-key="id"
  173. :props="defaultProps"
  174. :render-after-expand="false"
  175. check-strictly
  176. />
  177. </el-form-item>
  178. <el-form-item class="w-full items-center" label="区域类型">
  179. <el-select v-model="ruleForm.type" clearable filterable placeholder="请选择区域类型">
  180. <el-option v-for="item in areaType" :key="item.value" :label="item.label" :value="item.value" />
  181. </el-select>
  182. </el-form-item>
  183. </div>
  184. </el-form>
  185. <template #footer>
  186. <div class="flex justify-end w-full">
  187. <el-button size="default" @click="resetForm(ruleFormRef)">取消</el-button>
  188. <el-button size="default" type="primary" @click="submitForm(ruleFormRef)">确认</el-button>
  189. </div>
  190. </template>
  191. </el-dialog>
  192. </template>
  193. <style lang="scss" scoped>
  194. :deep(.splitpanes__splitter) {
  195. background: transparent !important;
  196. }
  197. .el-container {
  198. height: 100%;
  199. }
  200. .card-header {
  201. padding-bottom: 14px;
  202. border-bottom: 1px solid var(--el-card-border-color);
  203. box-sizing: border-box;
  204. margin-top: -2px;
  205. margin-bottom: 16px;
  206. }
  207. .right {
  208. height: 100%;
  209. :deep(.el-card__body) {
  210. height: 100%;
  211. }
  212. .form-wrap {
  213. padding-right: 20px;
  214. }
  215. }
  216. .el-empty {
  217. height: 100%;
  218. background-color: #fff;
  219. }
  220. .form-scoll {
  221. :deep(.el-card__body) {
  222. overflow: auto;
  223. }
  224. }
  225. :deep(.splitpanes__pane) {
  226. background-color: #fff;
  227. }
  228. .left {
  229. height: 100%;
  230. :deep(.el-tree-node__content) {
  231. height: 36px;
  232. }
  233. .custom-tree-node {
  234. display: flex;
  235. align-items: center;
  236. span {
  237. margin-left: 5px;
  238. }
  239. }
  240. .el-header {
  241. border-bottom: 1px solid #e6e6e6;
  242. display: flex;
  243. justify-content: space-between;
  244. align-items: center;
  245. height: 53px;
  246. }
  247. :deep(.el-card__body) {
  248. padding: 0;
  249. height: 100%;
  250. }
  251. .el-main {
  252. overflow: auto;
  253. flex: 1;
  254. flex-basis: 100%;
  255. }
  256. .el-footer {
  257. border-top: 1px solid #e6e6e6;
  258. display: flex;
  259. align-items: center;
  260. }
  261. }
  262. </style>