Area.vue 6.2 KB

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