1.优化工作台页面/dashboard/console
2.移除岗位管理相关代码和数据库
This commit is contained in:
@@ -52,6 +52,16 @@ export interface NewPlayerItem {
|
||||
name: string
|
||||
coin: number
|
||||
total_ticket_count: number
|
||||
create_time: string
|
||||
}
|
||||
|
||||
/** 玩家游玩记录项 */
|
||||
export interface PlayRecordItem {
|
||||
player_name: string
|
||||
reward_tier: string
|
||||
reward_tier_label: string
|
||||
win_coin: number
|
||||
create_time: string
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,3 +74,13 @@ export function fetchNewPlayerList() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 工作台-玩家游玩记录(最新50条)
|
||||
* @returns 列表
|
||||
*/
|
||||
export function fetchPlayRecordList() {
|
||||
return request.get<PlayRecordItem[]>({
|
||||
url: '/core/dice/dashboard/playRecordList'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
import request from '@/utils/http'
|
||||
|
||||
/**
|
||||
* 岗位API
|
||||
*/
|
||||
export default {
|
||||
/**
|
||||
* 获取数据列表
|
||||
* @param params 搜索参数
|
||||
* @returns 数据列表
|
||||
*/
|
||||
list(params: Record<string, any>) {
|
||||
return request.get<Api.Common.ApiPage>({
|
||||
url: '/core/post/index',
|
||||
params
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 读取数据
|
||||
* @param id 数据ID
|
||||
* @returns 数据详情
|
||||
*/
|
||||
read(id: number | string) {
|
||||
return request.get<Api.Common.ApiData>({
|
||||
url: '/core/post/read?id=' + id
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 创建数据
|
||||
* @param params 数据参数
|
||||
* @returns 执行结果
|
||||
*/
|
||||
save(params: Record<string, any>) {
|
||||
return request.post<any>({
|
||||
url: '/core/post/save',
|
||||
data: params
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新数据
|
||||
* @param params 数据参数
|
||||
* @returns 执行结果
|
||||
*/
|
||||
update(params: Record<string, any>) {
|
||||
return request.put<any>({
|
||||
url: '/core/post/update',
|
||||
data: params
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
* @param id 数据ID
|
||||
* @returns 执行结果
|
||||
*/
|
||||
delete(params: Record<string, any>) {
|
||||
return request.del<any>({
|
||||
url: '/core/post/destroy',
|
||||
data: params
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 可操作岗位
|
||||
* @returns 数据列表
|
||||
*/
|
||||
accessPost() {
|
||||
return request.get<Api.Common.ApiData[]>({
|
||||
url: '/core/post/accessPost'
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -303,7 +303,16 @@
|
||||
"subtitle": "Latest 50 new player records",
|
||||
"player": "Player",
|
||||
"balance": "Balance",
|
||||
"ticket": "Tickets"
|
||||
"ticket": "Tickets",
|
||||
"registerTime": "Register Time"
|
||||
},
|
||||
"playRecord": {
|
||||
"title": "Player Play Records",
|
||||
"subtitle": "Latest 50 play records",
|
||||
"player": "Player",
|
||||
"reward": "Reward Tier",
|
||||
"winCoin": "Win Amount",
|
||||
"playTime": "Play Time"
|
||||
},
|
||||
"walletRecord": {
|
||||
"title": "Player Charge Records",
|
||||
@@ -379,7 +388,6 @@
|
||||
"userCenter": "User Center",
|
||||
"menu": "Menu Management",
|
||||
"dept": "Department Management",
|
||||
"post": "Post Management",
|
||||
"config": "System Config"
|
||||
},
|
||||
"safeguard": {
|
||||
@@ -445,8 +453,6 @@
|
||||
"placeholderDeptCode": "Dept Code",
|
||||
"placeholderRoleName": "Role Name",
|
||||
"placeholderRoleCode": "Role Code",
|
||||
"placeholderPostName": "Post Name",
|
||||
"placeholderPostCode": "Post Code",
|
||||
"placeholderMenuName": "Menu Name",
|
||||
"placeholderMenuRoute": "Menu Route",
|
||||
"placeholderOperator": "Operator",
|
||||
@@ -514,8 +520,6 @@
|
||||
"dashboard": "Dashboard",
|
||||
"loginTime": "Last Login",
|
||||
"agentId": "Agent ID",
|
||||
"postName": "Post Name",
|
||||
"postCode": "Post Code",
|
||||
"deptName": "Dept Name",
|
||||
"deptCode": "Dept Code",
|
||||
"leader": "Leader",
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"search": {
|
||||
"postName": "Post Name",
|
||||
"postCode": "Post Code",
|
||||
"status": "Status",
|
||||
"placeholderPostName": "Please enter post name",
|
||||
"placeholderPostCode": "Please enter post code",
|
||||
"searchSelectPlaceholder": "Please select"
|
||||
},
|
||||
"table": {
|
||||
"postName": "Post Name",
|
||||
"postCode": "Post Code",
|
||||
"sort": "Sort",
|
||||
"status": "Status",
|
||||
"createTime": "Create Time"
|
||||
},
|
||||
"form": {
|
||||
"titleAdd": "Add Post",
|
||||
"titleEdit": "Edit Post",
|
||||
"labelName": "Post Name",
|
||||
"labelCode": "Post Code",
|
||||
"labelRemark": "Description",
|
||||
"labelSort": "Sort",
|
||||
"labelStatus": "Enabled",
|
||||
"placeholderName": "Please enter post name",
|
||||
"placeholderCode": "Please enter post code",
|
||||
"placeholderRemark": "Please enter description",
|
||||
"placeholderSort": "Please enter sort",
|
||||
"ruleNameRequired": "Please enter post name",
|
||||
"ruleCodeRequired": "Please enter post code",
|
||||
"addSuccess": "Added successfully",
|
||||
"editSuccess": "Updated successfully"
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@
|
||||
"labelPhone": "Phone",
|
||||
"labelDept": "Department",
|
||||
"labelRole": "Role",
|
||||
"labelPost": "Post",
|
||||
"labelGender": "Gender",
|
||||
"labelStatus": "Status",
|
||||
"labelRemark": "Remark",
|
||||
|
||||
@@ -303,7 +303,16 @@
|
||||
"subtitle": "最新50条新增玩家记录",
|
||||
"player": "玩家",
|
||||
"balance": "余额",
|
||||
"ticket": "抽奖券"
|
||||
"ticket": "抽奖券",
|
||||
"registerTime": "注册时间"
|
||||
},
|
||||
"playRecord": {
|
||||
"title": "玩家游玩记录",
|
||||
"subtitle": "最新50条游玩记录",
|
||||
"player": "玩家",
|
||||
"reward": "中奖档位",
|
||||
"winCoin": "赢取平台币",
|
||||
"playTime": "游玩时间"
|
||||
},
|
||||
"walletRecord": {
|
||||
"title": "玩家充值记录",
|
||||
@@ -375,7 +384,6 @@
|
||||
"userCenter": "个人中心",
|
||||
"menu": "菜单管理",
|
||||
"dept": "渠道(部门)管理",
|
||||
"post": "岗位管理",
|
||||
"config": "系统配置"
|
||||
},
|
||||
"safeguard": {
|
||||
@@ -441,8 +449,6 @@
|
||||
"placeholderDeptCode": "请输入部门编码",
|
||||
"placeholderRoleName": "请输入角色名称",
|
||||
"placeholderRoleCode": "请输入角色编码",
|
||||
"placeholderPostName": "请输入岗位名称",
|
||||
"placeholderPostCode": "请输入岗位编码",
|
||||
"placeholderMenuName": "请输入菜单名称",
|
||||
"placeholderMenuRoute": "请输入菜单路由",
|
||||
"placeholderOperator": "请输入操作用户",
|
||||
@@ -510,8 +516,6 @@
|
||||
"dashboard": "首页",
|
||||
"loginTime": "上次登录",
|
||||
"agentId": "代理ID",
|
||||
"postName": "岗位名称",
|
||||
"postCode": "岗位编码",
|
||||
"deptName": "部门名称",
|
||||
"deptCode": "部门编码",
|
||||
"leader": "部门领导",
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"search": {
|
||||
"postName": "岗位名称",
|
||||
"postCode": "岗位编码",
|
||||
"status": "状态",
|
||||
"placeholderPostName": "请输入岗位名称",
|
||||
"placeholderPostCode": "请输入岗位编码",
|
||||
"searchSelectPlaceholder": "请选择"
|
||||
},
|
||||
"table": {
|
||||
"postName": "岗位名称",
|
||||
"postCode": "岗位编码",
|
||||
"sort": "排序",
|
||||
"status": "状态",
|
||||
"createTime": "创建时间"
|
||||
},
|
||||
"form": {
|
||||
"titleAdd": "新增岗位",
|
||||
"titleEdit": "编辑岗位",
|
||||
"labelName": "岗位名称",
|
||||
"labelCode": "岗位编码",
|
||||
"labelRemark": "描述",
|
||||
"labelSort": "排序",
|
||||
"labelStatus": "启用",
|
||||
"placeholderName": "请输入岗位名称",
|
||||
"placeholderCode": "请输入岗位编码",
|
||||
"placeholderRemark": "请输入岗位描述",
|
||||
"placeholderSort": "请输入排序",
|
||||
"ruleNameRequired": "请输入岗位名称",
|
||||
"ruleCodeRequired": "请输入岗位编码",
|
||||
"addSuccess": "新增成功",
|
||||
"editSuccess": "修改成功"
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@
|
||||
"labelPhone": "手机号",
|
||||
"labelDept": "部门",
|
||||
"labelRole": "角色",
|
||||
"labelPost": "岗位",
|
||||
"labelGender": "性别",
|
||||
"labelStatus": "状态",
|
||||
"labelRemark": "备注",
|
||||
|
||||
@@ -25,7 +25,6 @@ export const MAP_PATH_TO_MENU_I18N_KEY: Record<string, string> = {
|
||||
'/system/user-center': 'menus.system.userCenter',
|
||||
'/system/menu': 'menus.system.menu',
|
||||
'/system/dept': 'menus.system.dept',
|
||||
'/system/post': 'menus.system.post',
|
||||
'/system/config': 'menus.system.config',
|
||||
'/safeguard': 'menus.safeguard.title',
|
||||
'/safeguard/dict': 'menus.safeguard.dict',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<!-- 工作台页面 -->
|
||||
<!-- 工作台页面:大富翁色子游戏数据统计 -->
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="userInfo.dashboard === 'statistics'">
|
||||
<CardList></CardList>
|
||||
<CardList />
|
||||
|
||||
<template v-if="isStatisticsDashboard">
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="24" :md="12" :lg="10">
|
||||
<ActiveUser />
|
||||
@@ -12,30 +12,22 @@
|
||||
<SalesOverview />
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<WalletRecordList />
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<NewPlayerList />
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</template>
|
||||
|
||||
<template v-if="userInfo.dashboard === 'work'">
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="24" :md="24" :lg="12">
|
||||
<NewUser />
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="6">
|
||||
<Dynamic />
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="6">
|
||||
<TodoList />
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</template>
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<NewPlayerList />
|
||||
</ElCol>
|
||||
<ElCol :sm="24" :md="12" :lg="12">
|
||||
<WalletRecordList />
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :sm="24" :md="24" :lg="24">
|
||||
<PlayRecordList />
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -45,16 +37,18 @@
|
||||
import SalesOverview from './modules/sales-overview.vue'
|
||||
import WalletRecordList from './modules/wallet-record-list.vue'
|
||||
import NewPlayerList from './modules/new-player-list.vue'
|
||||
import NewUser from './modules/new-user.vue'
|
||||
import Dynamic from './modules/dynamic-stats.vue'
|
||||
import TodoList from './modules/todo-list.vue'
|
||||
import PlayRecordList from './modules/play-record-list.vue'
|
||||
import { useCommon } from '@/hooks/core/useCommon'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
defineOptions({ name: 'Console' })
|
||||
|
||||
const userStore = useUserStore()
|
||||
const userInfo = userStore.getUserInfo
|
||||
|
||||
/** 统计页额外展示充值图表 */
|
||||
const isStatisticsDashboard = computed(
|
||||
() => userStore.getUserInfo.dashboard === 'statistics'
|
||||
)
|
||||
|
||||
const { scrollToTop } = useCommon()
|
||||
scrollToTop()
|
||||
|
||||
@@ -17,11 +17,23 @@
|
||||
>
|
||||
<template #default>
|
||||
<ElTableColumn :label="$t('console.newPlayer.player')" prop="name" min-width="120" align="center" />
|
||||
<ElTableColumn :label="$t('console.newPlayer.balance')" prop="coin" min-width="120" align="center">
|
||||
<ElTableColumn :label="$t('console.newPlayer.balance')" prop="coin" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
{{ formatCoin(scope.row.coin) }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
:label="$t('console.newPlayer.ticket')"
|
||||
prop="total_ticket_count"
|
||||
min-width="90"
|
||||
align="center"
|
||||
/>
|
||||
<ElTableColumn
|
||||
:label="$t('console.newPlayer.registerTime')"
|
||||
prop="create_time"
|
||||
min-width="170"
|
||||
align="center"
|
||||
/>
|
||||
</template>
|
||||
</ArtTable>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="art-card p-5 overflow-hidden mb-5 max-sm:mb-4">
|
||||
<div class="art-card-header mb-4">
|
||||
<div class="title">
|
||||
<h4>{{ $t('console.playRecord.title') }}</h4>
|
||||
<p class="text-g-600 text-sm mt-1">{{ $t('console.playRecord.subtitle') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<ArtTable
|
||||
class="w-full"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
size="default"
|
||||
:border="false"
|
||||
:stripe="true"
|
||||
:header-cell-style="{ background: 'transparent' }"
|
||||
>
|
||||
<template #default>
|
||||
<ElTableColumn
|
||||
:label="$t('console.playRecord.player')"
|
||||
prop="player_name"
|
||||
min-width="120"
|
||||
align="center"
|
||||
/>
|
||||
<ElTableColumn
|
||||
:label="$t('console.playRecord.reward')"
|
||||
prop="reward_tier_label"
|
||||
min-width="140"
|
||||
align="center"
|
||||
/>
|
||||
<ElTableColumn
|
||||
:label="$t('console.playRecord.winCoin')"
|
||||
prop="win_coin"
|
||||
min-width="120"
|
||||
align="center"
|
||||
>
|
||||
<template #default="scope">
|
||||
{{ formatCoin(scope.row.win_coin) }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
:label="$t('console.playRecord.playTime')"
|
||||
prop="create_time"
|
||||
min-width="170"
|
||||
align="center"
|
||||
/>
|
||||
</template>
|
||||
</ArtTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { fetchPlayRecordList, type PlayRecordItem } from '@/api/dashboard'
|
||||
|
||||
const tableData = ref<PlayRecordItem[]>([])
|
||||
|
||||
function formatCoin(val: number | undefined): string {
|
||||
if (val === undefined || val === null) return '0.00'
|
||||
return Number(val).toFixed(2)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchPlayRecordList().then((data) => {
|
||||
tableData.value = Array.isArray(data) ? data : []
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@@ -1,142 +0,0 @@
|
||||
<template>
|
||||
<div class="art-full-height">
|
||||
<!-- 搜索面板 -->
|
||||
<TableSearch v-model="searchForm" @search="handleSearch" @reset="resetSearchParams" />
|
||||
|
||||
<ElCard class="art-table-card" shadow="never">
|
||||
<!-- 表格头部 -->
|
||||
<ArtTableHeader v-model:columns="columnChecks" :loading="loading" @refresh="refreshData">
|
||||
<template #left>
|
||||
<ElSpace wrap>
|
||||
<ElButton v-permission="'core:post:save'" @click="showDialog('add')" v-ripple>
|
||||
<template #icon>
|
||||
<ArtSvgIcon icon="ri:add-fill" />
|
||||
</template>
|
||||
{{ $t('table.actions.add') }}
|
||||
</ElButton>
|
||||
<ElButton
|
||||
v-permission="'core:post:destroy'"
|
||||
:disabled="selectedRows.length === 0"
|
||||
@click="deleteSelectedRows(api.delete, refreshData)"
|
||||
v-ripple
|
||||
>
|
||||
<template #icon>
|
||||
<ArtSvgIcon icon="ri:delete-bin-5-line" />
|
||||
</template>
|
||||
{{ $t('table.actions.delete') }}
|
||||
</ElButton>
|
||||
<SaImport
|
||||
v-permission="'core:post:import'"
|
||||
download-url="/core/post/downloadTemplate"
|
||||
upload-url="/core/post/import"
|
||||
@success="refreshData"
|
||||
/>
|
||||
<SaExport v-permission="'core:post:export'" url="/core/post/export" />
|
||||
</ElSpace>
|
||||
</template>
|
||||
</ArtTableHeader>
|
||||
|
||||
<!-- 表格 -->
|
||||
<ArtTable
|
||||
ref="tableRef"
|
||||
rowKey="id"
|
||||
:loading="loading"
|
||||
:data="data"
|
||||
:columns="columns"
|
||||
:pagination="pagination"
|
||||
@sort-change="handleSortChange"
|
||||
@selection-change="handleSelectionChange"
|
||||
@pagination:size-change="handleSizeChange"
|
||||
@pagination:current-change="handleCurrentChange"
|
||||
>
|
||||
<!-- 操作列 -->
|
||||
<template #operation="{ row }">
|
||||
<div class="flex gap-2">
|
||||
<SaButton
|
||||
v-permission="'core:post:update'"
|
||||
type="secondary"
|
||||
@click="showDialog('edit', row)"
|
||||
/>
|
||||
<SaButton
|
||||
v-permission="'core:post:destroy'"
|
||||
type="error"
|
||||
@click="deleteRow(row, api.delete, refreshData)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</ArtTable>
|
||||
</ElCard>
|
||||
|
||||
<!-- 编辑弹窗 -->
|
||||
<EditDialog
|
||||
v-model="dialogVisible"
|
||||
:dialog-type="dialogType"
|
||||
:data="dialogData"
|
||||
@success="refreshData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useTable } from '@/hooks/core/useTable'
|
||||
import { useSaiAdmin } from '@/composables/useSaiAdmin'
|
||||
import api from '@/api/system/post'
|
||||
import TableSearch from './modules/table-search.vue'
|
||||
import EditDialog from './modules/edit-dialog.vue'
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = ref({
|
||||
name: undefined,
|
||||
code: undefined,
|
||||
status: undefined
|
||||
})
|
||||
|
||||
// 搜索处理
|
||||
const handleSearch = (params: Record<string, any>) => {
|
||||
Object.assign(searchParams, params)
|
||||
getData()
|
||||
}
|
||||
|
||||
// 表格配置
|
||||
const {
|
||||
columns,
|
||||
columnChecks,
|
||||
data,
|
||||
loading,
|
||||
getData,
|
||||
searchParams,
|
||||
pagination,
|
||||
resetSearchParams,
|
||||
handleSortChange,
|
||||
handleSizeChange,
|
||||
handleCurrentChange,
|
||||
refreshData
|
||||
} = useTable({
|
||||
core: {
|
||||
apiFn: api.list,
|
||||
columnsFactory: () => [
|
||||
{ type: 'selection' },
|
||||
{ prop: 'id', label: 'table.columns.common.no', width: 100, align: 'center' },
|
||||
{ prop: 'name', label: 'page.table.postName', minWidth: 120 },
|
||||
{ prop: 'code', label: 'page.table.postCode', minWidth: 120 },
|
||||
{ prop: 'remark', label: 'table.columns.common.description', minWidth: 150, showOverflowTooltip: true },
|
||||
{ prop: 'sort', label: 'page.table.sort', width: 100 },
|
||||
{ prop: 'status', label: 'page.table.status', saiType: 'dict', saiDict: 'data_status', width: 100 },
|
||||
{ prop: 'create_time', label: 'page.table.createTime', width: 180, sortable: true },
|
||||
{ prop: 'operation', label: 'table.actions.operation', width: 100, fixed: 'right', useSlot: true }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 编辑配置
|
||||
const {
|
||||
dialogType,
|
||||
dialogVisible,
|
||||
dialogData,
|
||||
showDialog,
|
||||
deleteRow,
|
||||
deleteSelectedRows,
|
||||
handleSelectionChange,
|
||||
selectedRows
|
||||
} = useSaiAdmin()
|
||||
</script>
|
||||
@@ -1,166 +0,0 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="dialogType === 'add' ? $t('page.form.titleAdd') : $t('page.form.titleEdit')"
|
||||
width="600px"
|
||||
align-center
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
|
||||
<el-form-item :label="$t('page.form.labelName')" prop="name">
|
||||
<el-input v-model="formData.name" :placeholder="$t('page.form.placeholderName')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.form.labelCode')" prop="code">
|
||||
<el-input v-model="formData.code" :placeholder="$t('page.form.placeholderCode')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.form.labelRemark')" prop="remark">
|
||||
<el-input
|
||||
v-model="formData.remark"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
:placeholder="$t('page.form.placeholderRemark')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.form.labelSort')" prop="sort">
|
||||
<el-input-number v-model="formData.sort" :placeholder="$t('page.form.placeholderSort')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.form.labelStatus')" prop="status">
|
||||
<sa-radio v-model="formData.status" dict="data_status" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="handleClose">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">{{ $t('table.form.submit') }}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import api from '@/api/system/post'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
dialogType: string
|
||||
data?: Record<string, any>
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
(e: 'success'): void
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: false,
|
||||
dialogType: 'add',
|
||||
data: undefined
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
const { t } = useI18n()
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
/**
|
||||
* 弹窗显示状态双向绑定
|
||||
*/
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (value) => emit('update:modelValue', value)
|
||||
})
|
||||
|
||||
/**
|
||||
* 表单验证规则
|
||||
*/
|
||||
const rules = computed<FormRules>(() => ({
|
||||
name: [{ required: true, message: t('page.form.ruleNameRequired'), trigger: 'blur' }],
|
||||
code: [{ required: true, message: t('page.form.ruleCodeRequired'), trigger: 'blur' }]
|
||||
}))
|
||||
|
||||
/**
|
||||
* 初始数据
|
||||
*/
|
||||
const initialFormData = {
|
||||
id: null,
|
||||
name: '',
|
||||
code: '',
|
||||
remark: '',
|
||||
sort: 100,
|
||||
status: 1
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单数据
|
||||
*/
|
||||
const formData = reactive({ ...initialFormData })
|
||||
|
||||
/**
|
||||
* 监听弹窗打开,初始化表单数据
|
||||
*/
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
initPage()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* 初始化页面数据
|
||||
*/
|
||||
const initPage = async () => {
|
||||
// 先重置为初始值
|
||||
Object.assign(formData, initialFormData)
|
||||
// 如果有数据,则填充数据
|
||||
if (props.data) {
|
||||
await nextTick()
|
||||
initForm()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化表单数据
|
||||
*/
|
||||
const initForm = () => {
|
||||
if (props.data) {
|
||||
for (const key in formData) {
|
||||
if (props.data[key] != null && props.data[key] != undefined) {
|
||||
;(formData as any)[key] = props.data[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭弹窗并重置表单
|
||||
*/
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交表单
|
||||
*/
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
if (props.dialogType === 'add') {
|
||||
await api.save(formData)
|
||||
ElMessage.success(t('page.form.addSuccess'))
|
||||
} else {
|
||||
await api.update(formData)
|
||||
ElMessage.success(t('page.form.editSuccess'))
|
||||
}
|
||||
emit('success')
|
||||
handleClose()
|
||||
} catch (error) {
|
||||
console.log('表单验证失败:', error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,77 +0,0 @@
|
||||
<template>
|
||||
<sa-search-bar
|
||||
ref="searchBarRef"
|
||||
v-model="formData"
|
||||
label-width="100px"
|
||||
:showExpand="false"
|
||||
@reset="handleReset"
|
||||
@search="handleSearch"
|
||||
@expand="handleExpand"
|
||||
>
|
||||
<el-col v-bind="setSpan(6)">
|
||||
<el-form-item :label="$t('page.search.postName')" prop="name">
|
||||
<el-input v-model="formData.name" :placeholder="$t('page.search.placeholderPostName')" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-bind="setSpan(6)">
|
||||
<el-form-item :label="$t('page.search.postCode')" prop="code">
|
||||
<el-input v-model="formData.code" :placeholder="$t('page.search.placeholderPostCode')" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-bind="setSpan(6)">
|
||||
<el-form-item :label="$t('page.search.status')" prop="status">
|
||||
<sa-select v-model="formData.status" dict="data_status" :placeholder="$t('page.search.searchSelectPlaceholder')" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</sa-search-bar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
modelValue: Record<string, any>
|
||||
}
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: Record<string, any>): void
|
||||
(e: 'search', params: Record<string, any>): void
|
||||
(e: 'reset'): void
|
||||
}
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
// 展开/收起
|
||||
const isExpanded = ref<boolean>(false)
|
||||
|
||||
// 表单数据双向绑定
|
||||
const searchBarRef = ref()
|
||||
const formData = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emit('update:modelValue', val)
|
||||
})
|
||||
|
||||
// 重置
|
||||
function handleReset() {
|
||||
searchBarRef.value?.ref.resetFields()
|
||||
emit('reset')
|
||||
}
|
||||
|
||||
// 搜索
|
||||
async function handleSearch() {
|
||||
emit('search', formData.value)
|
||||
}
|
||||
|
||||
// 展开/收起
|
||||
function handleExpand(expanded: boolean) {
|
||||
isExpanded.value = expanded
|
||||
}
|
||||
|
||||
// 栅格占据的列数
|
||||
const setSpan = (span: number) => {
|
||||
return {
|
||||
span: span,
|
||||
xs: 24, // 手机:满宽显示
|
||||
sm: span >= 12 ? span : 12, // 平板:大于等于12保持,否则用半宽
|
||||
md: span >= 8 ? span : 8, // 中等屏幕:大于等于8保持,否则用三分之一宽
|
||||
lg: span,
|
||||
xl: span
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -76,18 +76,6 @@
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item :label="$t('page.form.labelPost')" prop="post_ids">
|
||||
<el-select v-model="formData.post_ids" multiple clearable>
|
||||
<el-option
|
||||
v-for="post in optionData.postList"
|
||||
:key="(post as any)?.id"
|
||||
:value="(post as any)?.id"
|
||||
:label="(post as any)?.name"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item :label="$t('page.form.labelGender')" prop="gender">
|
||||
<sa-radio v-model="formData.gender" dict="gender" valueType="string" />
|
||||
@@ -129,7 +117,6 @@
|
||||
import api from '@/api/system/user'
|
||||
import deptApi from '@/api/system/dept'
|
||||
import roleApi from '@/api/system/role'
|
||||
import postApi from '@/api/system/post'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
@@ -156,8 +143,7 @@
|
||||
const formRef = ref<FormInstance>()
|
||||
const optionData = reactive({
|
||||
deptData: <any>[],
|
||||
roleList: <any>[],
|
||||
postList: <any>[]
|
||||
roleList: <any>[]
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -207,7 +193,6 @@
|
||||
phone: '',
|
||||
email: '',
|
||||
role_ids: [],
|
||||
post_ids: [],
|
||||
status: 1,
|
||||
gender: '',
|
||||
remark: ''
|
||||
@@ -239,18 +224,11 @@
|
||||
// 角色数据
|
||||
const roleData = await roleApi.accessRole()
|
||||
optionData.roleList = roleData
|
||||
// 岗位数据
|
||||
const postData = await postApi.accessPost()
|
||||
optionData.postList = postData
|
||||
// 如果有数据,则填充数据
|
||||
if (props.data) {
|
||||
await nextTick()
|
||||
if (props.data.id) {
|
||||
let data = await api.read(props.data.id)
|
||||
if (data.postList) {
|
||||
const post = (data.postList as any[])?.map((item: any) => item.id)
|
||||
data.post_ids = post
|
||||
}
|
||||
const role = (data.roleList as any[])?.map((item: any) => item.id)
|
||||
data.role_ids = role
|
||||
data.password = ''
|
||||
|
||||
Reference in New Issue
Block a user