2025-10-09 18:29:28 +08:00

293 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<x-search-bar class="mb-8-2">
<template #default="{ gutter, colSpan }">
<a-form :label-col="{ style: { width: '100px' } }" :model="searchFormData" layout="inline">
<a-row :gutter="gutter">
<a-col v-bind="colSpan">
<a-form-item :label="'站点名称'" name="name">
<a-input :placeholder="'请输入站点名称'" v-model:value="searchFormData.name"></a-input>
</a-form-item>
</a-col>
<a-col v-bind="colSpan">
<a-form-item :label="'站点类型'" name="name">
<a-select ref="select" v-model:value="searchFormData.name" @focus="focus"
@change="handleChange">
<a-select-option value="jack">已结单</a-select-option>
<a-select-option value="lucy">已作废</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col v-bind="colSpan">
<a-form-item :label="'所在区域'" name="name">
<a-input :placeholder="'请选择区域'" v-model:value="searchFormData.name"></a-input>
</a-form-item>
</a-col>
<a-col v-bind="colSpan">
<a-form-item :label="'所在节点'" name="name">
<a-select ref="select" v-model:value="searchFormData.name" @focus="focus"
@change="handleChange">
<a-select-option value="jack">已结单</a-select-option>
<a-select-option value="lucy">已作废</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col v-bind="colSpan" style="text-align: right;">
<a-space>
<a-button @click="handleResetSearch">{{ $t('button.reset') }}</a-button>
<a-button ghost type="primary" @click="handleSearch">
{{ $t('button.search') }}
</a-button>
</a-space>
</a-col>
</a-row>
</a-form>
</template>
</x-search-bar>
<a-card>
<!-- 添加标题和横线 -->
<div class="title-container">
<h3>服务站点列表</h3>
<div class="title-line"></div>
</div>
<x-action-bar class="mb-8-2">
<!-- 增加按钮之间的间距 -->
<a-space :size="12">
<a-button v-action="'add'" type="primary" @click="$refs.editDialogRef.handleCreate()">
新建
</a-button>
<a-button v-action="'add'" type="primary" @click="$refs.editDialogRef.handleCreate()">
导入
</a-button>
<a-button v-action="'add'" type="primary" @click="$refs.editDialogRef.handleCreate()">
<template #icon>
<UnorderedListOutlined />
</template>
导入记录
</a-button>
<a-button v-action="'add'" type="primary" @click="$refs.editDialogRef.handleCreate()">
导出
</a-button>
<a-button v-action="'add'" type="primary" @click="$refs.editDialogRef.handleCreate()">
<template #icon>
<UnorderedListOutlined />
</template>
导出记录
</a-button>
</a-space>
</x-action-bar>
<a-table rowKey="id" :loading="loading" :pagination="true" :columns="columns" :data-source="listData">
<template #bodyCell="{ column, record }">
<template v-if="'menuType' === column.key">
<!--菜单-->
<a-tag v-if="menuTypeEnum.is('page', record.type)" color="processing">
{{ menuTypeEnum.getDesc(record.type) }}
</a-tag>
<!--按钮-->
<a-tag v-if="menuTypeEnum.is('button', record.type)" color="success">
{{ menuTypeEnum.getDesc(record.type) }}
</a-tag>
</template>
<template v-if="'createAt' === column.key">
{{ formatUtcDateTime(record.created_at) }}
</template>
<template v-if="'statusType' === column.key">
<!--状态-->
<a-tag v-if="statusTypeEnum.is('enabled', record.status)" color="processing">
{{ statusTypeEnum.getDesc(record.status) }}
</a-tag>
<!--状态-->
<a-tag v-if="statusTypeEnum.is('disabled', record.status)" color="processing">
{{ statusTypeEnum.getDesc(record.status) }}
</a-tag>
</template>
<template v-if="'action' === column.key">
<x-action-button @click="$refs.editDialogRef.handleEdit(record)">
<a-tooltip>
<template #title>{{ $t('pages.system.menu.edit') }}</template>
<edit-outlined />
</a-tooltip>
</x-action-button>
<x-action-button @click="$refs.editDialogRef.handleCreateChild(record)">
<a-tooltip>
<template #title>{{ $t('pages.system.menu.button.addChild') }}</template>
<plus-circle-outlined />
</a-tooltip>
</x-action-button>
<x-action-button @click="handleDelete(record)">
<a-tooltip>
<template #title>{{ $t('pages.system.delete') }}</template>
<delete-outlined style="color: #ff4d4f" />
</a-tooltip>
</x-action-button>
</template>
</template>
</a-table>
</a-card>
<edit-dialog @ok="onOk" ref="editDialogRef" />
</template>
<script setup>
import { Modal, message } from 'ant-design-vue'
import { ref } from 'vue'
import { UnorderedListOutlined } from '@ant-design/icons-vue'
import apis from '@/apis'
import { config } from '@/config'
import { menuTypeEnum, statusTypeEnum } from '@/enums/system'
import { usePagination, useForm } from '@/hooks'
import { formatUtcDateTime } from '@/utils/util'
import EditDialog from './components/EditDialog.vue'
import { useI18n } from 'vue-i18n'
import storage from '@/utils/storage'
defineOptions({
// eslint-disable-next-line vue/no-reserved-component-names
name: 'menu',
})
const { t } = useI18n() // 解构出t方法
const columns = ref([
{ title: '工单号', dataIndex: 'name', key: 'name', fixed: true, width: 280 },
{ title: '服务对象', dataIndex: 'code', key: 'code', width: 240 },
{ title: '身份证号', dataIndex: 'type', key: 'menuType', width: 240 },
{ title: '联系方式1', dataIndex: 'status', key: 'statusType', width: 240 },
{ title: '联系方式2', dataIndex: 'sequence', width: 240 },
{ title: '计划服务时间', dataIndex: 'created_at', key: 'createAt', width: 240 },
{ title: '计划服务时常(分钟)', dataIndex: 'created_at', key: 'createAt', width: 240 },
{ title: '服务项目', dataIndex: 'created_at', key: 'createAt', width: 240 },
{ title: '所属区域', dataIndex: 'created_at', key: 'createAt', width: 240 },
{ title: '服务地址', dataIndex: 'created_at', key: 'createAt', width: 240 },
{ title: '服务组织', dataIndex: 'created_at', key: 'createAt', width: 240 },
{ title: '服务人员', dataIndex: 'created_at', key: 'createAt', width: 240 },
{ title: '下单员', dataIndex: 'created_at', key: 'createAt', width: 240 },
{ title: '下单时间', dataIndex: 'created_at', key: 'createAt', width: 240 },
])
const { listData, loading, showLoading, hideLoading, searchFormData, paginationState, resetPagination } =
usePagination()
const { resetForm } = useForm()
const editDialogRef = ref()
getMenuList()
/**
* 获取菜单列表
* @return {Promise<void>}
*/
async function getMenuList() {
try {
showLoading()
// const { current } = paginationState
const platform = storage.local.getItem('platform')
const { data, success, total } = await apis.menu
.getMenuList({
...searchFormData.value,
platform
})
.catch(() => {
throw new Error()
})
hideLoading()
if (config('http.code.success') === success) {
data.forEach((item) => {
item.name = t(item.code) || item.name
})
listData.value = data
paginationState.total = total
}
} catch (error) {
hideLoading()
}
}
/**
* 搜索
*/
function handleSearch() {
// resetForm()
resetPagination()
getMenuList()
}
/**
* 重置
*/
function handleResetSearch() {
searchFormData.value = {}
resetPagination()
getMenuList()
}
/**
* 删除
* @param id
*/
function handleDelete({ id }) {
Modal.confirm({
title: t('pages.system.menu.delTip'),
content: t('button.confirm'),
okText: t('button.confirm'),
onOk: () => {
return new Promise((resolve, reject) => {
; (async () => {
try {
const { success } = await apis.menu.delMenu(id).catch(() => {
throw new Error()
})
if (config('http.code.success') === success) {
resolve()
message.success(t('component.message.success.delete'))
await getMenuList()
}
} catch (error) {
reject()
}
})()
})
},
})
}
/**
* 编辑完成
*/
async function onOk() {
await getMenuList()
}
</script>
<style lang="less" scoped>
// 标题和横线样式
.title-container {
margin-bottom: 16px;
}
.title-line {
height: 1px;
width: 100%;
background-color: #e8e8e8; // 灰色横线
margin-top: 8px;
}
// 按钮间距已经通过a-space的size属性设置这里可以作为备选方案
// :deep(.ant-btn) {
// margin-right: 8px;
// &:last-child {
// margin-right: 0;
// }
// }
</style>