Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/layout/components/Navbar.vue
#	src/views/login.vue
This commit is contained in:
xzh
2025-07-22 20:18:54 +08:00
16 changed files with 1035 additions and 123 deletions

20
LICENSE
View File

@@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2019 RuoYi-Vue-Plus
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,76 +0,0 @@
## 平台简介
- 本仓库为前端技术栈 [Vue3](https://v3.cn.vuejs.org) + [TS](https://www.typescriptlang.org/) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 版本。
- 成员项目: 基于 vben5(ant-design-vue) 的前端项目 [ruoyi-plus-vben5](https://gitee.com/dapppp/ruoyi-plus-vben5)
- 配套后端代码仓库地址
- [RuoYi-Vue-Plus 5.X(注意版本号)](https://gitee.com/dromara/RuoYi-Vue-Plus)
- [RuoYi-Cloud-Plus 2.X(注意版本号)](https://gitee.com/dromara/RuoYi-Cloud-Plus)
## 前端运行
```bash
# 克隆项目
git clone https://gitee.com/JavaLionLi/plus-ui.git
# 安装依赖
npm install --registry=https://registry.npmmirror.com
# 启动服务
npm run dev
# 构建生产环境
npm run build:prod
# 前端访问地址 http://localhost:80
```
## 本框架与RuoYi的业务差异
| 业务 | 功能说明 | 本框架 | RuoYi |
| ------------ | ------------------------------------------------------------- | ------ | ----------------------------- |
| 租户管理 | 系统内租户的管理 如:租户套餐、过期时间、用户数量、企业信息等 | 支持 | 无 |
| 租户套餐管理 | 系统内租户所能使用的套餐管理 如:套餐内所包含的菜单等 | 支持 | 无 |
| 用户管理 | 用户的管理配置 如:新增用户、分配用户所属部门、角色、岗位等 | 支持 | 支持 |
| 部门管理 | 配置系统组织机构(公司、部门、小组) 树结构展现支持数据权限 | 支持 | 支持 |
| 岗位管理 | 配置系统用户所属担任职务 | 支持 | 支持 |
| 菜单管理 | 配置系统菜单、操作权限、按钮权限标识等 | 支持 | 支持 |
| 角色管理 | 角色菜单权限分配、设置角色按机构进行数据范围权限划分 | 支持 | 支持 |
| 字典管理 | 对系统中经常使用的一些较为固定的数据进行维护 | 支持 | 支持 |
| 参数管理 | 对系统动态配置常用参数 | 支持 | 支持 |
| 通知公告 | 系统通知公告信息发布维护 | 支持 | 支持 |
| 操作日志 | 系统正常操作日志记录和查询 系统异常信息日志记录和查询 | 支持 | 支持 |
| 登录日志 | 系统登录日志记录查询包含登录异常 | 支持 | 支持 |
| 文件管理 | 系统文件展示、上传、下载、删除等管理 | 支持 | 无 |
| 文件配置管理 | 系统文件上传、下载所需要的配置信息动态添加、修改、删除等管理 | 支持 | 无 |
| 在线用户管理 | 已登录系统的在线用户信息监控与强制踢出操作 | 支持 | 支持 |
| 定时任务 | 运行报表、任务管理(添加、修改、删除)、日志管理、执行器管理等 | 支持 | 仅支持任务与日志管理 |
| 代码生成 | 多数据源前后端代码的生成java、html、xml、sql支持CRUD下载 | 支持 | 仅支持单数据源 |
| 系统接口 | 根据业务代码自动生成相关的api接口文档 | 支持 | 支持 |
| 服务监控 | 监视集群系统CPU、内存、磁盘、堆栈、在线日志、Spring相关配置等 | 支持 | 仅支持单机CPU、内存、磁盘监控 |
| 缓存监控 | 对系统的缓存信息查询,命令统计等。 | 支持 | 支持 |
| 在线构建器 | 拖动表单元素生成相应的HTML代码。 | 支持 | 支持 |
| 使用案例 | 系统的一些功能案例 | 支持 | 不支持 |
## 演示图例
| | |
| ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| ![输入图片说明](https://foruda.gitee.com/images/1680077524361362822/270bb429_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680077619939771291/989bf9b6_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680077681751513929/1c27c5bd_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680077721559267315/74d63e23_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680077765638904515/1b75d4a6_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078026375951297/eded7a4b_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078237104531207/0eb1b6a7_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078254306078709/5931e22f_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078287971528493/0b9af60a_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078308138770249/8d3b6696_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078352553634393/db5ef880_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078378238393374/601e4357_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078414983206024/2aae27c1_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078446738419874/ecce7d59_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078475971341775/149e8634_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078491666717143/3fadece7_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078558863188826/fb8ced2a_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078574561685461/ae68a0b2_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078594932772013/9d8bfec6_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078626493093532/fcfe4ff6_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078643608812515/0295bd4f_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078685196286463/d7612c81_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078703877318597/56fce0bc_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078716586545643/b6dbd68f_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078734103217688/eb1e6aa6_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078759131415480/73c525d8_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078779416197879/75e3ed02_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078802329118061/77e10915_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078893627848351/34a1c342_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078928175016986/f126ec4a_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078941718318363/b68a0f72_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680078963175518631/3bb769a1_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680078982294090567/b31c343d_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680079000642440444/77ca82a9_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680079020995074177/03b7d52e_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680079039367822173/76811806_1766278.png '屏幕截图') |
| ![输入图片说明](https://foruda.gitee.com/images/1680079274333484664/4dfdc7c0_1766278.png '屏幕截图') | ![输入图片说明](https://foruda.gitee.com/images/1680079290467458224/d6715fcf_1766278.png '屏幕截图') |

View File

@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package",
"name": "ruoyi-vue-plus",
"name": "giftBook-web",
"version": "5.3.1-BETA2_2.3.0-BETA2",
"description": "礼薄管理系统",
"author": "LionLi",

View File

@@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { GiftBookVO, GiftBookForm, GiftBookQuery } from '@/api/main/giftBook/types';
/**
* 查询礼薄列表
* @param query
* @returns {*}
*/
export const listGiftBook = (query?: GiftBookQuery): AxiosPromise<GiftBookVO[]> => {
return request({
url: '/main/giftBook/list',
method: 'get',
params: query
});
};
/**
* 查询礼薄详细
* @param id
*/
export const getGiftBook = (id: string | number): AxiosPromise<GiftBookVO> => {
return request({
url: '/main/giftBook/' + id,
method: 'get'
});
};
/**
* 新增礼薄
* @param data
*/
export const addGiftBook = (data: GiftBookForm) => {
return request({
url: '/main/giftBook',
method: 'post',
data: data
});
};
/**
* 修改礼薄
* @param data
*/
export const updateGiftBook = (data: GiftBookForm) => {
return request({
url: '/main/giftBook',
method: 'put',
data: data
});
};
/**
* 删除礼薄
* @param id
*/
export const delGiftBook = (id: string | number | Array<string | number>) => {
return request({
url: '/main/giftBook/' + id,
method: 'delete'
});
};

View File

@@ -0,0 +1,45 @@
export interface GiftBookVO {
/**
* ID
*/
id: string | number;
/**
* 备注
*/
remark: string;
/**
* 礼薄名称
*/
name: string;
}
export interface GiftBookForm extends BaseEntity {
/**
* ID
*/
id?: string | number;
/**
* 备注
*/
remark?: string;
/**
* 礼薄名称
*/
name?: string;
}
export interface GiftBookQuery extends PageQuery {
/**
* 礼薄名称
*/
name?: string;
/**
* 日期范围参数
*/
params?: any;
}

View File

@@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { GiftBookDetailsVO, GiftBookDetailsForm, GiftBookDetailsQuery } from '@/api/main/giftBookDetails/types';
/**
* 查询礼薄详情列表
* @param query
* @returns {*}
*/
export const listGiftBookDetails = (query?: GiftBookDetailsQuery): AxiosPromise<GiftBookDetailsVO[]> => {
return request({
url: '/main/giftBookDetails/list',
method: 'get',
params: query
});
};
/**
* 查询礼薄详情详细
* @param id
*/
export const getGiftBookDetails = (id: string | number): AxiosPromise<GiftBookDetailsVO> => {
return request({
url: '/main/giftBookDetails/' + id,
method: 'get'
});
};
/**
* 新增礼薄详情
* @param data
*/
export const addGiftBookDetails = (data: GiftBookDetailsForm) => {
return request({
url: '/main/giftBookDetails',
method: 'post',
data: data
});
};
/**
* 修改礼薄详情
* @param data
*/
export const updateGiftBookDetails = (data: GiftBookDetailsForm) => {
return request({
url: '/main/giftBookDetails',
method: 'put',
data: data
});
};
/**
* 删除礼薄详情
* @param id
*/
export const delGiftBookDetails = (id: string | number | Array<string | number>) => {
return request({
url: '/main/giftBookDetails/' + id,
method: 'delete'
});
};

View File

@@ -0,0 +1,171 @@
export interface GiftBookDetailsVO {
/**
* ID
*/
id: string | number;
/**
* 备注
*/
remark: string;
/**
* 礼薄ID
*/
giftBookId: string | number;
/**
* 姓名
*/
name: string;
/**
* 年份
*/
year?: string;
/**
* 类型字典gift_book_event_type
*/
eventType: string;
/**
* 金额
*/
amount: number;
/**
* 礼物名称
*/
giftName: string;
/**
* 事件名称
*/
eventName: string;
/**
* 是否已还字典sys_yes_no
*/
isReturn: string;
/**
* 地址
*/
address: string;
}
export interface GiftBookDetailsForm extends BaseEntity {
/**
* ID
*/
id?: string | number;
/**
* 备注
*/
remark?: string;
/**
* 礼薄ID
*/
giftBookId?: string | number;
/**
* 姓名
*/
name?: string;
/**
* 年份
*/
year?: string;
/**
* 类型字典gift_book_event_type
*/
eventType?: string;
/**
* 金额
*/
amount?: number;
/**
* 礼物名称
*/
giftName?: string;
/**
* 事件名称
*/
eventName?: string;
/**
* 是否已还字典sys_yes_no
*/
isReturn: string;
/**
* 地址
*/
address?: string;
}
export interface GiftBookDetailsQuery extends PageQuery {
/**
* 礼薄ID
*/
giftBookId?: string | number;
/**
* 姓名
*/
name?: string;
/**
* 年份
*/
year?: string;
/**
* 类型字典gift_book_event_type
*/
eventType?: string;
/**
* 金额
*/
amount?: number;
/**
* 礼物名称
*/
giftName?: string;
/**
* 事件名称
*/
eventName?: string;
/**
* 是否已还字典sys_yes_no
*/
isReturn: string;
/**
* 地址
*/
address?: string;
/**
* 日期范围参数
*/
params?: any;
}

View File

@@ -5,7 +5,7 @@
</template>
<script setup lang="ts">
const url = ref('https://gitee.com/dromara/RuoYi-Vue-Plus');
const url = ref('https://gitee.com/dromara/giftBook-web');
function goto() {
window.open(url.value);

View File

@@ -43,6 +43,13 @@
</el-popover>
</div>
</el-tooltip>
<!-- <el-tooltip content="Github" effect="dark" placement="bottom">-->
<!-- <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />-->
<!-- </el-tooltip>-->
<!-- <el-tooltip :content="proxy.$t('navbar.document')" effect="dark" placement="bottom">-->
<!-- <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />-->
<!-- </el-tooltip>-->
<el-tooltip :content="proxy.$t('navbar.full')" effect="dark" placement="bottom">
<screenfull id="screenfull" class="right-menu-item hover-effect" />

View File

@@ -25,6 +25,7 @@
import variables from '@/assets/styles/variables.module.scss';
import logo from '@/assets/logo/logo.png';
import { useSettingsStore } from '@/store/modules/settings';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
defineProps({
@@ -34,7 +35,7 @@ defineProps({
}
});
const title = ref('RuoYi-Vue-Plus');
const title = ref('礼薄管理系统');
const settingsStore = useSettingsStore();
const sideTheme = computed(() => settingsStore.sideTheme);
</script>

View File

@@ -55,7 +55,7 @@ const onNewsClick = (item: any) => {
// 前往通知中心点击
const onGoToGiteeClick = () => {
window.open('https://gitee.com/dromara/RuoYi-Vue-Plus/tree/5.X/');
window.open('https://gitee.com/dromara/giftBook-web/tree/5.X/');
};
onMounted(() => {

View File

@@ -4,7 +4,7 @@
<el-col :sm="24" :lg="12" style="padding-left: 20px">
<h2>礼薄管理系统</h2>
<p>
RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 分布式集群 场景升级(不兼容原框架)
giftBook-web 是基于 RuoYi-Vue 针对 分布式集群 场景升级(不兼容原框架)
<br />
* 前端开发框架 Vue3TSElement Plus<br />
* 后端开发框架 Spring Boot<br />
@@ -38,9 +38,9 @@
<el-tag type="danger">&yen;免费开源</el-tag>
</p>
<p>
<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/RuoYi-Vue-Plus')">访问码云</el-button>
<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/RuoYi-Vue-Plus')">访问GitHub</el-button>
<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://plus-doc.dromara.org/#/ruoyi-vue-plus/changlog')"
<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://gitee.com/dromara/giftBook-web')">访问码云</el-button>
<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://github.com/dromara/giftBook-web')">访问GitHub</el-button>
<el-button type="primary" icon="Cloudy" plain @click="goTarget('https://plus-doc.dromara.org/#/giftBook-web/changlog')"
>更新日志</el-button
>
</p>

View File

@@ -44,17 +44,23 @@
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin: 0 0 25px 0">{{ proxy.$t('login.rememberPassword') }}</el-checkbox>
<el-form-item style="float: right">
<el-button circle :title="proxy.$t('login.social.wechat')" @click="doSocialLogin('wechat')">
<svg-icon icon-class="wechat" />
</el-button>
<el-button circle :title="proxy.$t('login.social.maxkey')" @click="doSocialLogin('maxkey')">
<svg-icon icon-class="maxkey" />
</el-button>
<el-button circle :title="proxy.$t('login.social.topiam')" @click="doSocialLogin('topiam')">
<svg-icon icon-class="topiam" />
</el-button>
</el-form-item>
<!-- <el-form-item style="float: right">-->
<!-- <el-button circle :title="proxy.$t('login.social.wechat')" @click="doSocialLogin('wechat')">-->
<!-- <svg-icon icon-class="wechat" />-->
<!-- </el-button>-->
<!-- <el-button circle :title="proxy.$t('login.social.maxkey')" @click="doSocialLogin('maxkey')">-->
<!-- <svg-icon icon-class="maxkey" />-->
<!-- </el-button>-->
<!-- <el-button circle :title="proxy.$t('login.social.topiam')" @click="doSocialLogin('topiam')">-->
<!-- <svg-icon icon-class="topiam" />-->
<!-- </el-button>-->
<!-- <el-button circle :title="proxy.$t('login.social.gitee')" @click="doSocialLogin('gitee')">-->
<!-- <svg-icon icon-class="gitee" />-->
<!-- </el-button>-->
<!-- <el-button circle :title="proxy.$t('login.social.github')" @click="doSocialLogin('github')">-->
<!-- <svg-icon icon-class="github" />-->
<!-- </el-button>-->
<!-- </el-form-item>-->
<el-form-item style="width: 100%">
<el-button :loading="loading" size="large" type="primary" style="width: 100%" @click.prevent="handleLogin">
<span v-if="!loading">{{ proxy.$t('login.login') }}</span>
@@ -66,9 +72,9 @@
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2025 疯狂的狮子Li All Rights Reserved.</span>
</div>
<!-- <div class="el-login-footer">-->
<!-- <span>Copyright © 2018-2025 疯狂的狮子Li All Rights Reserved.</span>-->
<!-- </div>-->
</div>
</template>
@@ -90,8 +96,8 @@ const { t } = useI18n();
const loginForm = ref<LoginData>({
tenantId: '000000',
username: 'admin',
password: 'admin123',
username: '',
password: '',
rememberMe: false,
code: '',
uuid: ''

View File

@@ -0,0 +1,220 @@
<template>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="礼薄名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入礼薄名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['main:giftBook:add']">新增 </el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['main:giftBook:edit']"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['main:giftBook:remove']"
>删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['main:giftBook:export']"> 导出 </el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" :data="giftBookList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="礼薄名称" align="center" prop="name" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['main:giftBook:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['main:giftBook:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改礼薄对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="giftBookFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="礼薄名称" prop="name">
<el-input v-model="form.name" placeholder="请输入礼薄名称" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="GiftBook" lang="ts">
import { listGiftBook, getGiftBook, delGiftBook, addGiftBook, updateGiftBook } from '@/api/main/giftBook';
import { GiftBookVO, GiftBookQuery, GiftBookForm } from '@/api/main/giftBook/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const giftBookList = ref<GiftBookVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const giftBookFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const initFormData: GiftBookForm = {
id: undefined,
remark: undefined,
name: undefined
};
const data = reactive<PageData<GiftBookForm, GiftBookQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
name: undefined,
params: {}
},
rules: {
name: [{ required: true, message: '礼薄名称不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询礼薄列表 */
const getList = async () => {
loading.value = true;
const res = await listGiftBook(queryParams.value);
giftBookList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
giftBookFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: GiftBookVO[]) => {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加礼薄';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: GiftBookVO) => {
reset();
const _id = row?.id || ids.value[0];
const res = await getGiftBook(_id);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改礼薄';
};
/** 提交按钮 */
const submitForm = () => {
giftBookFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
await updateGiftBook(form.value).finally(() => (buttonLoading.value = false));
} else {
await addGiftBook(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: GiftBookVO) => {
const _ids = row?.id || ids.value;
await proxy?.$modal.confirm('是否确认删除礼薄编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
await delGiftBook(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'main/giftBook/export',
{
...queryParams.value
},
`礼薄_${new Date().getTime()}.xlsx`
);
};
onMounted(() => {
getList();
});
</script>

View File

@@ -0,0 +1,432 @@
<template>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="礼薄" prop="giftBookId">
<el-select v-model="queryParams.giftBookId" placeholder="请选择礼薄" clearable>
<el-option v-for="item in giftBookList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入姓名" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="年份" prop="year">
<el-date-picker
v-model="queryParams.year"
type="year"
placeholder="请选择年份"
/>
</el-form-item>
<el-form-item label="类型" prop="eventType">
<el-select v-model="queryParams.eventType" placeholder="请选择类型" clearable>
<el-option v-for="dict in gift_book_event_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="事件名称" prop="eventName">
<el-input v-model="queryParams.eventName" placeholder="请输入事件名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="是否已还" prop="isReturn">
<el-select v-model="queryParams.isReturn" placeholder="请选择类型" clearable>
<el-option v-for="dict in sys_yes_no" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input v-model="queryParams.address" placeholder="请输入地址" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['main:giftBookDetails:add']"> 新增 </el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['main:giftBookDetails:edit']"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['main:giftBookDetails:remove']"
>删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['main:giftBookDetails:export']">导出 </el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExportWrod" v-hasPermi="['main:giftBookDetails:export']">导出PDF </el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleImport" v-hasPermi="['main:giftBookDetails:import']">导入 </el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" :data="giftBookDetailsList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="礼薄" align="center" prop="giftBookName" />
<el-table-column label="姓名" align="center" prop="name" />
<el-table-column label="年份" align="center" prop="year" />
<el-table-column label="类型" align="center" prop="eventType">
<template #default="scope">
<dict-tag :options="gift_book_event_type" :value="scope.row.eventType" />
</template>
</el-table-column>
<el-table-column label="金额" align="center" prop="amount" />
<el-table-column label="礼物名称" align="center" prop="giftName" />
<el-table-column label="事件名称" align="center" prop="eventName" />
<el-table-column label="是否已还" align="center" prop="isReturn">
<template #default="scope">
<dict-tag :options="sys_yes_no" :value="scope.row.isReturn" />
</template>
</el-table-column>
<el-table-column label="地址" align="center" prop="address" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['main:giftBookDetails:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['main:giftBookDetails:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改礼薄详情对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="giftBookDetailsFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="礼薄" prop="giftBookId">
<el-select v-model="form.giftBookId" placeholder="请选择礼薄">
<el-option v-for="item in giftBookList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="年份" prop="year">
<el-date-picker
v-model="form.year"
type="year"
placeholder="请选择年份"
value-format="YYYY"
/>
</el-form-item>
<el-form-item label="类型" prop="eventType">
<el-select v-model="form.eventType" placeholder="请选择类型">
<el-option v-for="dict in gift_book_event_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form.eventType === '0' || form.eventType === '2'" label="金额" prop="amount">
<el-input v-model="form.amount" type="number" placeholder="请输入金额" />
</el-form-item>
<el-form-item v-if="form.eventType === '1' || form.eventType === '2'" label="礼物名称" prop="giftName">
<el-input v-model="form.giftName" placeholder="请输入礼物名称" />
</el-form-item>
<el-form-item label="事件名称" prop="eventName">
<el-input v-model="form.eventName" placeholder="请输入事件名称" />
</el-form-item>
<el-form-item label="是否已还" prop="isReturn">
<el-radio-group v-model="form.isReturn">
<el-radio v-for="dict in sys_yes_no" :value="dict.value">{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input v-model="form.address" placeholder="请输入地址" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
<!-- 用户详情对话框 -->
<el-dialog v-model="upload.open" :title="upload.title" width="400px" append-to-body>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<el-icon class="el-icon--upload">
<i-ep-upload-filled />
</el-icon>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="text-center el-upload__tip">
<!-- <div class="el-upload__tip">-->
<!-- <el-checkbox v-model="upload.updateSupport" />-->
<!-- 是否更新已经存在的用户数据-->
<!-- </div>-->
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板 </el-link>
</div>
</template>
</el-upload>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="GiftBookDetails" lang="ts">
import { listGiftBookDetails, getGiftBookDetails, delGiftBookDetails, addGiftBookDetails, updateGiftBookDetails } from '@/api/main/giftBookDetails';
import { GiftBookDetailsVO, GiftBookDetailsQuery, GiftBookDetailsForm } from '@/api/main/giftBookDetails/types';
import { listGiftBook } from '@/api/main/giftBook';
import { GiftBookVO } from '@/api/main/giftBook/types';
import { globalHeaders } from '@/utils/request';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { gift_book_event_type, sys_yes_no } = toRefs<any>(proxy?.useDict('gift_book_event_type', 'sys_yes_no'));
const giftBookDetailsList = ref<GiftBookDetailsVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const giftBookDetailsFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const initFormData: GiftBookDetailsForm = {
id: undefined,
remark: undefined,
giftBookId: undefined,
name: undefined,
eventType: undefined,
amount: undefined,
giftName: undefined,
eventName: undefined,
isReturn: 'N',
address: undefined
};
const data = reactive<PageData<GiftBookDetailsForm, GiftBookDetailsQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
giftBookId: undefined,
name: undefined,
eventType: undefined,
amount: undefined,
giftName: undefined,
eventName: undefined,
isReturn: undefined,
address: undefined,
params: {}
},
rules: {
giftBookId: [{ required: true, message: '礼薄不能为空', trigger: 'blur' }],
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
eventType: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
amount: [{ required: true, message: '金额不能为空', trigger: 'blur' }],
giftName: [{ required: true, message: '礼物名称不能为空', trigger: 'blur' }],
isReturn: [{ required: true, message: '是否已还不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs(data);
const giftBookList = ref<GiftBookVO[]>([]);
const uploadRef = ref<ElUploadInstance>();
/*** 用户导入参数 */
const upload = reactive<ImportOption>({
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: '',
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: globalHeaders(),
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + '/main/giftBookDetails/importData'
});
/** 查询礼薄详情列表 */
const getList = async () => {
loading.value = true;
const res = await listGiftBookDetails(queryParams.value);
giftBookDetailsList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
giftBookDetailsFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: GiftBookDetailsVO[]) => {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加礼薄详情';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: GiftBookDetailsVO) => {
reset();
const _id = row?.id || ids.value[0];
const res = await getGiftBookDetails(_id);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改礼薄详情';
};
/** 提交按钮 */
const submitForm = () => {
giftBookDetailsFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
await updateGiftBookDetails(form.value).finally(() => (buttonLoading.value = false));
} else {
await addGiftBookDetails(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: GiftBookDetailsVO) => {
const _ids = row?.id || ids.value;
await proxy?.$modal.confirm('是否确认删除礼薄详情编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
await delGiftBookDetails(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'main/giftBookDetails/export',
{
...queryParams.value
},
`礼薄明细_${new Date().getTime()}.xlsx`
);
};
/** 导出按钮操作 */
const handleExportWrod = () => {
proxy?.download(
'main/giftBookDetails/exportPDF',
{
...queryParams.value
},
`礼薄明细_${new Date().getTime()}.pdf`
);
};
/** 查询礼薄列表 */
const getGiftBookList = async () => {
const res = await listGiftBook({ querypageNum: -1 });
giftBookList.value = res.rows;
};
/** 导入按钮操作 */
const handleImport = () => {
upload.title = '用户导入';
upload.open = true;
};
/** 下载模板操作 */
const importTemplate = () => {
proxy?.download('main/giftBookDetails/importTemplate', {}, `礼薄详情模板_${new Date().getTime()}.xlsx`);
};
/**文件上传中处理 */
const handleFileUploadProgress = () => {
upload.isUploading = true;
};
/** 文件上传成功处理 */
const handleFileSuccess = (response: any, file: UploadFile) => {
upload.open = false;
upload.isUploading = false;
uploadRef.value?.handleRemove(file);
ElMessageBox.alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + '</div>', '导入结果', {
dangerouslyUseHTMLString: true
});
getList();
};
/** 提交上传文件 */
function submitFileForm() {
uploadRef.value?.submit();
}
onMounted(() => {
getList();
getGiftBookList();
});
</script>

View File

@@ -55,9 +55,9 @@
<el-tab-pane label="修改密码" name="resetPwd">
<resetPwd />
</el-tab-pane>
<el-tab-pane label="第三方应用" name="thirdParty">
<thirdParty :auths="state.auths" />
</el-tab-pane>
<!-- <el-tab-pane label="第三方应用" name="thirdParty">-->
<!-- <thirdParty :auths="state.auths" />-->
<!-- </el-tab-pane>-->
<el-tab-pane label="在线设备" name="onlineDevice">
<onlineDevice :devices="state.devices" />
</el-tab-pane>