修改crud代码,增加textarea类型支持。修改版本管理展示
This commit is contained in:
parent
12c5677a84
commit
3cd59b4cd7
176
README.en-US.md
176
README.en-US.md
|
|
@ -1,176 +0,0 @@
|
||||||
<div align="center">
|
|
||||||
<img alt="vue3-element-admin" width="80" height="80" src="./src/assets/logo.png">
|
|
||||||
<h1>vue3-element-admin</h1>
|
|
||||||
|
|
||||||
<img src="https://img.shields.io/badge/Vue-3.5.13-brightgreen.svg"/>
|
|
||||||
<img src="https://img.shields.io/badge/Vite-6.0.5-green.svg"/>
|
|
||||||
<img src="https://img.shields.io/badge/Element Plus-2.9.1-blue.svg"/>
|
|
||||||
<img src="https://img.shields.io/badge/license-MIT-green.svg"/>
|
|
||||||
<a href="https://gitee.com/youlaiorg" target="_blank">
|
|
||||||
<img src="https://img.shields.io/badge/Author-有来开源组织-orange.svg"/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="https://gitee.com/youlaiorg/youlai-boot" target="_blank">
|
|
||||||
<img alt="有来技术" src="https://gitee.com/youlaiorg/vue3-element-admin/badge/star.svg"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/youlaitech/vue3-element-admin" target="_blank">
|
|
||||||
<img alt="有来技术" src="https://img.shields.io/github/stars/youlaitech/vue3-element-admin.svg?style=social&label=Stars"/>
|
|
||||||
</a>
|
|
||||||
<a href="https://gitcode.com/youlai/vue3-element-admin" target="_blank">
|
|
||||||
<img alt="有来技术" src="https://gitcode.com/youlai/vue3-element-admin/star/badge.svg"/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
<a target="_blank" href="http://vue3.youlai.tech">👀 Live Preview</a> | <a target="_blank" href="https://juejin.cn/post/7228990409909108793">📖 Read Documentation</a> | 🌐 <a href="./README.md">中文
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
[vue3-element-admin](https://gitee.com/youlaiorg/vue3-element-admin) is a free and open-source admin template for backend management frontend, built with popular technologies such as Vue3, Vite5, TypeScript, Element-Plus, and Pinia (with accompanying [backend source code](https://gitee.com/youlaiorg/youlai-boot)).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Project Features
|
|
||||||
|
|
||||||
- **Simple and Easy-to-use**: Upgraded version of [vue-element-admin](https://gitee.com/panjiachen/vue-element-admin) for Vue3, with minimal encapsulation and easy to get started.
|
|
||||||
|
|
||||||
- **Data Interaction**: Support both local `Mock` data and remote API. Comes with [Java backend source code](https://gitee.com/youlaiorg/youlai-boot) and online API documentation.
|
|
||||||
|
|
||||||
- **Permission Management**: Complete permission system for users, roles, menus, dictionaries, and departments.
|
|
||||||
|
|
||||||
- **Essential Infrastructure**: Dynamic routing, button permissions, internationalization, code style, Git commit conventions, and common component encapsulation.
|
|
||||||
|
|
||||||
- **Continuous Updates**: Since 2021, the project has maintained an open-source status with continuous updates, integrating new tools and dependencies in real time, and has accumulated a broad user base.
|
|
||||||
|
|
||||||
## Project Preview
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Project Links
|
|
||||||
|
|
||||||
| Project | Gitee | Github | GitCode |
|
|
||||||
|----------| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
|
||||||
| Frontend | [vue3-element-admin](https://gitee.com/youlaiorg/vue3-element-admin) | [vue3-element-admin](https://github.com/youlaitech/vue3-element-admin) | [vue3-element-admin](https://gitcode.net/youlai/vue3-element-admin) |
|
|
||||||
| Lite | [vue3-element-template](https://gitee.com/youlaiorg/vue3-element-template) | [vue3-element-template](https://github.com/youlaitech/vue3-element-template) |-|
|
|
||||||
| Backend | [youlai-boot](https://gitee.com/youlaiorg/youlai-boot) | [youlai-boot](https://github.com/haoxianrui/youlai-boot.git) | [youlai-boot](https://gitcode.net/youlai/youlai-boot) |
|
|
||||||
|
|
||||||
## Environment Setup
|
|
||||||
|
|
||||||
| Environment | Name and Version | Download Link |
|
|
||||||
| -------------------- | :----------------------------------------------------------- | ------------------------------------------------------------ |
|
|
||||||
| **Development Tool** | VSCode | [Download](https://code.visualstudio.com/Download) |
|
|
||||||
| **Runtime Environment** | Node ≥18 | [Download](http://nodejs.cn/download) |
|
|
||||||
|
|
||||||
|
|
||||||
## Project Setup
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clone the repository
|
|
||||||
git clone https://gitee.com/youlaiorg/vue3-element-admin.git
|
|
||||||
|
|
||||||
# Change directory
|
|
||||||
cd vue3-element-admin
|
|
||||||
|
|
||||||
# Install pnpm
|
|
||||||
npm install pnpm -g
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
pnpm install
|
|
||||||
|
|
||||||
# Start the project
|
|
||||||
pnpm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
## Project Deployment
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build the project
|
|
||||||
pnpm run build
|
|
||||||
|
|
||||||
# Upload files to the remote server
|
|
||||||
Copy the files generated in the `dist` directory to the `/usr/share/nginx/html` directory.
|
|
||||||
|
|
||||||
# nginx.cofig configuration
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name localhost;
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
index index.html index.htm;
|
|
||||||
}
|
|
||||||
# Reverse proxy configuration
|
|
||||||
location /prod-api/ {
|
|
||||||
proxy_pass http://vapi.youlai.tech/; # Replace vapi.youlai.tech with your backend API address
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Local Mock
|
|
||||||
|
|
||||||
The project supports both online API and local mock API. By default, it uses the online API. If you want to switch to the mock API, modify the value of `VITE_MOCK_DEV_SERVER` in the `.env.development` file to `true`.
|
|
||||||
|
|
||||||
## Backend API
|
|
||||||
|
|
||||||
> If you have a basic understanding of Java development, follow these steps to convert online API to local backend API and set up a full-stack development environment.
|
|
||||||
|
|
||||||
1. Get the backend source code based on `Java` and `SpringBoot` from [youlai-boot](https://gitee.com/youlaiorg/youlai-boot.git).
|
|
||||||
2. Follow the instructions in the backend project's README.md to set up the local environment.
|
|
||||||
3. Modify the value of `VITE_APP_API_URL` in the `.env.development` file to `http://localhost:8989`, replacing it with the backend API URL.
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- **Auto import plugin is disabled by default**
|
|
||||||
|
|
||||||
Component type declarations have been automatically generated for the template project. If you add and use new components, follow the instructions in the screenshot to enable automatic generation. After automatic generation is complete, remember to set it back to `false` to avoid conflicts.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- **Blank page when accessing the project**
|
|
||||||
|
|
||||||
Try upgrading your browser, as older browser engines may not support certain new JavaScript syntax, such as optional chaining operator `?.`.
|
|
||||||
|
|
||||||
- **Red highlight on project components, functions, and imports**
|
|
||||||
|
|
||||||
Restart VSCode to try again.
|
|
||||||
|
|
||||||
- **Other issues**
|
|
||||||
|
|
||||||
If you have any other issues or suggestions, please open an [issue](https://gitee.com/youlaiorg/vue3-element-admin/issues/new).
|
|
||||||
|
|
||||||
## Project Documentation
|
|
||||||
|
|
||||||
- [Building a Backend Management System from Scratch with Vue3, Vite, TypeScript, and Element-Plus](https://blog.csdn.net/u013737132/article/details/130191394)
|
|
||||||
|
|
||||||
- [ESLint+Prettier+Stylelint+EditorConfig for Standardized and Unified Frontend Code Style](https://blog.csdn.net/u013737132/article/details/130190788)
|
|
||||||
- [Git Commit Conventions with Husky, Lint-staged, Commitlint, Commitizen, and cz-git](https://blog.csdn.net/u013737132/article/details/130191363)
|
|
||||||
|
|
||||||
## Commit Conventions
|
|
||||||
|
|
||||||
Execute `pnpm run commit` to invoke interactive git commit and complete the information input and selection according to the prompts.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Community 🚀
|
|
||||||
|
|
||||||
> **Follow "Youlai Tech" WeChat Official Account to get the QR code for the community.**
|
|
||||||
>
|
|
||||||
> If the QR code for the community has expired, please add my WeChat (haoxianrui) and indicate whether you are interested in "Frontend", "Backend", or "Full Stack" to get the latest QR code.
|
|
||||||
>
|
|
||||||
> This measure is taken to ensure the quality of the community and prevent marketing advertising from infiltrating. Thank you for your understanding!
|
|
||||||
|
|
||||||
| Official Account | Community |
|
|
||||||
|:----:|:----:|
|
|
||||||
|  |  |
|
|
||||||
|
|
||||||
|
|
@ -4,14 +4,28 @@ const baseURL = System_BaseUrl + "/admin/version";
|
||||||
|
|
||||||
const VersionApi = {
|
const VersionApi = {
|
||||||
getList() {
|
getList() {
|
||||||
return request<any, getListResponse>({
|
return request<any>({
|
||||||
url: `${baseURL}/list`,
|
url: `${baseURL}/list`,
|
||||||
method: "get",
|
method: "get",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
add(data: addRequest) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${baseURL}`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
edit(data: editRequest) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${baseURL}`,
|
||||||
|
method: "put",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
},
|
||||||
delete(id: string) {
|
delete(id: string) {
|
||||||
return request<any>({
|
return request<any>({
|
||||||
url: `${baseURL}/id`,
|
url: `${baseURL}/` + id,
|
||||||
method: "delete",
|
method: "delete",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -19,7 +33,7 @@ const VersionApi = {
|
||||||
|
|
||||||
export default VersionApi;
|
export default VersionApi;
|
||||||
|
|
||||||
export interface getListResponse {
|
export interface versionForm {
|
||||||
/**
|
/**
|
||||||
* 版本 id
|
* 版本 id
|
||||||
*/
|
*/
|
||||||
|
|
@ -50,3 +64,62 @@ export interface getListResponse {
|
||||||
version?: string;
|
version?: string;
|
||||||
[property: string]: any;
|
[property: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface addRequest {
|
||||||
|
/**
|
||||||
|
* 是否强制更新,0:不强制更新;1:强制更新
|
||||||
|
*/
|
||||||
|
isForce: number;
|
||||||
|
/**
|
||||||
|
* 更新内容
|
||||||
|
*/
|
||||||
|
message: string;
|
||||||
|
/**
|
||||||
|
* 渠道,pc 桌面端, manager_app 管理端, phone_book 电话机点餐
|
||||||
|
*/
|
||||||
|
source: string;
|
||||||
|
/**
|
||||||
|
* 类型,0 windows,1 安卓,2 iOS
|
||||||
|
*/
|
||||||
|
type: string;
|
||||||
|
/**
|
||||||
|
* 下载地址
|
||||||
|
*/
|
||||||
|
url: string;
|
||||||
|
/**
|
||||||
|
* 版本号
|
||||||
|
*/
|
||||||
|
version: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
export interface editRequest {
|
||||||
|
/**
|
||||||
|
* 版本id,ID 编号
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
/**
|
||||||
|
* 是否强制升级,0:不强制更新;1:强制更新
|
||||||
|
*/
|
||||||
|
isForce: number;
|
||||||
|
/**
|
||||||
|
* 更新内容
|
||||||
|
*/
|
||||||
|
message: string;
|
||||||
|
/**
|
||||||
|
* 渠道,pc 桌面端, manager_app 管理端, phone_book 电话机点餐
|
||||||
|
*/
|
||||||
|
source: string;
|
||||||
|
/**
|
||||||
|
* 类型,0 windows,1 安卓,2 iOS
|
||||||
|
*/
|
||||||
|
type: string;
|
||||||
|
/**
|
||||||
|
* 下载地址
|
||||||
|
*/
|
||||||
|
url: string;
|
||||||
|
/**
|
||||||
|
* 版本号
|
||||||
|
*/
|
||||||
|
version: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
</template>
|
</template>
|
||||||
<!-- textarea 输入框 -->
|
<!-- textarea 输入框 -->
|
||||||
|
|
||||||
<template v-else-if="item.type === 'textarea' || item.type === undefined">
|
<template v-else-if="item.type === 'textarea'">
|
||||||
<el-input v-model="formData[item.prop]" type="textarea" v-bind="item.attrs" />
|
<el-input v-model="formData[item.prop]" type="textarea" v-bind="item.attrs" />
|
||||||
</template>
|
</template>
|
||||||
<!-- Select 选择器 -->
|
<!-- Select 选择器 -->
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@
|
||||||
<el-input v-model="formData[item.prop]" v-bind="item.attrs" />
|
<el-input v-model="formData[item.prop]" v-bind="item.attrs" />
|
||||||
</template>
|
</template>
|
||||||
<!-- textarea 输入框 -->
|
<!-- textarea 输入框 -->
|
||||||
<template v-if="item.type === 'textarea' || item.type === undefined">
|
<template v-if="item.type === 'textarea'">
|
||||||
<el-input v-model="formData[item.prop]" v-bind="item.attrs" />
|
<el-input v-model="formData[item.prop]" v-bind="item.attrs" type="textarea" />
|
||||||
</template>
|
</template>
|
||||||
<!-- Select 选择器 -->
|
<!-- Select 选择器 -->
|
||||||
<template v-else-if="item.type === 'select'">
|
<template v-else-if="item.type === 'select'">
|
||||||
|
|
@ -161,6 +161,10 @@
|
||||||
<template v-if="item.type === 'input' || item.type === undefined">
|
<template v-if="item.type === 'input' || item.type === undefined">
|
||||||
<el-input v-model="formData[item.prop]" v-bind="item.attrs" />
|
<el-input v-model="formData[item.prop]" v-bind="item.attrs" />
|
||||||
</template>
|
</template>
|
||||||
|
<!-- textarea 输入框 -->
|
||||||
|
<template v-if="item.type === 'textarea'">
|
||||||
|
<el-input v-model="formData[item.prop]" v-bind="item.attrs" type="textarea" />
|
||||||
|
</template>
|
||||||
<!-- Select 选择器 -->
|
<!-- Select 选择器 -->
|
||||||
<template v-else-if="item.type === 'select'">
|
<template v-else-if="item.type === 'select'">
|
||||||
<el-select v-model="formData[item.prop]" v-bind="item.attrs">
|
<el-select v-model="formData[item.prop]" v-bind="item.attrs">
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ import {
|
||||||
UploadRequestOptions,
|
UploadRequestOptions,
|
||||||
} from "element-plus";
|
} from "element-plus";
|
||||||
|
|
||||||
import FileAPI, { FileInfo } from "@/api/file";
|
import CommonApi, { FileInfo, uploadResponse } from "@/api/account/common";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
/**
|
/**
|
||||||
|
|
@ -165,7 +165,7 @@ function handleUpload(options: UploadRequestOptions) {
|
||||||
formData.append(key, props.data[key]);
|
formData.append(key, props.data[key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
FileAPI.upload(formData)
|
CommonApi.upload(formData)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
resolve(data);
|
resolve(data);
|
||||||
})
|
})
|
||||||
|
|
@ -187,9 +187,9 @@ const handleProgress = (event: UploadProgressEvent) => {
|
||||||
/**
|
/**
|
||||||
* 上传成功
|
* 上传成功
|
||||||
*/
|
*/
|
||||||
const handleSuccess = (fileInfo: FileInfo) => {
|
const handleSuccess = (fileInfo: string) => {
|
||||||
ElMessage.success("上传成功");
|
ElMessage.success("上传成功");
|
||||||
modelValue.value = [...modelValue.value, fileInfo.url];
|
modelValue.value = [...modelValue.value, fileInfo];
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleError = (error: any) => {
|
const handleError = (error: any) => {
|
||||||
|
|
@ -200,19 +200,19 @@ const handleError = (error: any) => {
|
||||||
* 删除文件
|
* 删除文件
|
||||||
*/
|
*/
|
||||||
function handleRemove(fileUrl: string) {
|
function handleRemove(fileUrl: string) {
|
||||||
FileAPI.delete(fileUrl).then(() => {
|
// CommonApi.delete(fileUrl).then(() => {
|
||||||
modelValue.value = modelValue.value.filter((url) => url !== fileUrl);
|
modelValue.value = modelValue.value.filter((url) => url !== fileUrl);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 下载文件
|
* 下载文件
|
||||||
*/
|
*/
|
||||||
function handleDownload(file: UploadUserFile) {
|
function handleDownload(file: UploadUserFile) {
|
||||||
const { url, name } = file;
|
// const { url, name } = file;
|
||||||
if (url) {
|
// if (url) {
|
||||||
FileAPI.download(url, name);
|
// CommonApi.download(url, name);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ const isSidebarCollapsed = computed(() => !appStore.sidebar.opened);
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.has-logo {
|
.has-logo {
|
||||||
.el-scrollbar {
|
.el-scrollbar {
|
||||||
height: calc(100vh - $navbar-height);
|
height: calc(100vh - $navbar-height - $window-top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import UserAPI, { type UserForm } from "@/api/system/user";
|
import VersionApi, { type addRequest } from "@/api/system/version";
|
||||||
|
import { sourceOptions, typeOptions, isForceOptions } from "./config";
|
||||||
import type { IModalConfig } from "@/components/CURD/types";
|
import type { IModalConfig } from "@/components/CURD/types";
|
||||||
|
|
||||||
const modalConfig: IModalConfig<UserForm> = {
|
const modalConfig: IModalConfig<addRequest> = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
dialog: {
|
dialog: {
|
||||||
title: "新增版本",
|
title: "新增版本",
|
||||||
|
|
@ -11,7 +12,9 @@ const modalConfig: IModalConfig<UserForm> = {
|
||||||
form: {
|
form: {
|
||||||
labelWidth: 140,
|
labelWidth: 140,
|
||||||
},
|
},
|
||||||
formAction: UserAPI.add,
|
formAction: function (data) {
|
||||||
|
return VersionApi.add({ ...data, url: typeof data.url === "string" ? data.url : data.url[0] });
|
||||||
|
},
|
||||||
beforeSubmit(data) {
|
beforeSubmit(data) {
|
||||||
console.log("提交之前处理", data);
|
console.log("提交之前处理", data);
|
||||||
},
|
},
|
||||||
|
|
@ -24,11 +27,7 @@ const modalConfig: IModalConfig<UserForm> = {
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请选择渠道",
|
placeholder: "请选择渠道",
|
||||||
},
|
},
|
||||||
options: [
|
options: sourceOptions,
|
||||||
{ label: "桌面端", value: "pc" },
|
|
||||||
{ label: "管理端", value: "manager_app" },
|
|
||||||
{ label: "电话机点餐", value: "phone_book " },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "类型",
|
label: "类型",
|
||||||
|
|
@ -42,11 +41,7 @@ const modalConfig: IModalConfig<UserForm> = {
|
||||||
xs: 24,
|
xs: 24,
|
||||||
sm: 12,
|
sm: 12,
|
||||||
},
|
},
|
||||||
options: [
|
options: typeOptions,
|
||||||
{ label: "windows", value: 0 },
|
|
||||||
{ label: "安卓", value: 1 },
|
|
||||||
{ label: "iOS", value: 2 },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "input",
|
type: "input",
|
||||||
|
|
@ -66,20 +61,27 @@ const modalConfig: IModalConfig<UserForm> = {
|
||||||
placeholder: "请输入版本号",
|
placeholder: "请输入版本号",
|
||||||
},
|
},
|
||||||
initialValue: 0,
|
initialValue: 0,
|
||||||
options: [
|
options: isForceOptions,
|
||||||
{ label: "是", value: 1 },
|
|
||||||
{ label: "否", value: 0 },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "textarea",
|
type: "textarea",
|
||||||
label: "更新提示内容",
|
label: "更新提示内容",
|
||||||
prop: "version",
|
prop: "message",
|
||||||
rules: [{ required: true, message: "请输入版本号", trigger: "blur" }],
|
rules: [{ required: true, message: "请输入更新提示内容", trigger: "blur" }],
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请输入版本号",
|
placeholder: "请输入更新提示内容",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "custom",
|
||||||
|
label: "版本文件",
|
||||||
|
prop: "url",
|
||||||
|
rules: [{ required: true, message: "请上传版本文件", trigger: "blur" }],
|
||||||
|
attrs: {
|
||||||
|
placeholder: "请上传版本文件",
|
||||||
|
},
|
||||||
|
initialValue: [],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
export const sourceOptions: options[] = [
|
||||||
|
{ label: "桌面端", value: "pc" },
|
||||||
|
{ label: "管理端", value: "manager_app" },
|
||||||
|
{ label: "电话机点餐", value: "phone_book " },
|
||||||
|
];
|
||||||
|
export const typeOptions: options[] = [
|
||||||
|
{ label: "windows", value: "0" },
|
||||||
|
{ label: "安卓", value: "1" },
|
||||||
|
{ label: "IOS", value: "2" },
|
||||||
|
];
|
||||||
|
export const isForceOptions: options[] = [
|
||||||
|
{ label: "不强制更新", value: 0 },
|
||||||
|
{ label: "强制更新", value: 1 },
|
||||||
|
];
|
||||||
|
|
||||||
|
export type optionsType = "source" | "type" | "isForce";
|
||||||
|
|
||||||
|
export function returnOptions(type: optionsType) {
|
||||||
|
if (type === "source") {
|
||||||
|
return sourceOptions;
|
||||||
|
}
|
||||||
|
if (type === "type") {
|
||||||
|
return typeOptions;
|
||||||
|
}
|
||||||
|
if (type === "isForce") {
|
||||||
|
return isForceOptions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function returnOptionsLabel(optionsType: optionsType, value: string | number) {
|
||||||
|
const options = returnOptions(optionsType);
|
||||||
|
if (!options) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const option = options.find((item) => item.value === value);
|
||||||
|
return option ? option.label : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface options {
|
||||||
|
label: string;
|
||||||
|
value: string | number;
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import VersionApi from "@/api/system/version";
|
import VersionApi from "@/api/system/version";
|
||||||
import RoleAPI from "@/api/system/role";
|
import type { editRequest } from "@/api/system/version";
|
||||||
import type { UserPageQuery } from "@/api/system/user";
|
|
||||||
import type { IContentConfig } from "@/components/CURD/types";
|
import type { IContentConfig } from "@/components/CURD/types";
|
||||||
|
|
||||||
const contentConfig: IContentConfig<UserPageQuery> = {
|
const contentConfig: IContentConfig<editRequest> = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
table: {
|
table: {
|
||||||
border: true,
|
border: true,
|
||||||
|
|
@ -19,30 +18,37 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
||||||
return VersionApi.getList();
|
return VersionApi.getList();
|
||||||
},
|
},
|
||||||
deleteAction: VersionApi.delete,
|
deleteAction: VersionApi.delete,
|
||||||
importsAction(data) {
|
// modifyAction: function (data) {
|
||||||
// 模拟导入数据
|
// // return VersionApi.edit(data);
|
||||||
console.log("importsAction", data);
|
// },
|
||||||
return Promise.resolve();
|
|
||||||
},
|
|
||||||
exportsAction: async function (params) {
|
|
||||||
// 模拟获取到的是全量数据
|
|
||||||
const res = await VersionApi.getList(params);
|
|
||||||
console.log("exportsAction", res.list);
|
|
||||||
return res.list;
|
|
||||||
},
|
|
||||||
pk: "id",
|
pk: "id",
|
||||||
toolbar: ["add"],
|
toolbar: ["add"],
|
||||||
defaultToolbar: ["refresh", "filter", "search"],
|
defaultToolbar: ["refresh", "filter", "search"],
|
||||||
cols: [
|
cols: [
|
||||||
{ type: "selection", width: 50, align: "center" },
|
{ type: "selection", width: 50, align: "center" },
|
||||||
{ label: "id", align: "center", prop: "id", width: 100, show: true },
|
{ label: "id", align: "center", prop: "id", width: 100, show: true },
|
||||||
{ label: "渠道", align: "center", prop: "source" },
|
{
|
||||||
|
label: "渠道",
|
||||||
|
align: "center",
|
||||||
|
prop: "source",
|
||||||
|
width: 120,
|
||||||
|
templet: "custom",
|
||||||
|
slotName: "options",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "类型",
|
label: "类型",
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "type",
|
prop: "type",
|
||||||
|
width: 120,
|
||||||
|
templet: "custom",
|
||||||
|
slotName: "options",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "版本号",
|
||||||
|
align: "center",
|
||||||
|
width: 120,
|
||||||
|
prop: "version",
|
||||||
},
|
},
|
||||||
{ label: "版本号", align: "center", prop: "version" },
|
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "是否强制升级",
|
label: "是否强制升级",
|
||||||
|
|
@ -52,6 +58,12 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
||||||
templet: "switch",
|
templet: "switch",
|
||||||
slotName: "isForce",
|
slotName: "isForce",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "更新内容",
|
||||||
|
align: "center",
|
||||||
|
prop: "message",
|
||||||
|
width: 240,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "下载地址",
|
label: "下载地址",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|
@ -65,20 +77,7 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
||||||
fixed: "right",
|
fixed: "right",
|
||||||
width: 280,
|
width: 280,
|
||||||
templet: "tool",
|
templet: "tool",
|
||||||
operat: [
|
operat: ["edit", "delete"],
|
||||||
{
|
|
||||||
icon: "Document",
|
|
||||||
name: "edit",
|
|
||||||
text: "编辑",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "delete",
|
|
||||||
icon: "delete",
|
|
||||||
text: "删除",
|
|
||||||
},
|
|
||||||
"edit",
|
|
||||||
"delete",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,116 +1,85 @@
|
||||||
import UserAPI, { type UserForm } from "@/api/system/user";
|
import VersionApi, { type editRequest } from "@/api/system/version";
|
||||||
import type { IModalConfig } from "@/components/CURD/types";
|
import type { IModalConfig } from "@/components/CURD/types";
|
||||||
import { DeviceEnum } from "@/enums/DeviceEnum";
|
import { sourceOptions, typeOptions, isForceOptions } from "./config";
|
||||||
import { useAppStore } from "@/store";
|
|
||||||
|
|
||||||
const modalConfig: IModalConfig<UserForm> = {
|
const modalConfig: IModalConfig<editRequest> = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
component: "drawer",
|
dialog: {
|
||||||
drawer: {
|
title: "编辑版本",
|
||||||
title: "修改用户",
|
width: 800,
|
||||||
size: useAppStore().device === DeviceEnum.MOBILE ? "80%" : 500,
|
draggable: true,
|
||||||
},
|
},
|
||||||
pk: "id",
|
pk: "id",
|
||||||
formAction: function (data) {
|
formAction: function (data) {
|
||||||
return UserAPI.update(data.id as number, data);
|
return VersionApi.edit({ ...data, url: typeof data.url === "string" ? data.url : data.url[0] });
|
||||||
},
|
},
|
||||||
beforeSubmit(data) {
|
beforeSubmit(data) {
|
||||||
console.log("提交之前处理", data);
|
console.log("提交之前处理", data);
|
||||||
},
|
},
|
||||||
formItems: [
|
formItems: [
|
||||||
{
|
{
|
||||||
label: "用户名",
|
label: "渠道",
|
||||||
prop: "username",
|
prop: "source",
|
||||||
rules: [{ required: true, message: "用户名不能为空", trigger: "blur" }],
|
rules: [{ required: true, message: "请选择渠道", trigger: "blur" }],
|
||||||
type: "input",
|
type: "select",
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请输入用户名",
|
placeholder: "请选择渠道",
|
||||||
readonly: true,
|
},
|
||||||
|
options: sourceOptions,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "类型",
|
||||||
|
prop: "type",
|
||||||
|
rules: [{ required: true, message: "请选择类型", trigger: "blur" }],
|
||||||
|
type: "select",
|
||||||
|
attrs: {
|
||||||
|
placeholder: "请选择类型",
|
||||||
|
},
|
||||||
|
col: {
|
||||||
|
xs: 24,
|
||||||
|
sm: 12,
|
||||||
|
},
|
||||||
|
options: typeOptions,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "input",
|
||||||
|
label: "版本号",
|
||||||
|
prop: "version",
|
||||||
|
rules: [{ required: true, message: "请输入版本号", trigger: "blur" }],
|
||||||
|
attrs: {
|
||||||
|
placeholder: "请输入版本号",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "用户昵称",
|
type: "radio",
|
||||||
prop: "nickname",
|
label: "是否强制更新",
|
||||||
rules: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
|
prop: "isForce",
|
||||||
type: "input",
|
rules: [{ required: true, message: "请输入版本号", trigger: "blur" }],
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请输入用户昵称",
|
placeholder: "请输入版本号",
|
||||||
},
|
},
|
||||||
|
initialValue: 0,
|
||||||
|
options: isForceOptions,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "所属部门",
|
type: "textarea",
|
||||||
prop: "deptId",
|
label: "更新提示内容",
|
||||||
rules: [{ required: true, message: "所属部门不能为空", trigger: "blur" }],
|
prop: "message",
|
||||||
type: "tree-select",
|
rules: [{ required: true, message: "请输入更新提示内容", trigger: "blur" }],
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请选择所属部门",
|
placeholder: "请输入更新提示内容",
|
||||||
data: [],
|
|
||||||
filterable: true,
|
|
||||||
"check-strictly": true,
|
|
||||||
"render-after-expand": false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "custom",
|
type: "custom",
|
||||||
label: "性别",
|
label: "版本文件",
|
||||||
prop: "gender",
|
prop: "url",
|
||||||
initialValue: 1,
|
rules: [{ required: true, message: "请上传版本文件", trigger: "blur" }],
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "角色",
|
|
||||||
prop: "roleIds",
|
|
||||||
rules: [{ required: true, message: "用户角色不能为空", trigger: "blur" }],
|
|
||||||
type: "select",
|
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请选择",
|
placeholder: "请上传版本文件",
|
||||||
multiple: true,
|
|
||||||
},
|
},
|
||||||
options: [],
|
|
||||||
initialValue: [],
|
initialValue: [],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type: "input",
|
|
||||||
label: "手机号码",
|
|
||||||
prop: "mobile",
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
|
||||||
message: "请输入正确的手机号码",
|
|
||||||
trigger: "blur",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
attrs: {
|
|
||||||
placeholder: "请输入手机号码",
|
|
||||||
maxlength: 11,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "邮箱",
|
|
||||||
prop: "email",
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
pattern: /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/,
|
|
||||||
message: "请输入正确的邮箱地址",
|
|
||||||
trigger: "blur",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
type: "input",
|
|
||||||
attrs: {
|
|
||||||
placeholder: "请输入邮箱",
|
|
||||||
maxlength: 50,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "状态",
|
|
||||||
prop: "status",
|
|
||||||
type: "switch",
|
|
||||||
attrs: {
|
|
||||||
activeText: "正常",
|
|
||||||
inactiveText: "禁用",
|
|
||||||
activeValue: 1,
|
|
||||||
inactiveValue: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@
|
||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
|
<template #options="scope">
|
||||||
|
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||||
|
</template>
|
||||||
<template #gender="scope">
|
<template #gender="scope">
|
||||||
<DictLabel v-model="scope.row[scope.prop]" code="gender" />
|
<DictLabel v-model="scope.row[scope.prop]" code="gender" />
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -45,8 +48,9 @@
|
||||||
:modal-config="addModalConfig"
|
:modal-config="addModalConfig"
|
||||||
@submit-click="handleSubmitClick"
|
@submit-click="handleSubmitClick"
|
||||||
>
|
>
|
||||||
<template #gender="scope">
|
<template #url="scope">
|
||||||
<Dict v-model="scope.formData[scope.prop]" code="gender" />
|
<FileUpload v-model="scope.formData[scope.prop]" :limit="1" v-bind="scope.attrs" />
|
||||||
|
<!-- <Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" /> -->
|
||||||
</template>
|
</template>
|
||||||
</page-modal>
|
</page-modal>
|
||||||
|
|
||||||
|
|
@ -56,8 +60,9 @@
|
||||||
:modal-config="editModalConfig"
|
:modal-config="editModalConfig"
|
||||||
@submit-click="handleSubmitClick"
|
@submit-click="handleSubmitClick"
|
||||||
>
|
>
|
||||||
<template #gender="scope">
|
<template #url="scope">
|
||||||
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
|
<FileUpload v-model="scope.formData[scope.prop]" :limit="1" v-bind="scope.attrs" />
|
||||||
|
<!-- <Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" /> -->
|
||||||
</template>
|
</template>
|
||||||
</page-modal>
|
</page-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -88,6 +93,7 @@ import contentConfig from "./config/content";
|
||||||
import contentConfig2 from "./config/content2";
|
import contentConfig2 from "./config/content2";
|
||||||
import editModalConfig from "./config/edit";
|
import editModalConfig from "./config/edit";
|
||||||
import searchConfig from "./config/search";
|
import searchConfig from "./config/search";
|
||||||
|
import { returnOptionsLabel } from "./config/config";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
searchRef,
|
searchRef,
|
||||||
|
|
@ -108,18 +114,20 @@ const {
|
||||||
async function handleAddClick() {
|
async function handleAddClick() {
|
||||||
addModalRef.value?.setModalVisible();
|
addModalRef.value?.setModalVisible();
|
||||||
// 加载部门下拉数据源
|
// 加载部门下拉数据源
|
||||||
addModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
// addModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
||||||
// 加载角色下拉数据源
|
// 加载角色下拉数据源
|
||||||
addModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
// addModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
||||||
}
|
}
|
||||||
// 编辑
|
// 编辑
|
||||||
async function handleEditClick(row: IObject) {
|
async function handleEditClick(row: IObject) {
|
||||||
editModalRef.value?.handleDisabled(false);
|
editModalRef.value?.handleDisabled(false);
|
||||||
editModalRef.value?.setModalVisible();
|
editModalRef.value?.setModalVisible();
|
||||||
// 根据id获取数据进行填充
|
// 根据id获取数据进行填充
|
||||||
const data = await VersionApi.getFormData(row.id);
|
// const data = await VersionApi.getFormData(row.id);
|
||||||
editModalRef.value?.setFormData(data);
|
console.log({ ...row, url: [row.url] });
|
||||||
|
editModalRef.value?.setFormData({ ...row, url: [row.url] });
|
||||||
}
|
}
|
||||||
|
1;
|
||||||
// 其他工具栏
|
// 其他工具栏
|
||||||
function handleToolbarClick(name: string) {
|
function handleToolbarClick(name: string) {
|
||||||
console.log(name);
|
console.log(name);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue