Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
H
hxyj-admin-fe
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hxyj
hxyj-admin-fe
Commits
f17ace8d
Commit
f17ace8d
authored
Jun 11, 2025
by
Jstar Xu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 城市管理页面ui初始化
parent
b8f87e2a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
368 additions
and
4 deletions
+368
-4
navbar.vue
src/layout/components/navbar/navbar.vue
+15
-4
city-management.ts
src/router/modules/city-management.ts
+26
-0
useTableCrud.ts
src/utils/hook/useTableCrud.ts
+159
-0
city-management.vue
src/views/city-management/city-management.vue
+101
-0
city-edit-dialog.vue
src/views/city-management/components/city-edit-dialog.vue
+67
-0
No files found.
src/layout/components/navbar/navbar.vue
View file @
f17ace8d
<
script
setup
lang=
"ts"
>
import
{
useDesignSettingStore
}
from
'@/store/modules/design-setting'
import
{
useUserStore
}
from
'@/store/modules/user'
import
{
readonly
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
import
{
readonly
,
computed
}
from
'vue'
import
{
useRouter
,
useRoute
}
from
'vue-router'
import
{
ExpandRight
,
ExpandLeft
}
from
'@icon-park/vue-next'
const
defaultAvatar
=
'https://mkp-dev.oss-cn-shenzhen.aliyuncs.com/game-template/20221018/1666079174947.png'
...
...
@@ -10,7 +10,7 @@ const defaultAvatar = 'https://mkp-dev.oss-cn-shenzhen.aliyuncs.com/game-templat
const
designSettingStore
=
useDesignSettingStore
()
const
userStore
=
useUserStore
()
const
router
=
useRouter
()
// const currentR
oute = useRoute()
const
r
oute
=
useRoute
()
const
menuOptions
=
readonly
([
{
...
...
@@ -35,7 +35,13 @@ function onDropdownSelect(key: number) {
})
}
}
const
breadcrumbs
=
computed
(()
=>
{
const
matchedRoutes
=
route
.
matched
.
filter
((
item
)
=>
item
.
meta
&&
item
.
meta
.
title
)
return
matchedRoutes
.
map
((
item
)
=>
({
path
:
item
.
path
,
title
:
item
.
meta
.
title
,
}))
})
// function handleRefreshPage() {
// router.replace({ path: currentRoute.fullPath })
// }
...
...
@@ -64,6 +70,11 @@ function onDropdownSelect(key: number) {
:stroke-width=
"3"
@
click=
"handleSidebarDisplayStatusChange('collapse')"
/>
<el-breadcrumb
class=
"ml-3"
>
<el-breadcrumb-item
v-for=
"(breadcrumb, index) in breadcrumbs"
:key=
"index"
:to=
"
{ path: breadcrumb.path }">
<el-text>
{{
breadcrumb
.
title
}}
</el-text>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
</div>
<div
class=
"mr-5 flex sm:mr-6"
>
...
...
src/router/modules/city-management.ts
0 → 100644
View file @
f17ace8d
import
{
type
RouteRecordRaw
}
from
'vue-router'
import
Layout
from
'@/layout/index.vue'
export
default
[
{
path
:
'/city-management'
,
meta
:
{
rank
:
1001
,
title
:
'城市管理'
,
icon
:
'icon-city'
,
},
component
:
Layout
,
children
:
[
{
path
:
''
,
name
:
'CityManagement'
,
meta
:
{
rank
:
1001
,
title
:
'列表'
,
hideSideMenItem
:
true
,
},
component
:
()
=>
import
(
'@/views/city-management/city-management.vue'
),
},
],
},
]
as
RouteRecordRaw
[]
src/utils/hook/useTableCrud.ts
0 → 100644
View file @
f17ace8d
import
{
reactive
,
ref
}
from
'vue'
type
Actions
=
'edit'
|
'create'
|
'view'
|
'del'
const
ACTIONSCN
=
{
view
:
'查看'
,
edit
:
'编辑'
,
create
:
'新增'
,
del
:
'删除'
,
}
export
function
useForm
(
initFormData
=
{})
{
const
formRef
=
ref
<
any
>
(
null
)
const
formModel
=
ref
({
...
initFormData
})
// const rules = {
// required: {
// required: true,
// message: '此为必填项',
// trigger: ['blur', 'change'],
// },
// }
const
validation
=
async
()
=>
{
return
formRef
.
value
.
validate
()
}
return
[
formRef
,
formModel
,
validation
]
as
const
}
export
function
useModal
()
{
const
options
=
reactive
({
visible
:
false
,
title
:
''
,
callback
:
()
=>
{},
loading
:
false
,
})
return
options
}
export
function
useTableCrud
({
name
,
actions
:
{
create
,
read
,
update
,
del
},
initForm
,
}:
{
name
:
string
actions
:
{
read
?:
(
params
:
any
)
=>
any
create
?:
(
params
:
any
)
=>
any
update
?:
(
params
:
any
)
=>
any
del
?:
(
params
:
any
)
=>
any
}
initForm
?:
any
})
{
const
modalAction
=
ref
(
''
)
const
modelOptions
=
useModal
()
const
[
modalFormRef
,
modalForm
,
validation
]
=
useForm
(
initForm
)
/** 新增 */
function
handleAdd
(
row
:
any
=
{})
{
handleOpen
({
action
:
'create'
,
row
:
Object
.
assign
({},
{
...
initForm
},
{
...
row
})
})
}
/** 修改 */
function
handleEdit
(
row
:
any
)
{
handleOpen
({
action
:
'edit'
,
row
})
}
/** 查看 */
function
handleView
(
row
:
any
)
{
handleOpen
({
action
:
'view'
,
row
})
}
/** 打开modal */
function
handleOpen
(
options
=
{}
as
{
title
?:
string
;
action
:
Actions
;
row
?:
any
;
onOk
?:
()
=>
Promise
<
any
>
})
{
const
{
action
,
row
,
onOk
,
title
}
=
options
modalAction
.
value
=
action
modalForm
.
value
=
{
...
row
}
// console.log(modalRef.value)
modelOptions
.
visible
=
true
modelOptions
.
title
=
title
||
ACTIONSCN
[
action
]
+
name
modelOptions
.
callback
=
async
()
=>
{
if
(
typeof
onOk
===
'function'
)
{
return
await
onOk
()
}
else
{
return
await
handleSave
(
action
)
}
}
}
/** 保存 */
async
function
handleSave
(
action
:
Actions
)
{
if
(
!
action
&&
!
[
'edit'
,
'add'
].
includes
(
modalAction
.
value
))
{
return
false
}
await
validation
()
const
actions
=
{
create
:
{
api
:
()
=>
create
?.(
modalForm
.
value
),
cb
:
()
=>
ElMessage
.
success
(
'新增成功'
),
},
edit
:
{
api
:
()
=>
update
?.(
modalForm
.
value
),
cb
:
()
=>
ElMessage
.
success
(
'保存成功'
),
},
}
const
currentAction
=
actions
[
modalAction
.
value
as
keyof
typeof
actions
]
try
{
modelOptions
.
loading
=
true
const
data
=
await
currentAction
.
api
()
currentAction
.
cb
()
modelOptions
.
loading
=
false
if
(
data
&&
read
)
read
(
data
)
}
catch
(
error
)
{
console
.
error
(
error
)
modelOptions
.
loading
=
false
return
false
}
}
/** 删除 */
function
handleDelete
(
id
:
string
|
number
,
confirmOptions
=
{})
{
if
(
!
id
&&
id
!==
0
)
return
ElMessageBox
.
confirm
(
'确定删除?'
,
'警告'
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
beforeClose
:
async
(
action
,
instance
,
done
)
=>
{
if
(
action
===
'confirm'
)
{
try
{
instance
.
confirmButtonLoading
=
true
const
data
=
await
del
?.(
id
)
ElMessage
.
success
(
'删除成功'
)
instance
.
confirmButtonLoading
=
false
read
?.(
data
)
}
catch
(
error
)
{
console
.
error
(
error
)
instance
.
confirmButtonLoading
=
false
}
done
()
}
else
{
done
()
}
},
...
confirmOptions
,
})
}
return
{
modal
:
modelOptions
,
modalFormRef
,
modalAction
,
modalForm
,
validation
,
handleAdd
,
handleDelete
,
handleEdit
,
handleView
,
handleOpen
,
handleSave
,
}
}
src/views/city-management/city-management.vue
0 → 100644
View file @
f17ace8d
<
script
setup
lang=
"ts"
>
import
{
Search
}
from
'@icon-park/vue-next'
import
{
ref
,
useTemplateRef
,
watchEffect
}
from
'vue'
import
GeneralTableLayout
from
'@/components/general-table-layout.vue'
import
CityEditDialog
from
'./components/city-edit-dialog.vue'
import
{
useTableCrud
}
from
'@/utils/hook/useTableCrud'
const
searchKeyword
=
ref
(
''
)
const
paginationConfig
=
ref
({
currentPage
:
1
,
pageSize
:
10
,
total
:
40
,
})
const
curdDialogRef
=
useTemplateRef
(
'curdDialogRef'
)
const
tableData
=
ref
([
{
id
:
1
,
title
:
'广州'
,
status
:
'状态'
,
short
:
'GZ'
,
remark
:
'备注信息'
,
date
:
'2016-05-03'
,
},
])
watchEffect
(()
=>
{
if
(
curdDialogRef
.
value
)
{
modalFormRef
.
value
=
curdDialogRef
.
value
.
formRef
}
})
const
{
modal
,
modalFormRef
,
modalForm
,
handleAdd
,
handleDelete
,
handleEdit
}
=
useTableCrud
({
name
:
'城市'
,
actions
:
{
create
:
(
e
)
=>
{
console
.
log
(
e
)
// modal.visible = false
},
read
:
(
e
)
=>
{
console
.
log
(
e
)
},
update
:
(
e
)
=>
{
console
.
log
(
e
)
},
del
:
(
e
)
=>
{
console
.
log
(
e
)
},
},
initForm
:
{
status
:
true
,
},
})
</
script
>
<
template
>
<GeneralTableLayout
v-model:pagination-config=
"paginationConfig"
>
<template
#
header
>
<div>
<el-input
v-model=
"searchKeyword"
style=
"width: 240px"
placeholder=
"请输入想要搜索的内容"
>
<template
#
suffix
>
<Search
theme=
"outline"
size=
"16"
fill=
"#333"
:stroke-width=
"3"
/>
</
template
>
</el-input>
</div>
<div
class=
"ml-[20px]"
>
<el-button
type=
"primary"
plain
>
查询
</el-button>
<el-button
type=
"danger"
plain
>
重置
</el-button>
</div>
<div
class=
"ml-auto"
>
<el-button
type=
"primary"
@
click=
"handleAdd()"
>
新增
</el-button>
</div>
</template>
<el-table
:data=
"tableData"
row-key=
"id"
border
class=
"w-full"
>
<el-table-column
type=
"index"
width=
"50"
/>
<el-table-column
prop=
"short"
label=
"首字母"
width=
"80"
/>
<el-table-column
prop=
"title"
label=
"城市名"
width=
"230"
/>
<el-table-column
prop=
"status"
label=
"状态"
width=
"180"
>
<
template
#
default=
"{ row }"
>
<el-switch
v-model=
"row.status"
></el-switch>
</
template
>
</el-table-column>
<el-table-column
prop=
"remark"
label=
"备注"
/>
<el-table-column
label=
"操作"
>
<
template
#
default=
"{ row }"
>
<el-button
type=
"primary"
text
bg
@
click=
"handleEdit(row)"
>
编辑
</el-button>
<el-button
type=
"danger"
text
bg
@
click=
"handleDelete(row.id)"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
</GeneralTableLayout>
<CityEditDialog
ref=
"curdDialogRef"
v-model:dialog-visible=
"modal.visible"
v-model:form-data=
"modalForm"
:modal-options=
"{ title: modal.title, callback: modal.callback, loading: modal.loading }"
/>
</template>
src/views/city-management/components/city-edit-dialog.vue
0 → 100644
View file @
f17ace8d
<
script
setup
lang=
"ts"
>
import
{
useTemplateRef
,
reactive
}
from
'vue'
import
type
{
FormRules
}
from
'element-plus'
interface
Props
{
modalOptions
:
{
title
:
string
callback
:
()
=>
void
loading
:
boolean
}
}
defineProps
<
Props
>
()
const
dialogVisible
=
defineModel
<
boolean
>
(
'dialogVisible'
,
{
default
:
false
})
const
formData
=
defineModel
<
any
>
(
'formData'
,
{
default
:
{}
})
const
formRef
=
useTemplateRef
(
'formRef'
)
const
rules
=
reactive
<
FormRules
<
{
title
:
string
;
short
:
string
;
status
:
string
;
remark
:
string
}
>>
({
title
:
[{
required
:
true
,
message
:
'请输入城市名称'
,
trigger
:
'blur'
}],
short
:
[{
required
:
true
,
message
:
'请输入城市名称缩写'
,
trigger
:
'blur'
}],
// status: [{ message: '请选择状态', trigger: 'blur' }],
// remark: [{ message: '请输入备注信息', trigger: 'blur' }],
})
defineExpose
({
formRef
})
</
script
>
<
template
>
<el-dialog
v-model=
"dialogVisible"
:title=
"modalOptions.title"
width=
"670"
@
close=
"
() =>
{
formRef?.resetFields()
}
"
>
<el-form
ref=
"formRef"
status-icon
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
style=
"width: 70%"
>
<el-form-item
label=
"城市名称"
prop=
"title"
>
<el-input
v-model=
"formData.title"
/>
</el-form-item>
<el-form-item
label=
"城市名称缩写"
prop=
"short"
>
<el-input
v-model=
"formData.short"
/>
</el-form-item>
<el-form-item
label=
"状态"
>
<el-switch
v-model=
"formData.status"
/>
</el-form-item>
<el-form-item
label=
"备注"
prop=
"remark"
>
<el-input
v-model=
"formData.remark"
:autosize=
"
{ minRows: 3 }" type="textarea" />
</el-form-item>
</el-form>
<template
#
footer
>
<el-button
:loading=
"modalOptions.loading"
type=
"primary"
@
click=
"
() =>
{
// console.log( modalOptions.callback)
modalOptions.callback()
}
"
>提交
</el-button
>
</
template
>
</el-dialog>
</template>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment