Merge remote-tracking branch 'yudao/dev' into dev

# Conflicts:
#	src/types/auto-components.d.ts
pull/78/head
puhui999 2023-04-04 10:29:59 +08:00
commit 933c710f36
105 changed files with 3163 additions and 2243 deletions

View File

@ -13,50 +13,38 @@ export interface JobVO {
createTime: Date
}
export interface JobPageReqVO extends PageParam {
name?: string
status?: number
handlerName?: string
}
export interface JobExportReqVO {
name?: string
status?: number
handlerName?: string
}
// 任务列表
export const getJobPageApi = (params: JobPageReqVO) => {
export const getJobPage = (params: PageParam) => {
return request.get({ url: '/infra/job/page', params })
}
// 任务详情
export const getJobApi = (id: number) => {
export const getJob = (id: number) => {
return request.get({ url: '/infra/job/get?id=' + id })
}
// 新增任务
export const createJobApi = (data: JobVO) => {
export const createJob = (data: JobVO) => {
return request.post({ url: '/infra/job/create', data })
}
// 修改定时任务调度
export const updateJobApi = (data: JobVO) => {
export const updateJob = (data: JobVO) => {
return request.put({ url: '/infra/job/update', data })
}
// 删除定时任务调度
export const deleteJobApi = (id: number) => {
export const deleteJob = (id: number) => {
return request.delete({ url: '/infra/job/delete?id=' + id })
}
// 导出定时任务调度
export const exportJobApi = (params: JobExportReqVO) => {
export const exportJob = (params) => {
return request.download({ url: '/infra/job/export-excel', params })
}
// 任务状态修改
export const updateJobStatusApi = (id: number, status: number) => {
export const updateJobStatus = (id: number, status: number) => {
const params = {
id,
status
@ -70,6 +58,6 @@ export const runJobApi = (id: number) => {
}
// 获得定时任务的下 n 次执行时间
export const getJobNextTimesApi = (id: number) => {
export const getJobNextTimes = (id: number) => {
return request.get({ url: '/infra/job/get_next_times?id=' + id })
}

View File

@ -14,34 +14,18 @@ export interface JobLogVO {
createTime: string
}
export interface JobLogPageReqVO extends PageParam {
jobId?: number
handlerName?: string
beginTime?: string
endTime?: string
status?: number
}
export interface JobLogExportReqVO {
jobId?: number
handlerName?: string
beginTime?: string
endTime?: string
status?: number
}
// 任务日志列表
export const getJobLogPageApi = (params: JobLogPageReqVO) => {
export const getJobLogPage = (params: PageParam) => {
return request.get({ url: '/infra/job-log/page', params })
}
// 任务日志详情
export const getJobLogApi = (id: number) => {
export const getJobLog = (id: number) => {
return request.get({ url: '/infra/job-log/get?id=' + id })
}
// 导出定时任务日志
export const exportJobLogApi = (params: JobLogExportReqVO) => {
export const exportJobLog = (params) => {
return request.download({
url: '/infra/job-log/export-excel',
params

View File

@ -0,0 +1,60 @@
import request from '@/config/axios'
/**
*
*/
export interface CategoryVO {
/**
*
*/
id?: number
/**
*
*/
parentId?: number
/**
*
*/
name: string
/**
*
*/
picUrl: string
/**
*
*/
sort?: number
/**
*
*/
description?: string
/**
*
*/
status: number
}
// 创建商品分类
export const createCategory = (data: CategoryVO) => {
return request.post({ url: '/product/category/create', data })
}
// 更新商品分类
export const updateCategory = (data: CategoryVO) => {
return request.put({ url: '/product/category/update', data })
}
// 删除商品分类
export const deleteCategory = (id: number) => {
return request.delete({ url: `/product/category/delete?id=${id}` })
}
// 获得商品分类
export const getCategory = (id: number) => {
return request.get({ url: `/product/category/get?id=${id}` })
}
// 获得商品分类列表
export const getCategoryList = (params: any) => {
return request.get({ url: '/product/category/list', params })
}

View File

@ -0,0 +1,103 @@
import request from '@/config/axios'
/**
*
*/
export interface PropertyVO {
id?: number
/** 名称 */
name: string
/** 备注 */
remark?: string
}
/**
*
*/
export interface PropertyValueVO {
id?: number
/** 属性项的编号 */
propertyId?: number
/** 名称 */
name: string
/** 备注 */
remark?: string
}
/**
*
*/
export interface PropertyValueDetailVO {
/** 属性项的编号 */
propertyId: number // 属性的编号
/** 属性的名称 */
propertyName: string
/** 属性值的编号 */
valueId: number
/** 属性值的名称 */
valueName: string
}
// ------------------------ 属性项 -------------------
// 创建属性项
export const createProperty = (data: PropertyVO) => {
return request.post({ url: '/product/property/create', data })
}
// 更新属性项
export const updateProperty = (data: PropertyVO) => {
return request.put({ url: '/product/property/update', data })
}
// 删除属性项
export const deleteProperty = (id: number) => {
return request.delete({ url: `/product/property/delete?id=${id}` })
}
// 获得属性项
export const getProperty = (id: number): Promise<PropertyVO> => {
return request.get({ url: `/product/property/get?id=${id}` })
}
// 获得属性项分页
export const getPropertyPage = (params: PageParam) => {
return request.get({ url: '/product/property/page', params })
}
// 获得属性项列表
export const getPropertyList = (params: any) => {
return request.get({ url: '/product/property/list', params })
}
// 获得属性项列表
export const getPropertyListAndValue = (params: any) => {
return request.get({ url: '/product/property/get-value-list', params })
}
// ------------------------ 属性值 -------------------
// 获得属性值分页
export const getPropertyValuePage = (params: PageParam & any) => {
return request.get({ url: '/product/property/value/page', params })
}
// 获得属性值
export const getPropertyValue = (id: number): Promise<PropertyValueVO> => {
return request.get({ url: `/product/property/value/get?id=${id}` })
}
// 创建属性值
export const createPropertyValue = (data: PropertyValueVO) => {
return request.post({ url: '/product/property/value/create', data })
}
// 更新属性值
export const updatePropertyValue = (data: PropertyValueVO) => {
return request.put({ url: '/product/property/value/update', data })
}
// 删除属性值
export const deletePropertyValue = (id: number) => {
return request.delete({ url: `/product/property/value/delete?id=${id}` })
}

View File

@ -29,17 +29,17 @@ export interface MerchantExportReqVO {
}
// 查询列表支付商户
export const getMerchantPageApi = (params: MerchantPageReqVO) => {
export const getMerchantPage = (params: MerchantPageReqVO) => {
return request.get({ url: '/pay/merchant/page', params })
}
// 查询详情支付商户
export const getMerchantApi = (id: number) => {
export const getMerchant = (id: number) => {
return request.get({ url: '/pay/merchant/get?id=' + id })
}
// 根据商户名称搜索商户列表
export const getMerchantListByNameApi = (name: string) => {
export const getMerchantListByName = (name: string) => {
return request.get({
url: '/pay/merchant/list-by-name?id=',
params: {
@ -49,26 +49,27 @@ export const getMerchantListByNameApi = (name: string) => {
}
// 新增支付商户
export const createMerchantApi = (data: MerchantVO) => {
export const createMerchant = (data: MerchantVO) => {
return request.post({ url: '/pay/merchant/create', data })
}
// 修改支付商户
export const updateMerchantApi = (data: MerchantVO) => {
export const updateMerchant = (data: MerchantVO) => {
return request.put({ url: '/pay/merchant/update', data })
}
// 删除支付商户
export const deleteMerchantApi = (id: number) => {
export const deleteMerchant = (id: number) => {
return request.delete({ url: '/pay/merchant/delete?id=' + id })
}
// 导出支付商户
export const exportMerchantApi = (params: MerchantExportReqVO) => {
export const exportMerchant = (params: MerchantExportReqVO) => {
return request.download({ url: '/pay/merchant/export-excel', params })
}
// 支付商户状态修改
export const changeMerchantStatusApi = (id: number, status: number) => {
export const updateMerchantStatus = (id: number, status: number) => {
const data = {
id,
status

View File

@ -44,6 +44,6 @@ export const deleteDictData = (id: number) => {
}
// 导出字典类型数据
export const exportDictDataApi = (params) => {
export const exportDictData = (params) => {
return request.get({ url: '/system/dict-data/export', params })
}

View File

@ -21,31 +21,27 @@ export interface OAuth2ClientVO {
createTime: Date
}
export interface OAuth2ClientPageReqVO extends PageParam {
name?: string
status?: number
}
// 查询 OAuth2列表
export const getOAuth2ClientPageApi = (params: OAuth2ClientPageReqVO) => {
// 查询 OAuth2 客户端的列表
export const getOAuth2ClientPage = (params: PageParam) => {
return request.get({ url: '/system/oauth2-client/page', params })
}
// 查询 OAuth2详情
export const getOAuth2ClientApi = (id: number) => {
// 查询 OAuth2 客户端的详情
export const getOAuth2Client = (id: number) => {
return request.get({ url: '/system/oauth2-client/get?id=' + id })
}
// 新增 OAuth2
export const createOAuth2ClientApi = (data: OAuth2ClientVO) => {
// 新增 OAuth2 客户端
export const createOAuth2Client = (data: OAuth2ClientVO) => {
return request.post({ url: '/system/oauth2-client/create', data })
}
// 修改 OAuth2
export const updateOAuth2ClientApi = (data: OAuth2ClientVO) => {
// 修改 OAuth2 客户端
export const updateOAuth2Client = (data: OAuth2ClientVO) => {
return request.put({ url: '/system/oauth2-client/update', data })
}
// 删除 OAuth2
export const deleteOAuth2ClientApi = (id: number) => {
export const deleteOAuth2Client = (id: number) => {
return request.delete({ url: '/system/oauth2-client/delete?id=' + id })
}

View File

@ -17,26 +17,26 @@ export interface PermissionAssignRoleDataScopeReqVO {
}
// 查询角色拥有的菜单权限
export const listRoleMenusApi = async (roleId: number) => {
export const getRoleMenuList = async (roleId: number) => {
return await request.get({ url: '/system/permission/list-role-resources?roleId=' + roleId })
}
// 赋予角色菜单权限
export const assignRoleMenuApi = async (data: PermissionAssignRoleMenuReqVO) => {
export const assignRoleMenu = async (data: PermissionAssignRoleMenuReqVO) => {
return await request.post({ url: '/system/permission/assign-role-menu', data })
}
// 赋予角色数据权限
export const assignRoleDataScopeApi = async (data: PermissionAssignRoleDataScopeReqVO) => {
export const assignRoleDataScope = async (data: PermissionAssignRoleDataScopeReqVO) => {
return await request.post({ url: '/system/permission/assign-role-data-scope', data })
}
// 查询用户拥有的角色数组
export const listUserRolesApi = async (userId: number) => {
export const getUserRoleList = async (userId: number) => {
return await request.get({ url: '/system/permission/list-user-roles?userId=' + userId })
}
// 赋予用户角色
export const assignUserRoleApi = async (data: PermissionAssignUserRoleReqVO) => {
export const assignUserRole = async (data: PermissionAssignUserRoleReqVO) => {
return await request.post({ url: '/system/permission/assign-user-role', data })
}

View File

@ -7,6 +7,8 @@ export interface RoleVO {
sort: number
status: number
type: number
dataScope: number
dataScopeDeptIds: number[]
createTime: Date
}
@ -49,6 +51,7 @@ export const updateRoleStatus = async (data: UpdateStatusReqVO) => {
export const deleteRole = async (id: number) => {
return await request.delete({ url: '/system/role/delete?id=' + id })
}
// 导出角色
export const exportRole = (params) => {
return request.download({

View File

@ -17,58 +17,43 @@ export interface UserVO {
createTime: Date
}
export interface UserPageReqVO extends PageParam {
deptId?: number
username?: string
mobile?: string
status?: number
createTime?: Date[]
}
export interface UserExportReqVO {
code?: string
name?: string
status?: number
createTime?: Date[]
}
// 查询用户管理列表
export const getUserPageApi = (params: UserPageReqVO) => {
export const getUserPage = (params: PageParam) => {
return request.get({ url: '/system/user/page', params })
}
// 查询用户详情
export const getUserApi = (id: number) => {
export const getUser = (id: number) => {
return request.get({ url: '/system/user/get?id=' + id })
}
// 新增用户
export const createUserApi = (data: UserVO | Recordable) => {
export const createUser = (data: UserVO) => {
return request.post({ url: '/system/user/create', data })
}
// 修改用户
export const updateUserApi = (data: UserVO | Recordable) => {
export const updateUser = (data: UserVO) => {
return request.put({ url: '/system/user/update', data })
}
// 删除用户
export const deleteUserApi = (id: number) => {
export const deleteUser = (id: number) => {
return request.delete({ url: '/system/user/delete?id=' + id })
}
// 导出用户
export const exportUserApi = (params: UserExportReqVO) => {
export const exportUser = (params) => {
return request.download({ url: '/system/user/export', params })
}
// 下载用户导入模板
export const importUserTemplateApi = () => {
export const importUserTemplate = () => {
return request.download({ url: '/system/user/get-import-template' })
}
// 用户密码重置
export const resetUserPwdApi = (id: number, password: string) => {
export const resetUserPwd = (id: number, password: string) => {
const data = {
id,
password
@ -77,7 +62,7 @@ export const resetUserPwdApi = (id: number, password: string) => {
}
// 用户状态修改
export const updateUserStatusApi = (id: number, status: number) => {
export const updateUserStatus = (id: number, status: number) => {
const data = {
id,
status

View File

@ -6,7 +6,10 @@ interface shortcutsType {
value: string
}
const props = defineProps({
modelValue: { type: String, default: '* * * * * ?' },
modelValue: {
type: String,
default: '* * * * * ?'
},
shortcuts: { type: Array as PropType<shortcutsType[]>, default: () => [] }
})
const defaultValue = ref('')

View File

@ -162,7 +162,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
children: [
{
path: 'job-log',
component: () => import('@/views/infra/job/JobLog.vue'),
component: () => import('@/views/infra/job/logger/index.vue'),
name: 'JobLog',
meta: {
noCache: true,
@ -319,6 +319,22 @@ const remainingRouter: AppRouteRecordRaw[] = [
}
}
]
},
{
path: '/property',
component: Layout,
name: 'property',
meta: {
hidden: true
},
children: [
{
path: 'value/:propertyId(\\d+)',
component: () => import('@/views/mall/product/property/value/index.vue'),
name: 'PropertyValue',
meta: { title: '商品属性值', icon: '', activeMenu: '/product/property' }
}
]
}
]

View File

@ -23,6 +23,7 @@ declare module '@vue/runtime-core' {
DictTag: typeof import('./../components/DictTag/src/DictTag.vue')['default']
Echart: typeof import('./../components/Echart/src/Echart.vue')['default']
Editor: typeof import('./../components/Editor/src/Editor.vue')['default']
ElAutoResizer: typeof import('element-plus/es')['ElAutoResizer']
ElBadge: typeof import('element-plus/es')['ElBadge']
ElButton: typeof import('element-plus/es')['ElButton']
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
@ -52,13 +53,16 @@ declare module '@vue/runtime-core' {
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
@ -67,9 +71,15 @@ declare module '@vue/runtime-core' {
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTableV2: typeof import('element-plus/es')['ElTableV2']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElTimeline: typeof import('element-plus/es')['ElTimeline']
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTransfer: typeof import('element-plus/es')['ElTransfer']
ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
ElUpload: typeof import('element-plus/es')['ElUpload']
Error: typeof import('./../components/Error/src/Error.vue')['default']

View File

@ -11,7 +11,7 @@
</ContentWrap>
<!-- 表单保存的弹窗 -->
<Dialog title="保存表单" v-model="modelVisible" width="600">
<Dialog title="保存表单" v-model="dialogVisible" width="600">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px">
<el-form-item label="表单名" prop="name">
<el-input v-model="formData.name" placeholder="请输入表单名" />
@ -33,7 +33,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -48,7 +48,7 @@ const message = useMessage() // 消息
const { query } = useRoute() //
const designer = ref() //
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const formData = ref({
name: '',
@ -63,7 +63,7 @@ const formRef = ref() // 表单 Ref
/** 处理保存按钮 */
const handleSave = () => {
modelVisible.value = true
dialogVisible.value = true
}
/** 提交表单 */
@ -85,7 +85,7 @@ const submitForm = async () => {
await FormApi.updateForm(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
} finally {
formLoading.value = false
}

View File

@ -20,7 +20,7 @@
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button type="primary" @click="openForm()" v-hasPermi="['bpm:form:create']">
<el-button type="primary" plain @click="openForm" v-hasPermi="['bpm:form:create']">
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
</el-form-item>

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -37,7 +37,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -50,8 +50,8 @@ import * as UserApi from '@/api/system/user'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -72,8 +72,8 @@ const userList = ref([]) // 用户列表
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -108,7 +108,7 @@ const submitForm = async () => {
await UserGroupApi.updateUserGroup(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -43,6 +43,7 @@
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['bpm:user-group:create']"
>

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible" width="600">
<Dialog :title="dialogTitle" v-model="dialogVisible" width="600">
<el-form
ref="formRef"
:model="formData"
@ -117,7 +117,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -129,8 +129,8 @@ import * as FormApi from '@/api/bpm/form'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -154,8 +154,8 @@ const formList = ref([]) // 流程表单的下拉框的数据
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -203,7 +203,7 @@ const submitForm = async () => {
await ModelApi.updateModel(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="导入流程" v-model="modelVisible" width="400">
<Dialog title="导入流程" v-model="dialogVisible" width="400">
<div>
<el-upload
ref="uploadRef"
@ -8,7 +8,7 @@
:data="formData"
name="bpmnFile"
v-model:file-list="fileList"
:drag="true"
drag
:auto-upload="false"
accept=".bpmn, .xml"
:limit="1"
@ -45,7 +45,7 @@
</div>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -53,7 +53,7 @@
import { getAccessToken, getTenantId } from '@/utils/auth'
const message = useMessage() //
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const formData = ref({
key: '',
@ -72,12 +72,12 @@ const fileList = ref([]) // 文件列表
/** 打开弹窗 */
const open = async () => {
modelVisible.value = true
dialogVisible.value = true
resetForm()
}
defineExpose({ open }) // open
/** 重置表单 */
/** 提交表单 */
const submitForm = async () => {
//
if (!formRef) return
@ -98,7 +98,7 @@ const submitForm = async () => {
/** 文件上传成功 */
const emit = defineEmits(['success']) // success
const submitFormSuccess = async (response: any): Promise<void> => {
const submitFormSuccess = async (response: any) => {
if (response.code !== 0) {
message.error(response.msg)
formLoading.value = false

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="转派审批人" v-model="modelVisible" width="500">
<Dialog title="转派审批人" v-model="dialogVisible" width="500">
<el-form
ref="formRef"
:model="formData"
@ -20,7 +20,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -28,7 +28,7 @@
import * as TaskApi from '@/api/bpm/task'
import * as UserApi from '@/api/system/user'
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const formData = ref({
id: '',
@ -43,7 +43,7 @@ const userList = ref<any[]>([]) // 用户列表
/** 打开弹窗 */
const open = async (id: string) => {
modelVisible.value = true
dialogVisible.value = true
resetForm()
formData.value.id = id
//
@ -62,7 +62,7 @@ const submitForm = async () => {
formLoading.value = true
try {
await TaskApi.updateTaskAssignee(formData.value)
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="修改任务规则" v-model="modelVisible" width="600">
<Dialog title="修改任务规则" v-model="dialogVisible" width="600">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px">
<el-form-item label="任务名称" prop="taskDefinitionName">
<el-input v-model="formData.taskDefinitionName" placeholder="请输入流标标识" disabled />
@ -93,7 +93,7 @@
<!-- 操作按钮 -->
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -109,7 +109,7 @@ import * as UserGroupApi from '@/api/bpm/userGroup'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const formLoading = ref(false) // 12
const formData = ref({
type: Number(undefined),
@ -171,7 +171,7 @@ const open = async (modelId: string, row: TaskAssignRuleApi.TaskAssignVO) => {
formData.value.scripts.push(...row.options)
}
//
modelVisible.value = true
dialogVisible.value = true
//
roleOptions.value = await RoleApi.getSimpleRoleList()
@ -232,7 +232,7 @@ const submitForm = async () => {
await TaskAssignRuleApi.updateTaskAssignRule(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="详情" v-model="modelVisible" :scroll="true" :max-height="500" width="800">
<Dialog title="详情" v-model="dialogVisible" :scroll="true" :max-height="500" width="800">
<el-descriptions border :column="1">
<el-descriptions-item label="日志主键" min-width="120">
{{ detailData.id }}
@ -45,13 +45,13 @@ import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import * as ApiAccessLog from '@/api/infra/apiAccessLog'
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref() //
/** 打开弹窗 */
const open = async (data: ApiAccessLog.ApiAccessLogVO) => {
modelVisible.value = true
dialogVisible.value = true
//
detailLoading.value = true
try {

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="详情" v-model="modelVisible" :scroll="true" :max-height="500" width="800">
<Dialog title="详情" v-model="dialogVisible" :scroll="true" :max-height="500" width="800">
<el-descriptions border :column="1">
<el-descriptions-item label="日志主键" min-width="120">
{{ detailData.id }}
@ -60,13 +60,13 @@ import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import * as ApiErrorLog from '@/api/infra/apiErrorLog'
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref() //
/** 打开弹窗 */
const open = async (data: ApiErrorLog.ApiErrorLogVO) => {
modelVisible.value = true
dialogVisible.value = true
//
detailLoading.value = true
try {

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="导入表" v-model="modelVisible" width="800px">
<Dialog title="导入表" v-model="dialogVisible" width="800px">
<!-- 搜索栏 -->
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
<el-form-item label="数据源" prop="dataSourceConfigId">
@ -69,7 +69,7 @@ import * as DataSourceConfigApi from '@/api/infra/dataSourceConfig'
import { ElTable } from 'element-plus'
const message = useMessage() //
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const dbTableLoading = ref(true) //
const dbTableList = ref<CodegenApi.DatabaseTableVO[]>([]) //
const queryParams = reactive({
@ -103,7 +103,7 @@ const open = async () => {
//
dataSourceConfigList.value = await DataSourceConfigApi.getDataSourceConfigList()
queryParams.dataSourceConfigId = dataSourceConfigList.value[0].id as number
modelVisible.value = true
dialogVisible.value = true
//
await getList()
}
@ -111,7 +111,7 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 关闭弹窗 */
const close = () => {
modelVisible.value = false
dialogVisible.value = false
tableList.value = []
}

View File

@ -1,7 +1,7 @@
<template>
<Dialog
title="代码预览"
v-model="modelVisible"
v-model="dialogVisible"
align-center
width="80%"
class="app-infra-codegen-preview-container"
@ -61,7 +61,7 @@ import * as CodegenApi from '@/api/infra/codegen'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const loading = ref(false) //
const preview = reactive({
fileTree: [], //
@ -86,7 +86,7 @@ interface filesType {
/** 打开弹窗 */
const open = async (id: number) => {
modelVisible.value = true
dialogVisible.value = true
try {
loading.value = true
//

View File

@ -163,7 +163,7 @@ const queryParams = reactive({
const queryFormRef = ref() //
const dataSourceConfigList = ref<DataSourceConfigApi.DataSourceConfigVO[]>([]) //
/** 查询参数列表 */
/** 查询列表 */
const getList = async () => {
loading.value = true
try {

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -36,7 +36,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -47,8 +47,8 @@ import * as ConfigApi from '@/api/infra/config'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -71,8 +71,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -105,7 +105,7 @@ const submitForm = async () => {
await ConfigApi.updateConfig(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -55,7 +55,12 @@
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button type="primary" @click="openModal('create')" v-hasPermi="['infra:config:create']">
<el-button
type="primary"
plain
@click="openModal('create')"
v-hasPermi="['infra:config:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -22,7 +22,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -32,8 +32,8 @@ import * as DataSourceConfigApi from '@/api/infra/dataSourceConfig'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref<DataSourceConfigApi.DataSourceConfigVO>({
@ -53,8 +53,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -87,7 +87,7 @@ const submitForm = async () => {
await DataSourceConfigApi.updateDataSourceConfig(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -5,6 +5,7 @@
<el-form-item>
<el-button
type="primary"
plain
@click="openModal('create')"
v-hasPermi="['infra:data-source-config:create']"
>

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-upload
ref="uploadRef"
:limit="1"
@ -24,7 +24,7 @@
</el-upload>
<template #footer>
<el-button @click="submitFileForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -36,8 +36,8 @@ import { getAccessToken } from '@/utils/auth'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const url = import.meta.env.VITE_UPLOAD_URL
const headers = { Authorization: 'Bearer ' + getAccessToken() }
@ -46,8 +46,8 @@ const uploadRef = ref()
/** 打开弹窗 */
const openModal = async () => {
modelVisible.value = true
modelTitle.value = t('action.fileUpload')
dialogVisible.value = true
dialogTitle.value = t('action.fileUpload')
}
defineExpose({ openModal }) // openModal
@ -71,7 +71,7 @@ const submitFileForm = () => {
/** 文件上传成功处理 */
const handleFileSuccess = () => {
//
modelVisible.value = false
dialogVisible.value = false
formLoading.value = false
unref(uploadRef)?.clearFiles()
//

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -94,7 +94,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -105,8 +105,8 @@ import * as FileConfigApi from '@/api/infra/fileConfig'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -137,8 +137,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -171,7 +171,7 @@ const submitForm = async () => {
await FileConfigApi.updateFileConfig(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -35,6 +35,7 @@
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openModal('create')"
v-hasPermi="['infra:file-config:create']"
>

View File

@ -0,0 +1,71 @@
<template>
<Dialog title="任务详细" v-model="dialogVisible" width="700px">
<el-descriptions border :column="1">
<el-descriptions-item label="任务编号" min-width="60">
{{ detailData.id }}
</el-descriptions-item>
<el-descriptions-item label="任务名称">
{{ detailData.name }}
</el-descriptions-item>
<el-descriptions-item label="任务名称">
<dict-tag :type="DICT_TYPE.INFRA_JOB_STATUS" :value="detailData.status" />
</el-descriptions-item>
<el-descriptions-item label="处理器的名字">
{{ detailData.handlerName }}
</el-descriptions-item>
<el-descriptions-item label="处理器的参数">
{{ detailData.handlerParam }}
</el-descriptions-item>
<el-descriptions-item label="Cron 表达式">
{{ detailData.cronExpression }}
</el-descriptions-item>
<el-descriptions-item label="重试次数">
{{ detailData.retryCount }}
</el-descriptions-item>
<el-descriptions-item label="重试间隔">
{{ detailData.retryInterval + ' 毫秒' }}
</el-descriptions-item>
<el-descriptions-item label="监控超时时间">
{{ detailData.monitorTimeout > 0 ? detailData.monitorTimeout + ' 毫秒' : '未开启' }}
</el-descriptions-item>
<el-descriptions-item label="后续执行时间">
<el-timeline>
<el-timeline-item
v-for="(nextTime, index) in nextTimes"
:key="index"
:timestamp="formatDate(nextTime)"
>
{{ index + 1 }}
</el-timeline-item>
</el-timeline>
</el-descriptions-item>
</el-descriptions>
</Dialog>
</template>
<script setup lang="ts">
import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import * as JobApi from '@/api/infra/job'
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref({}) //
const nextTimes = ref([]) //
/** 打开弹窗 */
const open = async (id: number) => {
dialogVisible.value = true
//
if (id) {
detailLoading.value = true
try {
detailData.value = await JobApi.getJob(id)
//
nextTimes.value = await JobApi.getJobNextTimes(id)
} finally {
detailLoading.value = false
}
}
}
defineExpose({ open }) // open
</script>

View File

@ -1,6 +1,5 @@
<template>
<!-- 添加或修改定时任务对话框 -->
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -22,14 +21,7 @@
<el-input v-model="formData.handlerParam" placeholder="请输入处理器的参数" />
</el-form-item>
<el-form-item label="CRON 表达式" prop="cronExpression">
<el-input v-model="formData.cronExpression" placeholder="请输入CRON 表达式">
<template #append>
<el-button type="primary" @click="handleShowCron">
生成表达式
<i class="el-icon-time el-icon--right"></i>
</el-button>
</template>
</el-input>
<crontab v-model="formData.cronExpression" />
</el-form-item>
<el-form-item label="重试次数" prop="retryCount">
<el-input
@ -47,56 +39,28 @@
<el-input v-model="formData.monitorTimeout" placeholder="请输入监控超时时间,单位:毫秒" />
</el-form-item>
</el-form>
<!-- 操作按钮 -->
<template #footer>
<!-- 按钮保存 -->
<div class="dialog-footer">
<el-button type="primary" @click="submitForm" :loading="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
</div>
<el-button type="primary" @click="submitForm" :loading="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
<el-dialog
title="Cron表达式生成器"
v-model="openCron"
append-to-body
class="scrollbar"
destroy-on-close
>
<crontab @hide="openCron = false" @fill="crontabFill" :expression="expression" />
</el-dialog>
</template>
<script setup lang="ts" name="JobForm">
import * as JobApi from '@/api/infra/job'
const emit = defineEmits(['success', 'crontabFill']) // success
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const defaultFormData = {
const formData = ref({
id: undefined,
name: '',
status: 0,
handlerName: '',
handlerParam: '',
cronExpression: '',
retryCount: 0,
retryInterval: 0,
monitorTimeout: 0,
createTime: new Date()
}
const formData = ref({ ...defaultFormData })
// Cron
const openCron = ref(false)
//
const expression = ref('')
//
cronExpression: ''
})
const formRules = reactive({
name: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
handlerName: [{ required: true, message: '处理器的名字不能为空', trigger: 'blur' }],
@ -107,37 +71,25 @@ const formRules = reactive({
const formRef = ref() // Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await JobApi.getJobApi(id)
formData.value = await JobApi.getJob(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ openModal }) // openModal
defineExpose({ open }) // open
/** cron表达式按钮操作 */
const handleShowCron = () => {
console.info(123333333333)
expression.value = formData.value.cronExpression
openCron.value = true
}
// cron
const crontabFill = (expression: string) => {
formData.value.cronExpression = expression
emit('crontabFill', expression)
}
//
/** 提交按钮 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef) return
@ -148,13 +100,13 @@ const submitForm = async () => {
try {
const data = formData.value as unknown as JobApi.JobVO
if (formType.value === 'create') {
await JobApi.createJobApi(data)
await JobApi.createJob(data)
message.success(t('common.createSuccess'))
} else {
await JobApi.updateJobApi(data)
await JobApi.updateJob(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {
@ -165,7 +117,11 @@ const submitForm = async () => {
/** 重置表单 */
const resetForm = () => {
formData.value = {
...defaultFormData
id: undefined,
name: '',
handlerName: '',
handlerParam: '',
cronExpression: ''
}
formRef.value?.resetFields()
}

View File

@ -1,74 +0,0 @@
<template>
<!-- 调度日志详细 -->
<Dialog title="调度日志详细" v-model="modelVisible" width="700px" append-to-body>
<el-form ref="form" :model="formData" label-width="120px" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="日志编号:">{{ formData.id }}</el-form-item>
<el-form-item label="任务编号:">{{ formData.jobId }}</el-form-item>
<el-form-item label="处理器的名字:">{{ formData.handlerName }}</el-form-item>
<el-form-item label="处理器的参数:">{{ formData.handlerParam }}</el-form-item>
<el-form-item label="第几次执行:">{{ formData.executeIndex }}</el-form-item>
<el-form-item label="执行时间:">{{
parseTime(formData.beginTime) + ' ~ ' + parseTime(formData.endTime)
}}</el-form-item>
<el-form-item label="执行时长:">{{ formData.duration + ' 毫秒' }}</el-form-item>
<el-form-item label="任务状态:">
<dict-tag :type="DICT_TYPE.INFRA_JOB_LOG_STATUS" :value="formData.status" />
</el-form-item>
<el-form-item label="执行结果:">{{ formData.result }}</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="close"> </el-button>
</div>
</template>
</Dialog>
</template>
<script setup lang="ts" name="JobView">
import * as JobLogApi from '@/api/infra/jobLog'
import { DICT_TYPE } from '@/utils/dict'
import { parseTime } from './utils'
const emit = defineEmits(['success']) // success
const { t } = useI18n() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const formLoading = ref(false) // 12
const formData = ref({
id: undefined,
jobId: undefined,
handlerParam: '',
handlerName: '',
executeIndex: '',
beginTime: undefined,
endTime: undefined,
duration: true,
result: '',
status: undefined
})
/** 打开弹窗 */
const openModal = async (id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.detail')
//
if (id) {
formLoading.value = true
try {
formData.value = await JobLogApi.getJobLogApi(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ openModal }) // openModal
const close = () => {
emit('success')
}
</script>

View File

@ -1,19 +1,31 @@
<template>
<content-wrap>
<!-- 搜索栏 -->
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="100px">
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="100px"
>
<el-form-item label="任务名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入任务名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="任务状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable>
<el-select
v-model="queryParams.status"
placeholder="请选择任务状态"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getDictOptions(DICT_TYPE.INFRA_JOB_STATUS)"
v-for="dict in getIntDictOptions(DICT_TYPE.INFRA_JOB_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@ -26,6 +38,7 @@
placeholder="请输入处理器的名字"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
@ -34,7 +47,7 @@
<el-button
type="primary"
plain
@click="openModal('create')"
@click="openForm('create')"
v-hasPermi="['infra:job:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
@ -48,63 +61,66 @@
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
<el-button type="info" plain @click="handleJobLog" v-hasPermi="['infra:job:query']">
<Icon icon="ep:zoom-in" class="mr-5px" /> 执行日志
</el-button>
</el-form-item>
</el-form>
</content-wrap>
<!-- 列表 -->
<content-wrap>
<el-table v-loading="loading" :data="list">
<el-table-column label="任务编号" align="center" prop="id" />
<el-table-column label="任务名称" align="center" prop="name" />
<el-table-column label="任务状态" align="center" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.INFRA_JOB_STATUS" :value="scope.row.status" />
</template> </el-table-column
>>
</template>
</el-table-column>
<el-table-column label="处理器的名字" align="center" prop="handlerName" />
<el-table-column label="处理器的参数" align="center" prop="handlerParam" />
<el-table-column label="CRON 表达式" align="center" prop="cronExpression" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column label="操作" align="center" width="200">
<template #default="scope">
<el-button
type="primary"
link
icon="el-icon-edit"
@click="openModal('update', scope.row.id)"
@click="openForm('update', scope.row.id)"
v-hasPermi="['infra:job:update']"
>修改</el-button
>
修改
</el-button>
<el-button
type="primary"
link
icon="el-icon-check"
@click="handleChangeStatus(scope.row)"
v-hasPermi="['infra:job:update']"
>{{ scope.row.status === InfraJobStatusEnum.STOP ? '开启' : '暂停' }}</el-button
>
{{ scope.row.status === InfraJobStatusEnum.STOP ? '开启' : '暂停' }}
</el-button>
<el-button
type="danger"
link
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['infra:job:delete']"
>删除</el-button
>
删除
</el-button>
<el-dropdown
class="mt-1"
:teleported="true"
@command="(command) => handleCommand(command, scope.row)"
v-hasPermi="['infra:job:trigger', 'infra:job:query']"
>
<el-button link icon="el-icon-d-arrow-right">更多</el-button>
<el-button type="primary" link><Icon icon="ep:d-arrow-right" /> 更多</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="handleRun" v-if="hasPermi(['infra:job:trigger'])">
<el-dropdown-item command="handleRun" v-if="checkPermi(['infra:job:trigger'])">
执行一次
</el-dropdown-item>
<el-dropdown-item command="handleView" v-if="hasPermi(['infra:job:query'])">
<el-dropdown-item command="openDetail" v-if="checkPermi(['infra:job:query'])">
任务详细
</el-dropdown-item>
<el-dropdown-item command="handleJobLog" v-if="hasPermi(['infra:job:query'])">
<el-dropdown-item command="handleJobLog" v-if="checkPermi(['infra:job:query'])">
调度日志
</el-dropdown-item>
</el-dropdown-menu>
@ -114,8 +130,7 @@
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@ -124,23 +139,21 @@
</content-wrap>
<!-- 表单弹窗添加/修改 -->
<job-form ref="modalRef" @success="getList" />
<JobForm ref="formRef" @success="getList" />
<!-- 表单弹窗查看 -->
<job-view ref="viewModalRef" @success="getList" />
<JobDetail ref="detailRef" />
</template>
<script setup lang="ts" name="Job">
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
import JobForm from './form.vue'
import JobView from './view.vue'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { checkPermi } from '@/utils/permission'
import JobForm from './JobForm.vue'
import JobDetail from './JobDetail.vue'
import download from '@/utils/download'
import * as JobApi from '@/api/infra/job'
import { InfraJobStatusEnum } from '@/utils/constants'
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
const { t } = useI18n() //
const message = useMessage() //
const { push } = useRouter()
const { push } = useRouter() //
const loading = ref(true) //
const total = ref(0) //
@ -155,11 +168,11 @@ const queryParams = reactive({
const queryFormRef = ref() //
const exportLoading = ref(false) //
/** 查询参数列表 */
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await JobApi.getJobPageApi(queryParams)
const data = await JobApi.getJobPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
@ -167,30 +180,6 @@ const getList = async () => {
}
}
const handleChangeStatus = async (row: JobApi.JobVO) => {
const text = row.status === InfraJobStatusEnum.STOP ? '开启' : '关闭'
const status =
row.status === InfraJobStatusEnum.STOP ? InfraJobStatusEnum.NORMAL : InfraJobStatusEnum.STOP
message
.confirm('确认要' + text + '定时任务编号为"' + row.id + '"的数据项?', t('common.reminder'))
.then(async () => {
row.status =
row.status === InfraJobStatusEnum.NORMAL
? InfraJobStatusEnum.NORMAL
: InfraJobStatusEnum.STOP
await JobApi.updateJobStatusApi(row.id, status)
message.success(text + '成功')
await getList()
})
.catch(() => {
row.status =
row.status === InfraJobStatusEnum.NORMAL
? InfraJobStatusEnum.STOP
: InfraJobStatusEnum.NORMAL
})
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
@ -203,10 +192,47 @@ const resetQuery = () => {
handleQuery()
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await JobApi.exportJob(queryParams)
download.excel(data, '定时任务.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 添加/修改操作 */
const modalRef = ref()
const openModal = (type: string, id?: number) => {
modalRef.value.openModal(type, id)
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 修改状态操作 */
const handleChangeStatus = async (row: JobApi.JobVO) => {
try {
//
const text = row.status === InfraJobStatusEnum.STOP ? '开启' : '关闭'
await message.confirm(
'确认要' + text + '定时任务编号为"' + row.id + '"的数据项?',
t('common.reminder')
)
const status =
row.status === InfraJobStatusEnum.STOP ? InfraJobStatusEnum.NORMAL : InfraJobStatusEnum.STOP
await JobApi.updateJobStatus(row.id, status)
message.success(text + '成功')
//
await getList()
} catch {
//
row.status =
row.status === InfraJobStatusEnum.NORMAL ? InfraJobStatusEnum.STOP : InfraJobStatusEnum.NORMAL
}
}
/** 删除按钮操作 */
@ -215,43 +241,21 @@ const handleDelete = async (id: number) => {
//
await message.delConfirm()
//
await JobApi.deleteJobApi(id)
await JobApi.deleteJob(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 查看操作 */
const viewModalRef = ref()
const handleView = (rowId?: number) => {
viewModalRef.value.openModal(rowId)
}
//
const handleJobLog = (rowId?: number) => {
if (rowId) {
push('/job/job-log?id=' + rowId)
} else {
push('/job/job-log')
}
}
//
const handleRun = (row: JobApi.JobVO) => {
message.confirm('确认要立即执行一次' + row.name + '?', t('common.reminder')).then(async () => {
await JobApi.runJobApi(row.id)
message.success('执行成功')
await getList()
})
}
/** '更多'操作按钮 */
const handleCommand = (command, row) => {
switch (command) {
case 'handleRun':
handleRun(row)
break
case 'handleView':
handleView(row?.id)
case 'openDetail':
openDetail(row.id)
break
case 'handleJobLog':
handleJobLog(row?.id)
@ -261,36 +265,32 @@ const handleCommand = (command, row) => {
}
}
/** 导出按钮操作 */
const handleExport = async () => {
/** 执行一次 */
const handleRun = async (row: JobApi.JobVO) => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await JobApi.exportJobApi(queryParams)
download.excel(data, '定时任务.xls')
} catch {
} finally {
exportLoading.value = false
}
//
await message.confirm('确认要立即执行一次' + row.name + '?', t('common.reminder'))
//
await JobApi.runJobApi(row.id)
message.success('执行成功')
//
await getList()
} catch {}
}
// dropdown v-hasPermiwaringv-if
const hasPermi = (permiKeys: string[]) => {
const { wsCache } = useCache()
const all_permission = '*:*:*'
const permissions = wsCache.get(CACHE_KEY.USER).permissions
/** 查看操作 */
const detailRef = ref()
const openDetail = (id: number) => {
detailRef.value.open(id)
}
if (permiKeys && permiKeys instanceof Array && permiKeys.length > 0) {
const permissionFlag = permiKeys
const hasPermissions = permissions.some((permission: string) => {
return all_permission === permission || permissionFlag.includes(permission)
})
return hasPermissions
/** 跳转执行日志 */
const handleJobLog = (id: number) => {
if (id) {
push('/job/job-log?id=' + id)
} else {
push('/job/job-log')
}
return false
}
/** 初始化 **/

View File

@ -0,0 +1,57 @@
<template>
<Dialog title="任务详细" v-model="dialogVisible" width="700px">
<el-descriptions border :column="1">
<el-descriptions-item label="日志编号" min-width="60">
{{ detailData.id }}
</el-descriptions-item>
<el-descriptions-item label="任务编号">
{{ detailData.jobId }}
</el-descriptions-item>
<el-descriptions-item label="处理器的名字">
{{ detailData.handlerName }}
</el-descriptions-item>
<el-descriptions-item label="处理器的参数">
{{ detailData.handlerParam }}
</el-descriptions-item>
<el-descriptions-item label="第几次执行">
{{ detailData.executeIndex }}
</el-descriptions-item>
<el-descriptions-item label="执行时间">
{{ formatDate(detailData.beginTime) + ' ~ ' + formatDate(detailData.endTime) }}
</el-descriptions-item>
<el-descriptions-item label="执行时长">
{{ detailData.duration + ' 毫秒' }}
</el-descriptions-item>
<el-descriptions-item label="任务状态">
<dict-tag :type="DICT_TYPE.INFRA_JOB_LOG_STATUS" :value="detailData.status" />
</el-descriptions-item>
<el-descriptions-item label="执行结果">
{{ detailData.duration + ' result' }}
</el-descriptions-item>
</el-descriptions>
</Dialog>
</template>
<script setup lang="ts">
import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import * as JobLogApi from '@/api/infra/jobLog'
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref({}) //
/** 打开弹窗 */
const open = async (id: number) => {
dialogVisible.value = true
//
if (id) {
detailLoading.value = true
try {
detailData.value = await JobLogApi.getJobLog(id)
} finally {
detailLoading.value = false
}
}
}
defineExpose({ open }) // open
</script>

View File

@ -1,37 +1,52 @@
<template>
<content-wrap>
<!-- 搜索栏 -->
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="120px">
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="120px"
>
<el-form-item label="处理器的名字" prop="handlerName">
<el-input
v-model="queryParams.handlerName"
placeholder="请输入处理器的名字"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="开始执行时间" prop="beginTime">
<el-date-picker
clearable
v-model="queryParams.beginTime"
type="date"
value-format="YYYY-MM-DD"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择开始执行时间"
clearable
class="!w-240px"
/>
</el-form-item>
<el-form-item label="结束执行时间" prop="endTime">
<el-date-picker
clearable
v-model="queryParams.endTime"
type="date"
value-format="YYYY-MM-DD"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择结束执行时间"
clearable
:default-time="new Date('1 23:59:59')"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="任务状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable>
<el-select
v-model="queryParams.status"
placeholder="请选择任务状态"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getDictOptions(DICT_TYPE.INFRA_JOB_LOG_STATUS)"
v-for="dict in getIntDictOptions(DICT_TYPE.INFRA_JOB_LOG_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@ -52,16 +67,19 @@
</el-button>
</el-form-item>
</el-form>
</content-wrap>
<!-- 列表 -->
<content-wrap>
<el-table v-loading="loading" :data="list">
<el-table-column label="日志编号" align="center" prop="id" />
<el-table-column label="任务编号" align="center" prop="jobId" />
<el-table-column label="处理器的名字" align="center" prop="handlerName" />
<el-table-column label="处理器的参数" align="center" prop="handlerParam" />
<el-table-column label="第几次执行" align="center" prop="executeIndex" />
<el-table-column label="执行时间" align="center" width="180">
<el-table-column label="执行时间" align="center" width="170s">
<template #default="scope">
<span>{{ parseTime(scope.row.beginTime) + ' ~ ' + parseTime(scope.row.endTime) }}</span>
<span>{{ formatDate(scope.row.beginTime) + ' ~ ' + formatDate(scope.row.endTime) }}</span>
</template>
</el-table-column>
<el-table-column label="执行时长" align="center" prop="duration">
@ -74,40 +92,39 @@
<dict-tag :type="DICT_TYPE.INFRA_JOB_LOG_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
type="primary"
link
icon="el-icon-view"
@click="handleView(scope.row.id)"
:loading="exportLoading"
@click="openDetail(scope.row.id)"
v-hasPermi="['infra:job:query']"
>详细
>
详细
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
<!-- 分页组件 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</content-wrap>
<!-- 表单弹窗查看 -->
<log-view ref="viewModalRef" @success="getList" />
<JobLogDetail ref="detailRef" />
</template>
<script setup lang="ts" name="JobLog">
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import download from '@/utils/download'
import LogView from './JobLogView.vue'
import JobLogDetail from './JobLogDetail.vue'
import * as JobLogApi from '@/api/infra/jobLog'
import { parseTime } from './utils'
const message = useMessage() //
const { query } = useRoute() //
const loading = ref(true) //
const total = ref(0) //
@ -115,6 +132,7 @@ const list = ref([]) // 列表的数据
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
jobId: query.id,
handlerName: undefined,
beginTime: undefined,
endTime: undefined,
@ -123,15 +141,11 @@ const queryParams = reactive({
const queryFormRef = ref() //
const exportLoading = ref(false) //
/** 查询参数列表 */
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await JobLogApi.getJobLogPageApi({
...queryParams,
beginTime: queryParams.beginTime ? queryParams.beginTime + ' 00:00:00' : undefined,
endTime: queryParams.endTime ? queryParams.endTime + ' 23:59:59' : undefined
})
const data = await JobLogApi.getJobLogPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
@ -152,9 +166,9 @@ const resetQuery = () => {
}
/** 查看操作 */
const viewModalRef = ref()
const handleView = (rowId?: number) => {
viewModalRef.value.openModal(rowId)
const detailRef = ref()
const openDetail = (rowId?: number) => {
detailRef.value.open(rowId)
}
/** 导出按钮操作 */
@ -164,7 +178,7 @@ const handleExport = async () => {
await message.exportConfirm()
//
exportLoading.value = true
const data = await JobLogApi.exportJobLogApi(queryParams)
const data = await JobLogApi.exportJobLog(queryParams)
download.excel(data, '定时任务执行日志.xls')
} catch {
} finally {

View File

@ -1,44 +0,0 @@
export const parseTime = (time) => {
if (!time) {
return null
}
const format = '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time
.replace(new RegExp(/-/gm), '/')
.replace('T', ' ')
.replace(new RegExp(/\.[\d]{3}/gm), '')
}
if (typeof time === 'number' && time.toString().length === 10) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}

View File

@ -1,89 +0,0 @@
<template>
<!-- 任务详细 -->
<Dialog title="任务详细" v-model="modelVisible" width="700px" append-to-body>
<el-form ref="formRef" :model="formData" label-width="200px">
<el-row>
<el-col :span="24">
<el-form-item label="任务编号:">{{ formData.id }}</el-form-item>
<el-form-item label="任务名称:">{{ formData.name }}</el-form-item>
<el-form-item label="任务名称:">
<dict-tag :type="DICT_TYPE.INFRA_JOB_STATUS" :value="formData.status" />
</el-form-item>
<el-form-item label="处理器的名字:">{{ formData.handlerName }}</el-form-item>
<el-form-item label="处理器的参数:">{{ formData.handlerParam }}</el-form-item>
<el-form-item label="cron表达式">{{ formData.cronExpression }}</el-form-item>
<el-form-item label="重试次数:">{{ formData.retryCount }}</el-form-item>
<el-form-item label="重试间隔:">{{ formData.retryInterval + ' 毫秒' }}</el-form-item>
<el-form-item label="监控超时时间:">{{
formData.monitorTimeout > 0 ? formData.monitorTimeout + ' 毫秒' : '未开启'
}}</el-form-item>
<el-form-item label="后续执行时间:">
<el-timeline class="pt-3">
<el-timeline-item
v-for="(activity, index) in nextTimes"
:key="index"
:timestamp="parseTime(activity)"
>
{{ index + 1 }}
</el-timeline-item>
</el-timeline>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="close"> </el-button>
</div>
</template>
</Dialog>
</template>
<script setup lang="ts" name="JobView">
import * as JobApi from '@/api/infra/job'
import { parseTime } from './utils'
import { DICT_TYPE } from '@/utils/dict'
const emit = defineEmits(['success']) // success
const { t } = useI18n() //
const formRef = ref() // Ref
const modelVisible = ref(false) //
const modelTitle = ref('') //
const formLoading = ref(false) // 12
const formData = ref({
id: undefined,
name: '',
handlerParam: '',
handlerName: '',
cronExpression: '',
retryCount: true,
retryInterval: '',
monitorTimeout: 0,
status: 0
})
const nextTimes = ref([])
/** 打开弹窗 */
const openModal = async (id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.detail')
//
if (id) {
formLoading.value = true
try {
formData.value = await JobApi.getJobApi(id)
//
nextTimes.value = await JobApi.getJobNextTimesApi(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ openModal }) // openModal
const close = () => {
modelVisible.value = false
emit('success')
}
</script>

View File

@ -0,0 +1,147 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="80px"
v-loading="formLoading"
>
<el-form-item label="上级分类" prop="parentId">
<el-tree-select
v-model="formData.parentId"
:data="categoryTree"
:props="{ label: 'name', value: 'id' }"
:render-after-expand="false"
placeholder="请选择上级分类"
check-strictly
default-expand-all
/>
</el-form-item>
<el-form-item label="分类名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入分类名称" />
</el-form-item>
<el-form-item label="分类图片" prop="picUrl">
<UploadImg v-model="formData.picUrl" :limit="1" :is-show-tip="false" />
<div v-if="formData.parentId === 0" style="font-size: 10px"> 200x100 </div>
<div v-else style="font-size: 10px">推荐 100x100 图片分辨率</div>
</el-form-item>
<el-form-item label="分类排序" prop="sort">
<el-input-number v-model="formData.sort" controls-position="right" :min="0" />
</el-form-item>
<el-form-item label="开启状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="分类描述">
<el-input v-model="formData.description" type="textarea" placeholder="请输入分类描述" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants'
import { handleTree } from '@/utils/tree'
import * as ProductCategoryApi from '@/api/mall/product/category'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
name: '',
picUrl: '',
status: CommonStatusEnum.ENABLE,
description: ''
})
const formRules = reactive({
parentId: [{ required: true, message: '请选择上级分类', trigger: 'blur' }],
name: [{ required: true, message: '分类名称不能为空', trigger: 'blur' }],
picUrl: [{ required: true, message: '分类图片不能为空', trigger: 'blur' }],
sort: [{ required: true, message: '分类排序不能为空', trigger: 'blur' }],
status: [{ required: true, message: '开启状态不能为空', trigger: 'blur' }]
})
const formRef = ref() // Ref
const categoryTree = ref<any[]>([]) //
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await ProductCategoryApi.getCategory(id)
} finally {
formLoading.value = false
}
}
//
await getTree()
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
const data = formData.value as ProductCategoryApi.CategoryVO
if (formType.value === 'create') {
await ProductCategoryApi.createCategory(data)
message.success(t('common.createSuccess'))
} else {
await ProductCategoryApi.updateCategory(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
name: '',
picUrl: '',
status: CommonStatusEnum.ENABLE,
description: ''
}
formRef.value?.resetFields()
}
/** 获得分类树 */
const getTree = async () => {
const data = await ProductCategoryApi.getCategoryList({})
const tree = handleTree(data, 'id', 'parentId')
const menu = { id: 0, name: '顶级分类', children: tree }
categoryTree.value = [menu]
}
</script>

View File

@ -0,0 +1,144 @@
<template>
<!-- 搜索工作栏 -->
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="分类名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入分类名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['product:category:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" row-key="id" default-expand-all>
<el-table-column label="分类名称" prop="name" sortable />
<el-table-column label="分类图片" align="center" prop="picUrl">
<template #default="scope">
<img v-if="scope.row.picUrl" :src="scope.row.picUrl" alt="分类图片" class="h-100px" />
</template>
</el-table-column>
<el-table-column label="分类排序" align="center" prop="sort" />
<el-table-column label="开启状态" align="center" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
width="180"
:formatter="dateFormatter"
/>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['product:category:update']"
>
编辑
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['product:category:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<CategoryForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts" name="ProductCategory">
import { DICT_TYPE } from '@/utils/dict'
import { handleTree } from '@/utils/tree'
import { dateFormatter } from '@/utils/formatTime'
import * as ProductCategoryApi from '@/api/mall/product/category'
import CategoryForm from './CategoryForm.vue'
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const list = ref<any[]>([]) //
const queryParams = reactive({
name: undefined
})
const queryFormRef = ref() //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await ProductCategoryApi.getCategoryList(queryParams)
list.value = handleTree(data, 'id', 'parentId')
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await ProductCategoryApi.deleteCategory(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>

View File

@ -0,0 +1,95 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="80px"
v-loading="formLoading"
>
<el-form-item label="名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</div>
</template>
</Dialog>
</template>
<script setup lang="ts">
import * as PropertyApi from '@/api/mall/product/property'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
name: ''
})
const formRules = reactive({
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await PropertyApi.getProperty(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
const data = formData.value as PropertyApi.PropertyVO
if (formType.value === 'create') {
await PropertyApi.createProperty(data)
message.success(t('common.createSuccess'))
} else {
await PropertyApi.updateProperty(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
name: ''
}
formRef.value?.resetFields()
}
</script>

View File

@ -0,0 +1,160 @@
<template>
<!-- 搜索工作栏 -->
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
plain
type="primary"
@click="openForm('create')"
v-hasPermi="['product:property:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="名称" align="center" />
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column
label="创建时间"
align="center"
prop="createTime"
width="180"
:formatter="dateFormatter"
/>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['product:property:update']"
>
编辑
</el-button>
<el-button link type="primary">
<router-link :to="'/property/value/' + scope.row.id">属性值</router-link>
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['product:property:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<PropertyForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts" name="Config">
import { dateFormatter } from '@/utils/formatTime'
import * as PropertyApi from '@/api/mall/product/property'
import PropertyForm from './PropertyForm.vue'
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const total = ref(0) //
const list = ref([]) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: undefined,
createTime: []
})
const queryFormRef = ref() //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await PropertyApi.getPropertyPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await PropertyApi.deleteProperty(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>

View File

@ -0,0 +1,102 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="80px"
v-loading="formLoading"
>
<el-form-item label="属性编号" prop="category">
<el-input v-model="formData.propertyId" disabled="" />
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import * as PropertyApi from '@/api/mall/product/property'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
propertyId: undefined,
name: '',
remark: ''
})
const formRules = reactive({
propertyId: [{ required: true, message: '属性不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }]
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, propertyId: number, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
formData.value.propertyId = propertyId
//
if (id) {
formLoading.value = true
try {
formData.value = await PropertyApi.getPropertyValue(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
const data = formData.value as PropertyApi.PropertyValueVO
if (formType.value === 'create') {
await PropertyApi.createPropertyValue(data)
message.success(t('common.createSuccess'))
} else {
await PropertyApi.updatePropertyValue(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
propertyId: undefined,
name: '',
remark: ''
}
formRef.value?.resetFields()
}
</script>

View File

@ -0,0 +1,160 @@
<template>
<!-- 搜索工作栏 -->
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="属性项" prop="propertyId">
<el-select v-model="queryParams.propertyId" class="!w-240px">
<el-option
v-for="item in propertyOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
plain
type="primary"
@click="openForm('create')"
v-hasPermi="['product:property:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list">
<el-table-column label="编号" align="center" prop="id" />
<el-table-column label="名称" align="center" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<el-table-column
label="创建时间"
align="center"
prop="createTime"
width="180"
:formatter="dateFormatter"
/>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['product:property:update']"
>
编辑
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['product:property:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<ValueForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts" name="Config">
import { dateFormatter } from '@/utils/formatTime'
import * as PropertyApi from '@/api/mall/product/property'
import ValueForm from './ValueForm.vue'
const message = useMessage() //
const { t } = useI18n() //
const { params } = useRoute() //
const loading = ref(true) //
const total = ref(0) //
const list = ref([]) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
propertyId: Number(params.propertyId),
name: undefined
})
const queryFormRef = ref() //
const propertyOptions = ref([]) //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await PropertyApi.getPropertyValuePage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, queryParams.propertyId, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await PropertyApi.deleteProperty(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(async () => {
await getList()
//
propertyOptions.value = await PropertyApi.getPropertyList({})
})
</script>

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -64,7 +64,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -73,8 +73,8 @@ import * as AccountApi from '@/api/mp/account'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -98,8 +98,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -132,7 +132,7 @@ const submitForm = async () => {
await AccountApi.updateAccount(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -19,14 +19,8 @@
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<Icon icon="ep:search" class="mr-5px" />
搜索
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" />
重置
</el-button>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
</el-form-item>
</el-form>
</content-wrap>
@ -41,7 +35,6 @@
:key="item.articleId"
>
<wx-news :articles="item.content.newsItem" />
<!-- 操作 -->
<el-row justify="center" class="ope-row">
<el-button
type="danger"
@ -54,9 +47,8 @@
</el-row>
</div>
</div>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@ -66,24 +58,18 @@
</template>
<script setup lang="ts" name="freePublish">
import { getFreePublishPage, deleteFreePublish } from '@/api/mp/freePublish'
import * as FreePublishApi from '@/api/mp/freePublish'
import * as MpAccountApi from '@/api/mp/account'
import WxNews from '@/views/mp/components/wx-news/main.vue'
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const total = ref(0) //
const list = ref([]) //
interface QueryParams {
currentPage: number | undefined | string
pageNo: number | undefined | string
accountId: number | undefined | string
}
const queryParams: QueryParams = reactive({
currentPage: 1, //
pageNo: 1, //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
accountId: undefined //
})
const queryFormRef = ref() //
@ -96,25 +82,14 @@ const getList = async () => {
message.error('未选中公众号,无法查询已发表图文')
return false
}
// TODO await
loading.value = true
getFreePublishPage(queryParams)
.then((data) => {
console.log(data)
// thumbUrl picUrl wx-news
data.list.forEach((item) => {
console.log(item)
const newsItem = item.content.newsItem
newsItem.forEach((article) => {
article.picUrl = article.thumbUrl
})
})
list.value = data.list
total.value = data.total
})
.finally(() => {
loading.value = false
})
try {
loading.value = true
const data = await FreePublishApi.getFreePublishPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
@ -135,21 +110,15 @@ const resetQuery = () => {
/** 删除按钮操作 */
const handleDelete = async (item) => {
{
// TODO await
const articleId = item.articleId
const accountId = queryParams.accountId
message
.confirm('删除后用户将无法访问此页面,确定删除?')
.then(function () {
return deleteFreePublish(accountId, articleId)
})
.then(() => {
getList()
message.success('删除成功')
})
.catch(() => {})
}
try {
//
await message.delConfirm('删除后用户将无法访问此页面,确定删除?')
//
await FreePublishApi.deleteFreePublish(queryParams.accountId, item.articleId)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
onMounted(async () => {
@ -162,15 +131,6 @@ onMounted(async () => {
})
</script>
<style lang="scss" scoped>
.pagination {
float: right;
margin-right: 25px;
}
.add_but {
padding: 10px;
}
.ope-row {
margin-top: 5px;
text-align: center;

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -13,7 +13,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -22,8 +22,8 @@ import * as MpTagApi from '@/api/mp/tag'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -37,8 +37,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, accountId: number, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
formData.value.accountId = accountId
@ -72,7 +72,7 @@ const submitForm = async () => {
await MpTagApi.updateTag(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -12,9 +12,9 @@
<el-select v-model="queryParams.accountId" placeholder="请选择公众号" class="!w-240px">
<el-option
v-for="item in accountList"
:key="parseInt(item.id)"
:key="item.id"
:label="item.name"
:value="parseInt(item.id)"
:value="item.id"
/>
</el-select>
</el-form-item>
@ -28,21 +28,15 @@
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery">
<Icon icon="ep:search" class="mr-5px" />
搜索
</el-button>
<el-button @click="resetQuery">
<Icon icon="ep:refresh" class="mr-5px" />
重置
</el-button>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
</el-form-item>
<el-button type="primary" plain @click="openForm('create')" v-hasPermi="['mp:tag:create']">
<Icon icon="ep:plus" class="mr-5px" />
新增
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button type="success" plain @click="handleSync" v-hasPermi="['mp:tag:sync']">
<Icon icon="ep:refresh" class="mr-5px" />
同步
<Icon icon="ep:refresh" class="mr-5px" /> 同步
</el-button>
</el-form-item>
</el-form>
@ -99,7 +93,6 @@ import { dateFormatter } from '@/utils/formatTime'
import * as MpTagApi from '@/api/mp/tag'
import * as MpAccountApi from '@/api/mp/account'
import TagForm from './TagForm.vue'
const message = useMessage() //
const { t } = useI18n() //
@ -143,7 +136,6 @@ const resetQuery = () => {
queryFormRef.value.resetFields()
//
if (accountList.value.length > 0) {
// @ts-ignore
queryParams.accountId = accountList.value[0].id
}
handleQuery()
@ -184,7 +176,6 @@ onMounted(async () => {
accountList.value = await MpAccountApi.getSimpleAccountList()
//
if (accountList.value.length > 0) {
// @ts-ignore
queryParams.accountId = accountList.value[0].id
}
await getList()

View File

@ -0,0 +1,110 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px">
<el-form-item label="商户全称" prop="name">
<el-input v-model="formData.name" placeholder="请输入商户全称" />
</el-form-item>
<el-form-item label="商户简称" prop="shortName">
<el-input v-model="formData.shortName" placeholder="请输入商户简称" />
</el-form-item>
<el-form-item label="开启状态" prop="status">
<el-select v-model="formData.status" placeholder="请选择状态" clearable>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import * as MerchantApi from '@/api/pay/merchant'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
name: '',
shortName: '',
status: CommonStatusEnum.ENABLE,
remark: ''
})
const formRules = reactive({
name: [{ required: true, message: '商户名称不能为空', trigger: 'blur' }],
shortName: [{ required: true, message: '商户简称不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await MerchantApi.getMerchant(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
const data = formData.value as unknown as MerchantApi.MerchantVO
if (formType.value === 'create') {
await MerchantApi.createMerchant(data)
message.success(t('common.createSuccess'))
} else {
await MerchantApi.updateMerchant(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
name: '',
shortName: '',
status: CommonStatusEnum.ENABLE,
remark: ''
}
formRef.value?.resetFields()
}
</script>

View File

@ -1,153 +1,242 @@
<template>
<ContentWrap>
<!-- 列表 -->
<XTable @register="registerTable">
<template #toolbar_buttons>
<!-- 操作新增 -->
<XButton
<content-wrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="商户号" prop="no">
<el-input v-model="queryParams.no" placeholder="请输入商户号" clearable class="!w-240px" />
</el-form-item>
<el-form-item label="商户全称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入商户全称"
clearable
class="!w-240px"
/>
</el-form-item>
<el-form-item label="商户简称" prop="shortName">
<el-input
v-model="queryParams.shortName"
placeholder="请输入商户简称"
clearable
class="!w-240px"
/>
</el-form-item>
<el-form-item label="开启状态" prop="status">
<el-select v-model="queryParams.status" placeholder="字典状态" clearable class="!w-240px">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="queryParams.remark"
placeholder="请输入备注"
clearable
class="!w-240px"
/>
</el-form-item>
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
value-format="YYYY-MM-DD HH:mm:ss"
type="datetimerange"
start-placeholder="开始日期"
end-placeholder="结束日期"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
plain
type="primary"
preIcon="ep:zoom-in"
:title="t('action.add')"
@click="openForm('create')"
v-hasPermi="['pay:merchant:create']"
@click="handleCreate()"
/>
<!-- 操作导出 -->
<XButton
type="warning"
preIcon="ep:download"
:title="t('action.export')"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['pay:merchant:export']"
@click="exportList('商户列表.xls')"
/>
</template>
<template #actionbtns_default="{ row }">
<!-- 操作修改 -->
<XTextButton
preIcon="ep:edit"
:title="t('action.edit')"
v-hasPermi="['pay:merchant:update']"
@click="handleUpdate(row.id)"
/>
<!-- 操作详情 -->
<XTextButton
preIcon="ep:view"
:title="t('action.detail')"
v-hasPermi="['pay:merchant:query']"
@click="handleDetail(row.id)"
/>
<!-- 操作删除 -->
<XTextButton
preIcon="ep:delete"
:title="t('action.del')"
v-hasPermi="['pay:merchant:delete']"
@click="deleteData(row.id)"
/>
</template>
</XTable>
</ContentWrap>
<XModal v-model="dialogVisible" :title="dialogTitle">
<!-- 对话框(添加 / 修改) -->
<Form
v-if="['create', 'update'].includes(actionType)"
:schema="allSchemas.formSchema"
:rules="rules"
ref="formRef"
/>
<!-- 对话框(详情) -->
<Descriptions
v-if="actionType === 'detail'"
:schema="allSchemas.detailSchema"
:data="detailData"
/>
<!-- 操作按钮 -->
<template #footer>
<!-- 按钮保存 -->
<XButton
v-if="['create', 'update'].includes(actionType)"
type="primary"
:title="t('action.save')"
:loading="actionLoading"
@click="submitForm()"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</content-wrap>
<!-- 列表 -->
<content-wrap>
<el-table v-loading="loading" :data="list">
<el-table-column label="商户编号" align="center" prop="id" />
<el-table-column label="商户号" align="center" prop="no" />
<el-table-column label="商户全称" align="center" prop="name" />
<el-table-column label="商户简称" align="center" prop="shortName" />
<el-table-column label="开启状态" align="center" prop="status">
<template #default="scope">
<el-switch
v-model="scope.row.status"
:active-value="0"
:inactive-value="1"
@change="handleStatusChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180"
/>
<!-- 按钮关闭 -->
<XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
</template>
</XModal>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['pay:merchant:update']"
>
修改
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['pay:merchant:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</content-wrap>
<!-- 表单弹窗添加/修改 -->
<MerchantForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts" name="Merchant">
import type { FormExpose } from '@/components/Form'
import { rules, allSchemas } from './merchant.data'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as MerchantApi from '@/api/pay/merchant'
const { t } = useI18n() //
import MerchantForm from './MerchantForm.vue'
const message = useMessage() //
//
const [registerTable, { reload, deleteData, exportList }] = useXTable({
allSchemas: allSchemas,
getListApi: MerchantApi.getMerchantPageApi,
deleteApi: MerchantApi.deleteMerchantApi,
exportListApi: MerchantApi.exportMerchantApi
const { t } = useI18n() //
const loading = ref(true) //
const total = ref(0) //
const list = ref([]) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: '',
shortName: '',
status: undefined
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
// ========== CRUD ==========
const actionLoading = ref(false) //
const actionType = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('edit') //
const formRef = ref<FormExpose>() // Ref
const detailData = ref() // Ref
//
const setDialogTile = (type: string) => {
dialogTitle.value = t('action.' + type)
actionType.value = type
dialogVisible.value = true
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await MerchantApi.getMerchantPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
//
const handleCreate = () => {
setDialogTile('create')
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
//
const handleUpdate = async (rowId: number) => {
setDialogTile('update')
//
const res = await MerchantApi.getMerchantApi(rowId)
unref(formRef)?.setValues(res)
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
//
const handleDetail = async (rowId: number) => {
setDialogTile('detail')
const res = await MerchantApi.getMerchantApi(rowId)
detailData.value = res
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
//
const submitForm = async () => {
const elForm = unref(formRef)?.getElFormRef()
if (!elForm) return
elForm.validate(async (valid) => {
if (valid) {
actionLoading.value = true
//
try {
const data = unref(formRef)?.formModel as MerchantApi.MerchantVO
if (actionType.value === 'create') {
await MerchantApi.createMerchantApi(data)
message.success(t('common.createSuccess'))
} else {
await MerchantApi.updateMerchantApi(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
} finally {
actionLoading.value = false
//
await reload()
}
}
})
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await MerchantApi.deleteMerchant(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 修改状态操作 */
const handleStatusChange = async (row: MerchantApi.MerchantVO) => {
try {
//
const text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用'
await message.confirm('确认要"' + text + '""' + row.name + '"商户吗?', t('common.reminder'))
//
await MerchantApi.updateMerchantStatus(row.id, row.status)
//
await getList()
} catch {
//
row.status =
row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE : CommonStatusEnum.ENABLE
}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await MerchantApi.exportMerchant(queryParams)
download.excel(data, '商户信息.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>

View File

@ -1,70 +0,0 @@
import type { VxeCrudSchema } from '@/hooks/web/useVxeCrudSchemas'
const { t } = useI18n() // 国际化
// 表单校验
export const rules = reactive({
no: [required],
name: [required],
shortName: [required],
status: [required]
})
// CrudSchema
const crudSchemas = reactive<VxeCrudSchema>({
primaryKey: 'id',
primaryType: 'seq',
primaryTitle: '商户编号',
action: true,
columns: [
{
title: '商户号',
field: 'no',
isSearch: true
},
{
title: '商户全称',
field: 'code',
isSearch: true
},
{
title: '商户简称',
field: 'shortName',
isSearch: true
},
{
title: t('common.status'),
field: 'status',
dictType: DICT_TYPE.COMMON_STATUS,
dictClass: 'number',
isSearch: true
},
{
title: t('form.remark'),
field: 'remark',
isTable: false,
form: {
component: 'Input',
componentProps: {
type: 'textarea',
rows: 4
},
colProps: {
span: 24
}
}
},
{
title: t('common.createTime'),
field: 'createTime',
formatter: 'formatDate',
isForm: false,
search: {
show: true,
itemRender: {
name: 'XDataTimePicker'
}
}
}
]
})
export const { allSchemas } = useVxeCrudSchemas(crudSchemas)

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="IP 查询" v-model="modelVisible">
<Dialog title="IP 查询" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -16,7 +16,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -24,7 +24,7 @@
import * as AreaApi from '@/api/system/area'
const message = useMessage() //
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const formData = ref({
ip: '',
@ -37,7 +37,7 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const openModal = async () => {
modelVisible.value = true
dialogVisible.value = true
resetForm()
}
defineExpose({ openModal }) // openModal

View File

@ -1,7 +1,7 @@
<template>
<!-- 操作栏 -->
<content-wrap>
<el-button type="primary" @click="openModal()">
<el-button type="primary" plain @click="openModal()">
<Icon icon="ep:plus" class="mr-5px" /> IP 查询
</el-button>
</content-wrap>

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -58,7 +58,7 @@
</el-form>
<template #footer>
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -71,8 +71,8 @@ import { CommonStatusEnum } from '@/utils/constants'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -101,8 +101,8 @@ const userList = ref<UserApi.UserVO[]>([]) // 用户列表
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -139,7 +139,7 @@ const submitForm = async () => {
await DeptApi.updateDeptApi(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -51,13 +51,7 @@
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading="loading"
:data="list"
row-key="id"
v-if="refreshTable"
:default-expand-all="isExpandAll"
>
<el-table v-loading="loading" :data="list" row-key="id" default-expand-all v-if="refreshTable">
<el-table-column prop="name" label="部门名称" width="260" />
<el-table-column prop="leader" label="负责人" width="120">
<template #default="scope">

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -52,7 +52,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -63,8 +63,8 @@ import { CommonStatusEnum } from '@/utils/constants'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -115,8 +115,8 @@ const colorTypeOptions = readonly([
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -149,7 +149,7 @@ const submitForm = async () => {
await DictDataApi.updateDictData(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -180,7 +180,7 @@ const handleExport = async () => {
await message.exportConfirm()
//
exportLoading.value = true
const data = await DictDataApi.exportDictDataApi(queryParams)
const data = await DictDataApi.exportDictData(queryParams)
download.excel(data, '字典数据.xls')
} catch {
} finally {

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -34,7 +34,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -46,8 +46,8 @@ import { CommonStatusEnum } from '@/utils/constants'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -65,8 +65,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -99,7 +99,7 @@ const submitForm = async () => {
await DictTypeApi.updateDictType(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -41,7 +41,6 @@
v-model="queryParams.createTime"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
@ -51,7 +50,12 @@
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button type="primary" @click="openModal('create')" v-hasPermi="['system:dict:create']">
<el-button
type="primary"
plain
@click="openModal('create')"
v-hasPermi="['system:dict:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -22,7 +22,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -32,8 +32,8 @@ import * as ErrorCodeApi from '@/api/system/errorCode'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
//
@ -54,8 +54,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -88,7 +88,7 @@ const submitForm = async () => {
await ErrorCodeApi.updateErrorCodeApi(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -61,6 +61,7 @@
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openModal('create')"
v-hasPermi="['system:error-code:create']"
>
@ -121,8 +122,7 @@
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="详情" v-model="modelVisible" width="800">
<Dialog title="详情" v-model="dialogVisible" width="800">
<el-descriptions border :column="1">
<el-descriptions-item label="日志编号" min-width="120">
{{ detailData.id }}
@ -30,13 +30,13 @@ import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import * as LoginLogApi from '@/api/system/loginLog'
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref() //
/** 打开弹窗 */
const open = async (data: LoginLogApi.LoginLogVO) => {
modelVisible.value = true
dialogVisible.value = true
//
detailLoading.value = true
try {

View File

@ -1,9 +1,9 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<Form ref="formRef" :schema="allSchemas.formSchema" :rules="rules" v-loading="formLoading" />
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -14,16 +14,16 @@ import { rules, allSchemas } from './account.data'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formRef = ref() // Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
//
if (id) {
@ -56,7 +56,7 @@ const submitForm = async () => {
await MailAccountApi.updateMailAccount(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -6,6 +6,7 @@
<template #actionMore>
<el-button
type="primary"
plain
@click="openModal('create')"
v-hasPermi="['system:mail-account:create']"
>

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="详情" v-model="modelVisible" :scroll="true" :max-height="500">
<Dialog title="详情" v-model="dialogVisible" :scroll="true" :max-height="500">
<Descriptions :schema="allSchemas.detailSchema" :data="detailData">
<!-- 展示 HTML 内容 -->
<template #templateContent="{ row }">
@ -12,13 +12,13 @@
import * as MailLogApi from '@/api/system/mail/log'
import { allSchemas } from './log.data'
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref() //
/** 打开弹窗 */
const openModal = async (id: number) => {
modelVisible.value = true
dialogVisible.value = true
//
detailLoading.value = true
try {

View File

@ -1,9 +1,9 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible" :scroll="true" :width="800" :max-height="500">
<Dialog :title="dialogTitle" v-model="dialogVisible" :scroll="true" :width="800" :max-height="500">
<Form ref="formRef" :schema="allSchemas.formSchema" :rules="rules" v-loading="formLoading" />
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -14,16 +14,16 @@ import { rules, allSchemas } from './template.data'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formRef = ref() // Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
//
if (id) {
@ -56,7 +56,7 @@ const submitForm = async () => {
await MailTemplateApi.updateMailTemplate(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -6,6 +6,7 @@
<template #actionMore>
<el-button
type="primary"
plain
@click="openModal('create')"
v-hasPermi="['system:mail-account:create']"
>

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="测试" v-model="modelVisible">
<Dialog title="测试" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -27,7 +27,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -36,7 +36,7 @@ import * as MailTemplateApi from '@/api/system/mail/template'
const message = useMessage() //
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const formLoading = ref(false) // 12
const formData = ref({
content: '',
@ -54,7 +54,7 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const openModal = async (id: number) => {
modelVisible.value = true
dialogVisible.value = true
resetForm()
//
formLoading.value = true
@ -92,7 +92,7 @@ const submitForm = async () => {
if (logId) {
message.success('提交发送成功!发送结果,见发送日志编号:' + logId)
}
modelVisible.value = false
dialogVisible.value = false
} finally {
formLoading.value = false
}

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -108,7 +108,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -122,8 +122,8 @@ const { wsCache } = useCache()
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -152,8 +152,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, id?: number, parentId?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
if (parentId) {
@ -205,7 +205,7 @@ const submitForm = async () => {
await MenuApi.updateMenu(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible" width="800">
<Dialog :title="dialogTitle" v-model="dialogVisible" width="800">
<el-form
ref="formRef"
:model="formData"
@ -39,7 +39,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -49,8 +49,8 @@ import * as NoticeApi from '@/api/system/notice'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -71,8 +71,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -105,7 +105,7 @@ const submitForm = async () => {
await NoticeApi.updateNotice(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -37,6 +37,7 @@
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openModal('create')"
v-hasPermi="['system:notice:create']"
>
@ -114,11 +115,11 @@ const loading = ref(true) // 列表的加载中
const total = ref(0) //
const list = ref([]) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
title: '',
type: undefined,
status: undefined,
pageNo: 1,
pageSize: 100
status: undefined
})
const queryFormRef = ref() //
@ -127,7 +128,6 @@ const getList = async () => {
loading.value = true
try {
const data = await NoticeApi.getNoticePage(queryParams)
list.value = data.list
total.value = data.total
} finally {

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="详情" v-model="modelVisible" :scroll="true" :max-height="500">
<Dialog title="详情" v-model="dialogVisible" :scroll="true" :max-height="500">
<el-descriptions border :column="1">
<el-descriptions-item label="编号" min-width="120">
{{ detailData.id }}
@ -45,13 +45,13 @@ import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import * as NotifyMessageApi from '@/api/system/notify/message'
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref() //
/** 打开弹窗 */
const open = async (data: NotifyMessageApi.NotifyMessageVO) => {
modelVisible.value = true
dialogVisible.value = true
//
detailLoading.value = true
try {

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="消息详情" v-model="modelVisible" :scroll="true" :max-height="500">
<Dialog title="消息详情" v-model="dialogVisible" :scroll="true" :max-height="500">
<el-descriptions border :column="1">
<el-descriptions-item label="发送人">
{{ detailData.templateNickname }}
@ -27,13 +27,13 @@ import { DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import * as NotifyMessageApi from '@/api/system/notify/message'
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref() //
/** 打开弹窗 */
const open = async (data: NotifyMessageApi.NotifyMessageVO) => {
modelVisible.value = true
dialogVisible.value = true
//
detailLoading.value = true
try {

View File

@ -46,7 +46,7 @@
</ContentWrap>
<!-- 添加/修改的弹窗 -->
<XModal id="templateModel" :loading="modelLoading" v-model="modelVisible" :title="modelTitle">
<XModal id="templateModel" :loading="modelLoading" v-model="dialogVisible" :title="dialogTitle">
<!-- 表单添加/修改 -->
<Form
ref="formRef"
@ -70,7 +70,7 @@
@click="submitForm()"
/>
<!-- 按钮关闭 -->
<XButton :loading="actionLoading" :title="t('dialog.close')" @click="modelVisible = false" />
<XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
</template>
</XModal>
@ -132,8 +132,8 @@ const [registerTable, { reload, deleteData }] = useXTable({
})
//
const modelVisible = ref(false) //
const modelTitle = ref('edit') //
const dialogVisible = ref(false) //
const dialogTitle = ref('edit') //
const modelLoading = ref(false) // loading
const actionType = ref('') //
const actionLoading = ref(false) // Loading
@ -143,9 +143,9 @@ const detailData = ref() // 详情 Ref
//
const setDialogTile = (type: string) => {
modelLoading.value = true
modelTitle.value = t('action.' + type)
dialogTitle.value = t('action.' + type)
actionType.value = type
modelVisible.value = true
dialogVisible.value = true
}
//
@ -188,7 +188,7 @@ const submitForm = async () => {
await NotifyTemplateApi.updateNotifyTemplateApi(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
} finally {
actionLoading.value = false
//

View File

@ -1,10 +1,10 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible" width="800">
<Dialog :title="dialogTitle" v-model="dialogVisible" scroll max-height="500px">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="120px"
label-width="160px"
v-loading="formLoading"
>
<el-form-item label="客户端编号" prop="secret">
@ -25,11 +25,12 @@
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getDictOptions(DICT_TYPE.COMMON_STATUS)"
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="parseInt(dict.value)"
>{{ dict.label }}</el-radio
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="访问令牌的有效期" prop="accessTokenValiditySeconds">
@ -47,7 +48,7 @@
style="width: 500px"
>
<el-option
v-for="dict in getDictOptions(DICT_TYPE.SYSTEM_OAUTH2_GRANT_TYPE)"
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_OAUTH2_GRANT_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@ -137,22 +138,20 @@
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
</div>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants'
import * as ClientApi from '@/api/system/oauth2/client'
import UploadImg from '@/components/UploadFile'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -162,7 +161,7 @@ const formData = ref({
name: undefined,
logo: undefined,
description: undefined,
status: DICT_TYPE.COMMON_STATUS,
status: CommonStatusEnum.ENABLE,
accessTokenValiditySeconds: 30 * 60,
refreshTokenValiditySeconds: 30 * 24 * 60,
redirectUris: [],
@ -191,22 +190,22 @@ const formRules = reactive({
const formRef = ref() // Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await ClientApi.getOAuth2ClientApi(id)
formData.value = await ClientApi.getOAuth2Client(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ openModal }) // openModal
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
@ -220,13 +219,13 @@ const submitForm = async () => {
try {
const data = formData.value as unknown as ClientApi.OAuth2ClientVO
if (formType.value === 'create') {
await ClientApi.createOAuth2ClientApi(data)
await ClientApi.createOAuth2Client(data)
message.success(t('common.createSuccess'))
} else {
await ClientApi.updateOAuth2ClientApi(data)
await ClientApi.updateOAuth2Client(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {
@ -243,7 +242,7 @@ const resetForm = () => {
name: undefined,
logo: undefined,
description: undefined,
status: DICT_TYPE.COMMON_STATUS,
status: CommonStatusEnum.ENABLE,
accessTokenValiditySeconds: 30 * 60,
refreshTokenValiditySeconds: 30 * 24 * 60,
redirectUris: [],

View File

@ -1,206 +1,185 @@
<template>
<ContentWrap>
<!-- 列表 -->
<XTable @register="registerTable">
<template #toolbar_buttons>
<!-- 操作新增 -->
<XButton
type="primary"
preIcon="ep:zoom-in"
:title="t('action.add')"
v-hasPermi="['system:oauth2-client:create']"
@click="handleCreate()"
/>
</template>
<template #accessTokenValiditySeconds_default="{ row }">
{{ row.accessTokenValiditySeconds + '秒' }}
</template>
<template #refreshTokenValiditySeconds_default="{ row }">
{{ row.refreshTokenValiditySeconds + '秒' }}
</template>
<template #authorizedGrantTypes_default="{ row }">
<el-tag
:disable-transitions="true"
:key="index"
v-for="(authorizedGrantType, index) in row.authorizedGrantTypes"
:index="index"
>
{{ authorizedGrantType }}
</el-tag>
</template>
<template #actionbtns_default="{ row }">
<!-- 操作修改 -->
<XTextButton
preIcon="ep:edit"
:title="t('action.edit')"
v-hasPermi="['system:oauth2-client:update']"
@click="handleUpdate(row.id)"
/>
<!-- 操作详情 -->
<XTextButton
preIcon="ep:view"
:title="t('action.detail')"
v-hasPermi="['system:oauth2-client:query']"
@click="handleDetail(row.id)"
/>
<!-- 操作删除 -->
<XTextButton
preIcon="ep:delete"
:title="t('action.del')"
v-hasPermi="['system:oauth2-client:delete']"
@click="deleteData(row.id)"
/>
</template>
</XTable>
</ContentWrap>
<!-- 弹窗 -->
<XModal id="postModel" v-model="dialogVisible" :title="dialogTitle">
<!-- 表单添加/修改 -->
<Form
ref="formRef"
v-if="['create', 'update'].includes(actionType)"
:schema="allSchemas.formSchema"
:rules="rules"
/>
<!-- 表单详情 -->
<Descriptions
v-if="actionType === 'detail'"
:schema="allSchemas.detailSchema"
:data="detailData"
<!-- 搜索 -->
<content-wrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<template #accessTokenValiditySeconds="{ row }">
{{ row.accessTokenValiditySeconds + '秒' }}
</template>
<template #refreshTokenValiditySeconds="{ row }">
{{ row.refreshTokenValiditySeconds + '秒' }}
</template>
<template #authorizedGrantTypes="{ row }">
<el-tag
:disable-transitions="true"
:key="index"
v-for="(authorizedGrantType, index) in row.authorizedGrantTypes"
:index="index"
<el-form-item label="应用名" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入应用名"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
plain
type="primary"
@click="openForm('create')"
v-hasPermi="['system:oauth2-client:create']"
>
{{ authorizedGrantType }}
</el-tag>
</template>
<template #scopes="{ row }">
<el-tag
:disable-transitions="true"
:key="index"
v-for="(scopes, index) in row.scopes"
:index="index"
>
{{ scopes }}
</el-tag>
</template>
<template #autoApproveScopes="{ row }">
<el-tag
:disable-transitions="true"
:key="index"
v-for="(autoApproveScopes, index) in row.autoApproveScopes"
:index="index"
>
{{ autoApproveScopes }}
</el-tag>
</template>
<template #redirectUris="{ row }">
<el-tag
:disable-transitions="true"
:key="index"
v-for="(redirectUris, index) in row.redirectUris"
:index="index"
>
{{ redirectUris }}
</el-tag>
</template>
</Descriptions>
<template #footer>
<!-- 按钮保存 -->
<XButton
v-if="['create', 'update'].includes(actionType)"
type="primary"
:title="t('action.save')"
:loading="actionLoading"
@click="submitForm()"
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
</el-form-item>
</el-form>
</content-wrap>
<!-- 列表 -->
<content-wrap>
<el-table v-loading="loading" :data="list">
<el-table-column label="客户端编号" align="center" prop="clientId" />
<el-table-column label="客户端密钥" align="center" prop="secret" />
<el-table-column label="应用名" align="center" prop="name" />
<el-table-column label="应用图标" align="center" prop="logo">
<template #default="scope">
<img width="40px" height="40px" :src="scope.row.logo" />
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="访问令牌的有效期" align="center" prop="accessTokenValiditySeconds">
<template #default="scope">{{ scope.row.accessTokenValiditySeconds }} </template>
</el-table-column>
<el-table-column label="刷新令牌的有效期" align="center" prop="refreshTokenValiditySeconds">
<template #default="scope">{{ scope.row.refreshTokenValiditySeconds }} </template>
</el-table-column>
<el-table-column label="授权类型" align="center" prop="authorizedGrantTypes">
<template #default="scope">
<el-tag
:disable-transitions="true"
:key="index"
v-for="(authorizedGrantType, index) in scope.row.authorizedGrantTypes"
:index="index"
>
{{ authorizedGrantType }}
</el-tag>
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
width="180"
:formatter="dateFormatter"
/>
<!-- 按钮关闭 -->
<XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
</template>
</XModal>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['system:oauth2-client:update']"
>
编辑
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['system:oauth2-client:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</content-wrap>
<!-- 表单弹窗添加/修改 -->
<ClientForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts" name="Client">
import type { FormExpose } from '@/components/Form'
// import
<script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import * as ClientApi from '@/api/system/oauth2/client'
const { t } = useI18n() //
import ClientForm from './ClientForm.vue'
const message = useMessage() //
const { t } = useI18n() //
//
const [registerTable, { reload, deleteData }] = useXTable({
allSchemas: allSchemas,
getListApi: ClientApi.getOAuth2ClientPageApi,
deleteApi: ClientApi.deleteOAuth2ClientApi
const loading = ref(true) //
const total = ref(0) //
const list = ref([]) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: null,
status: null
})
//
const dialogVisible = ref(false) //
const dialogTitle = ref('edit') //
const actionType = ref('') //
const actionLoading = ref(false) // Loading
const formRef = ref<FormExpose>() // Ref
const detailData = ref() // Ref
//
const setDialogTile = (type: string) => {
dialogTitle.value = t('action.' + type)
actionType.value = type
dialogVisible.value = true
const queryFormRef = ref() //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await ClientApi.getOAuth2ClientPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
//
const handleCreate = () => {
setDialogTile('create')
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
//
const handleUpdate = async (rowId: number) => {
setDialogTile('update')
//
const res = await ClientApi.getOAuth2ClientApi(rowId)
unref(formRef)?.setValues(res)
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
//
const handleDetail = async (rowId: number) => {
setDialogTile('detail')
const res = await ClientApi.getOAuth2ClientApi(rowId)
detailData.value = res
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
// /
const submitForm = async () => {
const elForm = unref(formRef)?.getElFormRef()
if (!elForm) return
elForm.validate(async (valid) => {
if (valid) {
actionLoading.value = true
//
try {
const data = unref(formRef)?.formModel as ClientApi.OAuth2ClientVO
if (actionType.value === 'create') {
await ClientApi.createOAuth2ClientApi(data)
message.success(t('common.createSuccess'))
} else {
await ClientApi.updateOAuth2ClientApi(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
} finally {
actionLoading.value = false
//
await reload()
}
}
})
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await ClientApi.deleteOAuth2Client(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="详情" v-model="modelVisible" :scroll="true" :max-height="500" width="800">
<Dialog title="详情" v-model="dialogVisible" :scroll="true" :max-height="500" width="800">
<el-descriptions border :column="1">
<el-descriptions-item label="日志主键" min-width="120">
{{ detailData.id }}
@ -61,13 +61,13 @@
import { formatDate } from '@/utils/formatTime'
import * as OperateLogApi from '@/api/system/operatelog'
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref() //
/** 打开弹窗 */
const openModal = async (data: OperateLogApi.OperateLogVO) => {
modelVisible.value = true
dialogVisible.value = true
//
detailLoading.value = true
try {

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible" width="800">
<Dialog :title="dialogTitle" v-model="dialogVisible" width="800">
<el-form
ref="formRef"
:model="formData"
@ -29,7 +29,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -41,8 +41,8 @@ import * as PostApi from '@/api/system/post'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -63,8 +63,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const openModal = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -97,7 +97,7 @@ const submitForm = async () => {
await PostApi.updatePost(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -39,6 +39,7 @@
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openModal('create')"
v-hasPermi="['system:notice:create']"
>

View File

@ -1,202 +0,0 @@
<template>
<Dialog :title="dialogScopeTitle" v-model="dialogScopeVisible" width="800">
<el-form
ref="menuPermissionFormRef"
:model="dataScopeForm"
:inline="true"
label-width="80px"
v-loading="formLoading"
>
<el-form-item label="角色名称">
<el-tag>{{ dataScopeForm.name }}</el-tag>
</el-form-item>
<el-form-item label="角色标识">
<el-tag>{{ dataScopeForm.code }}</el-tag>
</el-form-item>
<!-- 分配角色的数据权限对话框 -->
<el-form-item label="权限范围" v-if="actionScopeType === 'data'">
<el-select v-model="dataScopeForm.dataScope">
<el-option
v-for="item in dataScopeDictDatas"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- 分配角色的菜单权限对话框 -->
<el-row>
<el-col :span="24">
<el-form-item
label="权限范围"
v-if="
actionScopeType === 'menu' ||
dataScopeForm.dataScope === SystemDataScopeEnum.DEPT_CUSTOM
"
style="display: flex"
>
<el-card class="card" shadow="never">
<template #header>
父子联动(选中父节点自动选择子节点):
<el-switch
v-model="checkStrictly"
inline-prompt
active-text="是"
inactive-text="否"
/>
全选/全不选:
<el-switch
v-model="treeNodeAll"
inline-prompt
active-text="是"
inactive-text="否"
@change="handleCheckedTreeNodeAll()"
/>
</template>
<el-tree
ref="treeRef"
node-key="id"
show-checkbox
:check-strictly="!checkStrictly"
:props="defaultProps"
:data="treeOptions"
empty-text="加载中,请稍后"
/>
</el-card>
</el-form-item> </el-col
></el-row>
</el-form>
<!-- 操作按钮 -->
<template #footer>
<div class="dialog-footer">
<el-button
:title="t('action.save')"
:loading="actionLoading"
@click="submitScope()"
type="primary"
:disabled="formLoading"
>
保存
</el-button>
<el-button
:loading="actionLoading"
:title="t('dialog.close')"
@click="dialogScopeVisible = false"
> </el-button
>
</div>
</template>
</Dialog>
</template>
<script setup lang="ts">
import * as RoleApi from '@/api/system/role'
import type { ElTree } from 'element-plus'
import type { FormExpose } from '@/components/Form'
import { handleTree, defaultProps } from '@/utils/tree'
import { SystemDataScopeEnum } from '@/utils/constants'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as MenuApi from '@/api/system/menu'
import * as DeptApi from '@/api/system/dept'
import * as PermissionApi from '@/api/system/permission'
// ========== CRUD ==========
const actionLoading = ref(false) //
const menuPermissionFormRef = ref<FormExpose>() // Ref
const { t } = useI18n() //
const dialogScopeTitle = ref('菜单权限')
const dataScopeDictDatas = ref()
const message = useMessage() //
const actionScopeType = ref('')
//
const checkStrictly = ref(true)
const treeNodeAll = ref(false)
const dialogScopeVisible = ref(false) //
const formLoading = ref(false) // 12
const treeOptions = ref<any[]>([]) //
const treeRef = ref<InstanceType<typeof ElTree>>()
// ========== ==========
const dataScopeForm = reactive({
id: 0,
name: '',
code: '',
dataScope: 0,
checkList: []
})
/** 打开弹窗 */
const openModal = async (type: string, row: RoleApi.RoleVO) => {
dataScopeForm.id = row.id
dataScopeForm.name = row.name
dataScopeForm.code = row.code
actionScopeType.value = type
dialogScopeVisible.value = true
if (type === 'menu') {
const menuRes = await MenuApi.getSimpleMenusList()
treeOptions.value = handleTree(menuRes)
const role = await PermissionApi.listRoleMenusApi(row.id)
if (role) {
role?.forEach((item: any) => {
unref(treeRef)?.setChecked(item, true, false)
})
}
} else if (type === 'data') {
const deptRes = await DeptApi.getSimpleDeptList()
treeOptions.value = handleTree(deptRes)
const role = await RoleApi.getRole(row.id)
dataScopeForm.dataScope = role.dataScope
if (role.dataScopeDeptIds) {
role.dataScopeDeptIds?.forEach((item: any) => {
unref(treeRef)?.setChecked(item, true, false)
})
}
}
}
//
const submitScope = async () => {
if ('data' === actionScopeType.value) {
const data = ref<PermissionApi.PermissionAssignRoleDataScopeReqVO>({
roleId: dataScopeForm.id,
dataScope: dataScopeForm.dataScope,
dataScopeDeptIds:
dataScopeForm.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM
? []
: (treeRef.value!.getCheckedKeys(false) as unknown as Array<number>)
})
await PermissionApi.assignRoleDataScopeApi(data.value)
} else if ('menu' === actionScopeType.value) {
const data = ref<PermissionApi.PermissionAssignRoleMenuReqVO>({
roleId: dataScopeForm.id,
menuIds: [
...(treeRef.value!.getCheckedKeys(false) as unknown as Array<number>),
...(treeRef.value!.getHalfCheckedKeys() as unknown as Array<number>)
]
})
await PermissionApi.assignRoleMenuApi(data.value)
}
message.success(t('common.updateSuccess'))
dialogScopeVisible.value = false
}
// /
const handleCheckedTreeNodeAll = () => {
treeRef.value!.setCheckedNodes(treeNodeAll.value ? treeOptions.value : [])
}
const init = () => {
dataScopeDictDatas.value = getIntDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE)
}
defineExpose({ openModal }) // openModal
// ========== ==========
onMounted(() => {
init()
})
</script>
<style scoped>
.card {
width: 100%;
max-height: 400px;
overflow-y: scroll;
}
</style>

View File

@ -0,0 +1,154 @@
<template>
<Dialog title="菜单权限" v-model="dialogVisible">
<el-form ref="formRef" :model="formData" label-width="80px" v-loading="formLoading">
<el-form-item label="角色名称">
<el-tag>{{ formData.name }}</el-tag>
</el-form-item>
<el-form-item label="角色标识">
<el-tag>{{ formData.code }}</el-tag>
</el-form-item>
<el-form-item label="菜单权限">
<el-card class="cardHeight">
<template #header>
全选/全不选:
<el-switch
v-model="treeNodeAll"
inline-prompt
active-text="是"
inactive-text="否"
@change="handleCheckedTreeNodeAll"
/>
全部展开/折叠:
<el-switch
v-model="menuExpand"
inline-prompt
active-text="展开"
inactive-text="折叠"
@change="handleCheckedTreeExpand"
/>
</template>
<el-tree
ref="treeRef"
node-key="id"
show-checkbox
:props="defaultProps"
:data="menuOptions"
empty-text="加载中,请稍候"
/>
</el-card>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { handleTree, defaultProps } from '@/utils/tree'
import * as RoleApi from '@/api/system/role'
import * as MenuApi from '@/api/system/menu'
import * as PermissionApi from '@/api/system/permission'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const formLoading = ref(false) // 12
const formData = reactive({
id: 0,
name: '',
code: '',
menuIds: []
})
const formRef = ref() // Ref
const menuOptions = ref<any[]>([]) //
const menuExpand = ref(false) // /
const treeRef = ref() // Ref
const treeNodeAll = ref(false) // /
/** 打开弹窗 */
const open = async (row: RoleApi.RoleVO) => {
dialogVisible.value = true
resetForm()
// Menu setChecked
menuOptions.value = handleTree(await MenuApi.getSimpleMenusList())
//
formData.id = row.id
formData.name = row.name
formData.code = row.code
formLoading.value = true
try {
formData.value.menuIds = await PermissionApi.getRoleMenuList(row.id)
//
formData.value.menuIds.forEach((menuId: number) => {
treeRef.value.setChecked(menuId, true, false)
})
} finally {
formLoading.value = false
}
}
defineExpose({ open }) // open
/** 提交表单 */
const submitForm = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
const data = {
roleId: formData.id,
menuIds: [
...(treeRef.value.getCheckedKeys(false) as unknown as Array<number>), //
...(treeRef.value.getHalfCheckedKeys() as unknown as Array<number>) //
]
}
await PermissionApi.assignRoleMenu(data)
message.success(t('common.updateSuccess'))
dialogVisible.value = false
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
//
treeNodeAll.value = false
menuExpand.value = false
//
formData.value = {
id: 0,
name: '',
code: '',
menuIds: []
}
treeRef.value?.setCheckedNodes([])
formRef.value?.resetFields()
}
/** 全选/全不选 */
const handleCheckedTreeNodeAll = () => {
treeRef.value.setCheckedNodes(treeNodeAll.value ? menuOptions.value : [])
}
/** 展开/折叠全部 */
const handleCheckedTreeExpand = () => {
const nodes = treeRef.value?.store.nodesMap
for (let node in nodes) {
if (nodes[node].expanded === menuExpand.value) {
continue
}
nodes[node].expanded = menuExpand.value
}
}
</script>
<style lang="scss" scoped>
.cardHeight {
width: 100%;
max-height: 400px;
overflow-y: scroll;
}
</style>

View File

@ -0,0 +1,161 @@
<template>
<Dialog title="菜单权限" v-model="dialogVisible" width="800">
<el-form ref="formRef" :model="formData" label-width="80px" v-loading="formLoading">
<el-form-item label="角色名称">
<el-tag>{{ formData.name }}</el-tag>
</el-form-item>
<el-form-item label="角色标识">
<el-tag>{{ formData.code }}</el-tag>
</el-form-item>
<el-form-item label="权限范围">
<el-select v-model="formData.dataScope">
<el-option
v-for="item in getIntDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE)"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<el-form-item
label="权限范围"
v-if="formData.dataScope === SystemDataScopeEnum.DEPT_CUSTOM"
style="display: flex"
>
<el-card class="card" shadow="never">
<template #header>
全选/全不选:
<el-switch
v-model="treeNodeAll"
inline-prompt
active-text="是"
inactive-text="否"
@change="handleCheckedTreeNodeAll()"
/>
全部展开/折叠:
<el-switch
v-model="deptExpand"
inline-prompt
active-text="展开"
inactive-text="折叠"
@change="handleCheckedTreeExpand"
/>
父子联动(选中父节点自动选择子节点):
<el-switch v-model="checkStrictly" inline-prompt active-text="" inactive-text="" />
</template>
<el-tree
ref="treeRef"
node-key="id"
show-checkbox
:check-strictly="!checkStrictly"
:props="defaultProps"
:data="deptOptions"
empty-text="加载中,请稍后"
default-expand-all
/>
</el-card>
</el-form-item>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { handleTree, defaultProps } from '@/utils/tree'
import { SystemDataScopeEnum } from '@/utils/constants'
import * as RoleApi from '@/api/system/role'
import * as DeptApi from '@/api/system/dept'
import * as PermissionApi from '@/api/system/permission'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const formLoading = ref(false) // 12
const formData = reactive({
id: 0,
name: '',
code: '',
dataScope: undefined,
dataScopeDeptIds: []
})
const formRef = ref() // Ref
const deptOptions = ref<any[]>([]) //
const deptExpand = ref(false) // /
const treeRef = ref() // Ref
const treeNodeAll = ref(false) // /
const checkStrictly = ref(true) //
/** 打开弹窗 */
const open = async (row: RoleApi.RoleVO) => {
dialogVisible.value = true
resetForm()
// Dept setChecked
deptOptions.value = handleTree(await DeptApi.getSimpleDeptList())
//
formData.id = row.id
formData.name = row.name
formData.code = row.code
formData.dataScope = row.dataScope
row.dataScopeDeptIds?.forEach((deptId: number) => {
treeRef.value.setChecked(deptId, true, false)
})
}
defineExpose({ open }) // open
/** 提交表单 */
const submitForm = async () => {
formLoading.value = true
try {
const data = {
roleId: formData.id,
dataScope: formData.dataScope,
dataScopeDeptIds:
formData.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM
? []
: treeRef.value.getCheckedKeys(false)
}
await PermissionApi.assignRoleDataScope(data)
message.success(t('common.updateSuccess'))
dialogVisible.value = false
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
//
treeNodeAll.value = false
deptExpand.value = false
checkStrictly.value = true
//
formData.value = {
id: 0,
name: '',
code: '',
dataScope: undefined,
dataScopeDeptIds: []
}
treeRef.value?.setCheckedNodes([])
formRef.value?.resetFields()
}
/** 全选/全不选 */
const handleCheckedTreeNodeAll = () => {
treeRef.value.setCheckedNodes(treeNodeAll.value ? deptOptions.value : [])
}
/** 展开/折叠全部 */
const handleCheckedTreeExpand = () => {
const nodes = treeRef.value?.store.nodesMap
for (let node in nodes) {
if (nodes[node].expanded === deptExpand.value) {
continue
}
nodes[node].expanded = deptExpand.value
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -32,7 +32,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -43,8 +43,8 @@ import * as RoleApi from '@/api/system/role'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -66,8 +66,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -113,7 +113,7 @@ const submitForm = async () => {
await RoleApi.updateRole(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -108,7 +108,7 @@
preIcon="ep:basketball"
title="菜单权限"
v-hasPermi="['system:permission:assign-role-menu']"
@click="handleScope('menu', scope.row)"
@click="openAssignMenuForm(scope.row)"
>
菜单权限
</el-button>
@ -118,7 +118,7 @@
preIcon="ep:coin"
title="数据权限"
v-hasPermi="['system:permission:assign-role-data-scope']"
@click="handleScope('data', scope.row)"
@click="openDataPermissionForm(scope.row)"
>
数据权限
</el-button>
@ -145,15 +145,18 @@
<!-- 表单弹窗添加/修改 -->
<RoleForm ref="formRef" @success="getList" />
<!-- 表单弹窗菜单权限 -->
<MenuPermissionForm ref="menuPermissionFormRef" @success="getList" />
<RoleAssignMenuForm ref="assignMenuFormRef" />
<!-- 表单弹窗数据权限 -->
<RoleDataPermissionForm ref="dataPermissionFormRef" />
</template>
<script setup lang="tsx">
import * as RoleApi from '@/api/system/role'
import RoleForm from './RoleForm.vue'
import MenuPermissionForm from './MenuPermissionForm.vue'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as RoleApi from '@/api/system/role'
import RoleForm from './RoleForm.vue'
import RoleAssignMenuForm from './RoleAssignMenuForm.vue'
import RoleDataPermissionForm from './RoleDataPermissionForm.vue'
const message = useMessage() //
const { t } = useI18n() //
@ -202,9 +205,15 @@ const openForm = (type: string, id?: number) => {
}
/** 数据权限操作 */
const menuPermissionFormRef = ref()
const handleScope = async (type: string, row: RoleApi.RoleVO) => {
menuPermissionFormRef.value.openModal(type, row)
const dataPermissionFormRef = ref()
const openDataPermissionForm = async (row: RoleApi.RoleVO) => {
dataPermissionFormRef.value.open(row)
}
/** 菜单权限操作 */
const assignMenuFormRef = ref()
const openAssignMenuForm = async (row: RoleApi.RoleVO) => {
assignMenuFormRef.value.open(row)
}
/** 删除按钮操作 */

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -39,7 +39,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -50,8 +50,8 @@ import { CommonStatusEnum } from '@/utils/constants'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -70,8 +70,8 @@ const tagList = ref([]) // 标签数组
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -106,7 +106,7 @@ const submitForm = async () => {
await SensitiveWordApi.updateSensitiveWord(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="检测敏感词" v-model="modelVisible">
<Dialog title="检测敏感词" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -24,10 +24,8 @@
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
</div>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -35,7 +33,7 @@
import * as SensitiveWordApi from '@/api/system/sensitiveWord'
const message = useMessage() //
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const formLoading = ref(false) // 12
const formData = ref({
text: '',
@ -50,7 +48,7 @@ const tagList = ref([]) // 标签数组
/** 打开弹窗 */
const open = async () => {
modelVisible.value = true
dialogVisible.value = true
resetForm()
// Tag
tagList.value = await SensitiveWordApi.getSensitiveWordTagList()
@ -73,7 +71,7 @@ const submitForm = async () => {
return
}
message.warning('包含敏感词:' + data.join(', '))
modelVisible.value = false
dialogVisible.value = false
} finally {
formLoading.value = false
}

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -46,7 +46,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -57,8 +57,8 @@ import { CommonStatusEnum } from '@/utils/constants'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -81,8 +81,8 @@ const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -116,7 +116,7 @@ const submitForm = async () => {
await SmsChannelApi.updateSmsChannel(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -40,6 +40,7 @@
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['system:sms-channel:create']"
>

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="详情" v-model="modelVisible" :scroll="true" :max-height="500" width="800">
<Dialog title="详情" v-model="dialogVisible" :scroll="true" :max-height="500" width="800">
<el-descriptions border :column="1">
<el-descriptions-item label="日志主键" min-width="120">
{{ detailData.id }}
@ -65,14 +65,14 @@ import { formatDate } from '@/utils/formatTime'
import * as SmsLogApi from '@/api/system/sms/smsLog'
import * as SmsChannelApi from '@/api/system/sms/smsChannel'
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const detailLoading = ref(false) //
const detailData = ref() //
const channelList = ref([]) //
/** 打开弹窗 */
const open = async (data: SmsLogApi.SmsLogVO) => {
modelVisible.value = true
dialogVisible.value = true
//
detailLoading.value = true
try {

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -59,7 +59,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -71,8 +71,8 @@ import { CommonStatusEnum } from '@/utils/constants'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') //
const formData = ref<SmsTemplateApi.SmsTemplateVO>({
@ -99,8 +99,8 @@ const formRef = ref() // 表单 Ref
const channelList = ref<SmsChannelApi.SmsChannelVO[]>([]) //
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -134,7 +134,7 @@ const submitForm = async () => {
await SmsTemplateApi.updateSmsTemplate(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -1,5 +1,5 @@
<template>
<Dialog title="测试" v-model="modelVisible">
<Dialog title="测试" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -32,7 +32,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -40,7 +40,7 @@
import * as SmsTemplateApi from '@/api/system/sms/smsTemplate'
const message = useMessage() //
const modelVisible = ref(false) //
const dialogVisible = ref(false) //
const formLoading = ref(false) // 12
//
@ -59,7 +59,7 @@ const formRules = reactive({
const formRef = ref() // Ref
const open = async (id: number) => {
modelVisible.value = true
dialogVisible.value = true
resetForm()
//
formLoading.value = true
@ -97,7 +97,7 @@ const submitForm = async () => {
if (logId) {
message.success('提交发送成功!发送结果,见发送日志编号:' + logId)
}
modelVisible.value = false
dialogVisible.value = false
} finally {
formLoading.value = false
}

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible" width="50%">
<Dialog :title="dialogTitle" v-model="dialogVisible" width="50%">
<el-form
ref="formRef"
:model="formData"
@ -71,7 +71,7 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -83,8 +83,8 @@ import * as TenantPackageApi from '@/api/system/tenantPackage'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -112,8 +112,8 @@ const packageList = ref([]) // 租户套餐
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
@ -148,7 +148,7 @@ const submitForm = async () => {
await TenantApi.updateTenant(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {

View File

@ -71,7 +71,12 @@
<Icon icon="ep:refresh" class="mr-5px" />
重置
</el-button>
<el-button type="primary" @click="openForm('create')" v-hasPermi="['system:tenant:create']">
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['system:tenant:create']"
>
<Icon icon="ep:plus" class="mr-5px" />
新增
</el-button>

View File

@ -1,5 +1,5 @@
<template>
<Dialog :title="modelTitle" v-model="modelVisible">
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
@ -57,24 +57,22 @@
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="modelVisible = false"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts" name="TenantPackageForm">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { CommonStatusEnum } from '@/utils/constants'
import { defaultProps } from '@/utils/tree'
import { defaultProps, handleTree } from '@/utils/tree'
import * as TenantPackageApi from '@/api/system/tenantPackage'
import * as MenuApi from '@/api/system/menu'
import { ElTree } from 'element-plus'
import { handleTree } from '@/utils/tree'
const { t } = useI18n() //
const message = useMessage() //
const modelVisible = ref(false) //
const modelTitle = ref('') //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
@ -92,13 +90,13 @@ const formRules = reactive({
const formRef = ref() // Ref
const menuOptions = ref<any[]>([]) //
const menuExpand = ref(false) // /
const treeRef = ref<InstanceType<typeof ElTree>>() // Ref
const treeRef = ref<InstanceType<typeof ElTree>>() // Ref
const treeNodeAll = ref(false) // /
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
modelVisible.value = true
modelTitle.value = t('action.' + type)
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
// Menu setChecked
@ -133,8 +131,8 @@ const submitForm = async () => {
try {
const data = formData.value as unknown as TenantPackageApi.TenantPackageVO
data.menuIds = [
...(treeRef.value!.getCheckedKeys(false) as unknown as Array<number>), //
...(treeRef.value!.getHalfCheckedKeys() as unknown as Array<number>) //
...(treeRef.value.getCheckedKeys(false) as unknown as Array<number>), //
...(treeRef.value.getHalfCheckedKeys() as unknown as Array<number>) //
]
if (formType.value === 'create') {
await TenantPackageApi.createTenantPackage(data)
@ -143,7 +141,7 @@ const submitForm = async () => {
await TenantPackageApi.updateTenantPackage(data)
message.success(t('common.updateSuccess'))
}
modelVisible.value = false
dialogVisible.value = false
//
emit('success')
} finally {
@ -168,17 +166,19 @@ const resetForm = () => {
formRef.value?.resetFields()
}
// /
/** 全选/全不选 */
const handleCheckedTreeNodeAll = () => {
treeRef.value!.setCheckedNodes(treeNodeAll.value ? menuOptions.value : [])
treeRef.value.setCheckedNodes(treeNodeAll.value ? menuOptions.value : [])
}
// /TODO:for
/** 展开/折叠全部 */
const handleCheckedTreeExpand = () => {
const nodes = treeRef.value?.store.nodesMap
for (let node in nodes) {
if (nodes[node].expanded === menuExpand.value) continue
nodes[node].expanded = !nodes[node].expanded
if (nodes[node].expanded === menuExpand.value) {
continue
}
nodes[node].expanded = menuExpand.value
}
}
</script>

View File

@ -42,6 +42,7 @@
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['system:tenant-package:create']"
>
@ -63,11 +64,13 @@
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template #default="scope">
<span>{{ formatDate(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
width="180"
:formatter="dateFormatter"
/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button
@ -103,7 +106,7 @@
</template>
<script setup lang="ts" name="TenantPackage">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import { dateFormatter } from '@/utils/formatTime'
import * as TenantPackageApi from '@/api/system/tenantPackage'
import TenantPackageForm from './TenantPackageForm.vue'
const message = useMessage() //
@ -112,7 +115,7 @@ const { t } = useI18n() // 国际化
const loading = ref(true) //
const total = ref(0) //
const list = ref([]) //
const queryParams: Record<string, any> = ref<Record<string, any>>({
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: null,

View File

@ -1,6 +1,6 @@
<template>
<div class="head-container">
<el-input v-model="deptName" placeholder="请输入部门名称" clearable style="margin-bottom: 20px">
<el-input v-model="deptName" placeholder="请输入部门名称" clearable class="mb-20px">
<template #prefix>
<Icon icon="ep:search" />
</template>
@ -8,15 +8,15 @@
</div>
<div class="head-container">
<el-tree
:data="deptOptions"
:data="deptList"
:props="defaultProps"
node-key="id"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="treeRef"
node-key="id"
default-expand-all
highlight-current
@node-click="handleDeptNodeClick"
@node-click="handleNodeClick"
/>
</div>
</template>
@ -26,25 +26,30 @@ import { ElTree } from 'element-plus'
import * as DeptApi from '@/api/system/dept'
import { defaultProps, handleTree } from '@/utils/tree'
const emits = defineEmits(['node-click'])
const deptName = ref('')
const deptOptions = ref<Tree[]>([]) //
const deptList = ref<Tree[]>([]) //
const treeRef = ref<InstanceType<typeof ElTree>>()
/** 获得部门树 */
const getTree = async () => {
const res = await DeptApi.getSimpleDeptList()
deptOptions.value = []
deptOptions.value.push(...handleTree(res))
deptList.value = []
deptList.value.push(...handleTree(res))
}
const filterNode = (value: string, data: Tree) => {
if (!value) return true
return data.name.includes(value)
/** 基于名字过滤 */
const filterNode = (name: string, data: Tree) => {
if (!name) return true
return data.name.includes(name)
}
const handleDeptNodeClick = async (row: { [key: string]: any }) => {
/** 处理部门被点击 */
const handleNodeClick = async (row: { [key: string]: any }) => {
emits('node-click', row)
}
const emits = defineEmits(['node-click'])
/** 初始化 */
onMounted(async () => {
await getTree()
})

View File

@ -0,0 +1,93 @@
<template>
<Dialog title="分配角色" v-model="dialogVisible">
<el-form ref="formRef" :model="formData" label-width="80px" v-loading="formLoading">
<el-form-item label="用户名称">
<el-input v-model="formData.username" :disabled="true" />
</el-form-item>
<el-form-item label="用户昵称">
<el-input v-model="formData.nickname" :disabled="true" />
</el-form-item>
<el-form-item label="角色">
<el-select v-model="formData.roleIds" multiple placeholder="请选择角色">
<el-option v-for="item in roleList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import * as PermissionApi from '@/api/system/permission'
import * as UserApi from '@/api/system/user'
import * as RoleApi from '@/api/system/role'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const formLoading = ref(false) // 12
const formData = ref({
id: undefined,
nickname: '',
username: '',
roleIds: []
})
const formRef = ref() // Ref
const roleList = ref([]) //
/** 打开弹窗 */
const open = async (row: UserApi.UserVO) => {
dialogVisible.value = true
resetForm()
//
formData.value.id = row.id
formData.value.username = row.username
formData.value.nickname = row.nickname
//
formLoading.value = true
try {
formData.value.roleIds = await PermissionApi.getUserRoleList(row.id)
} finally {
formLoading.value = false
}
//
roleList.value = await RoleApi.getSimpleRoleList()
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
await PermissionApi.assignUserRole({
userId: formData.value.id,
roleIds: formData.value.roleIds
})
message.success(t('common.updateSuccess'))
dialogVisible.value = false
//
emit('success', true)
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
nickname: '',
username: '',
roleIds: []
}
formRef.value?.resetFields()
}
</script>

Some files were not shown because too many files have changed in this diff Show More