15 Commits

Author SHA1 Message Date
ahjung
19df8d5f09 1.9.2 2024-06-29 17:35:10 +08:00
Ah jung
489f791caa Update README.md 2024-06-11 21:43:40 +08:00
ahjung
2f72f34bbe 优化已知错误 2024-05-12 11:02:47 +08:00
ahjung
3d4d554733 文案修改 2024-04-10 14:44:27 +08:00
ahjung
38fe255306 basicModal 组件 导出 modalMethods 方法 2024-04-10 14:36:36 +08:00
ahjung
58e99c183b README 文件更新 2024-04-09 16:43:58 +08:00
ahjung
ee8aed2f62 1.9.1 2024-04-09 16:28:28 +08:00
Ah jung
260397f3ae Merge pull request #279 from thatsgolden/patch-1
feat(BasicForm): trigger query via Enter key
2024-04-09 15:45:58 +08:00
Golden
fa983a9b64 feat(BasicForm): trigger query via Enter key
- Allow push Enter key to query the table form.
2024-03-04 13:36:55 +08:00
Ah jung
4c49e28596 Merge pull request #272 from Mevolove/main
style: 加宽基础表单,分步表单和上传图片中label的宽度
2024-02-18 13:38:49 +08:00
Mevol
9a5fe5249c style: 加宽基础表单,分步表单和上传图片中label的宽度 2024-01-16 15:19:10 +08:00
Ah jung
02235bf6fc Merge pull request #265 from NogiRuka/style/center-upload-icon-and-text-in-basicForm
style(BasicUpload): center upload icon and text in BasicForm
2023-10-25 19:31:11 +08:00
“乃木流架”
0656035857 style(BasicUpload): center upload icon and text in BasicForm 2023-10-21 23:54:14 +09:00
Ah jung
81e8222461 Merge pull request #257 from L1yp/fix-transition-hot-refresh
fix: 修复transition组件导致的白屏(重现: 热更新transition下的组件script代码切换tab即可)
2023-08-10 15:07:26 +08:00
Lyp
09411a927e fix: 修复transition组件导致的白屏(重现: 热更新transition下的组件script代码切换tab即可) 2023-08-10 14:55:16 +08:00
37 changed files with 7398 additions and 5924 deletions

View File

@@ -1,5 +1,18 @@
# CHANGELOG # CHANGELOG
## 1.9.2
- 升级 `vite``5.x` 版本
- 优化 `BasicTable` 组件,编辑样式
- 新增 `BasicTable` 组件,支持 `striped` 入参
- 依赖升级
## 1.9.1
- 优化 `typeSctipt` 类型定义
- 优化 `setup` 语法
- 依赖升级
## 1.9.0 ## 1.9.0
- 新增 `BasicForm` 组件,支持 `setLoading`, `setSchema` 方法 - 新增 `BasicForm` 组件,支持 `setLoading`, `setSchema` 方法
@@ -13,6 +26,7 @@
- 修复 `手机端侧边导航风格不一致bug` 关闭[#247](https://github.com/jekip/naive-ui-admin/issues/247 - 修复 `手机端侧边导航风格不一致bug` 关闭[#247](https://github.com/jekip/naive-ui-admin/issues/247
- 移除 `yarn.lock` 文件 - 移除 `yarn.lock` 文件
- 依赖升级 - 依赖升级
## 1.8.2 ## 1.8.2
- ### ✨ Features - ### ✨ Features

View File

@@ -1,38 +1,42 @@
## 简介 ## 🚀 简介
[Naive Ui Admin](https://github.com/jekip/naive-ui-admin) 完全免费且可商用,基于 [Vue3.0](https://github.com/vuejs/vue-next)、[Vite](https://github.com/vitejs/vite)、 [Naive UI](https://www.naiveui.com/)、[TypeScript](https://www.typescriptlang.org/) 的中后台解决方案,它使用了最新的前端技术栈,并提炼了典型的业务模型,页面,包括二次封装组件、动态菜单、权限校验、粒子化权限控制等功能,它可以帮助你快速搭建企业级中后台项目, 相信不管是从新技术使用还是其他方面,都能帮助到你 `Naive Ui Admin` 是一款 完全免费 且可商用的中后台解决方案,基于 🌟 `Vue3.0` 🌟、🚀 `Vite` 🚀、✨ [Naive UI](https://www.naiveui.com/) ✨ 和 🎉 `TypeScript` 🎉
它融合了最新的前端技术栈,提炼了典型的业务模型和页面,包括二次封装组件、动态菜单、权限校验等功能,助力快速搭建企业级中后台项目。
## 特性
- 二次封装实用高扩展性组件
- 响应式、多主题,多配置,快速集成,开箱即用
- 最新技术栈,使用 `Vue3``Typescript``Pinia``Vite` 等前端前沿技术
- 强大的鉴权系统,对路由、菜单、功能点等支持`三种鉴权模式`,满足不同的业务鉴权需求
- 持续更新,实用性页面模板功能和交互,随意搭配组合,让构建页面变得简单化
## 预览
## 🌈 特性
📦 二次封装的实用高扩展性组件
🎨 响应式、多主题、多配置,快速集成,开箱即用
🚀 强大的鉴权系统,支持 三种鉴权模式,满足多样业务需求
🌐 持续更新的实用性页面模板和交互设计,简化页面构建
## 🎥 预览
- [naive-ui-admin](https://jekip.github.io) - [naive-ui-admin](https://jekip.github.io)
账号admin密码123456随意 账号admin密码123456随意
## 提示 ## 💡 提示
如果开源版本的功能和组件,并不能满足您的需求,不妨看看,我们全新 `NaiveAdmin` 他或许能让您眼前一亮O(∩_∩)O哈哈~ 如果您需要更多功能和组件,不妨尝试全新 `NaiveAdmin`,它可能正是您寻找的解决方案
[NaiveAdmin 官网](https://www.naiveadmin.com) [NaiveAdmin 官网](https://www.naiveadmin.com)
[NaiveAdmin 变更日志](https://www.yuque.com/u5825/zaqu0e) [NaiveAdmin 变更日志](https://www.yuque.com/u5825/zaqu0e)
[为什么选我们?](https://www.naiveadmin.com/choose/we) [为什么选我们?](https://www.naiveadmin.com/choose/we)
### Plus ### Plus
基于 `NaiveUi` 全新设计版本,增众多特性,强烈推荐 基于 `NaiveUi` 全新设计版本,增加了众多特性,值得一试
[NaiveAdmin Plus 预览](https://plus.naiveadmin.com) [NaiveAdmin Plus 预览](https://plus.naiveadmin.com)
### Arco vue ### Arco vue
智能设计体系,连接轻盈体验 智能设计体系,提供轻盈体验
[NaiveAdmin Arco 预览](https://arco.naiveadmin.com) [NaiveAdmin Arco 预览](https://arco.naiveadmin.com)
@@ -50,11 +54,11 @@
[NaiveAdmin Antd 预览](https://antd.naiveadmin.com) [NaiveAdmin Antd 预览](https://antd.naiveadmin.com)
## 文档 ## 📚 文档
[文档地址](https://jekip.github.io/docs) [文档地址](https://docs.naiveadmin.com)
## 准备 ## 🛠 准备
- [node](http://nodejs.org/) 和 [git](https://git-scm.com/) -项目开发环境 - [node](http://nodejs.org/) 和 [git](https://git-scm.com/) -项目开发环境
- [Vite](https://vitejs.dev/) - 熟悉 vite 特性 - [Vite](https://vitejs.dev/) - 熟悉 vite 特性
@@ -62,10 +66,11 @@
- [TypeScript](https://www.typescriptlang.org/) - 熟悉`TypeScript`基本语法 - [TypeScript](https://www.typescriptlang.org/) - 熟悉`TypeScript`基本语法
- [Es6+](http://es6.ruanyifeng.com/) - 熟悉 es6 基本语法 - [Es6+](http://es6.ruanyifeng.com/) - 熟悉 es6 基本语法
- [Vue-Router-Next](https://next.router.vuejs.org/) - 熟悉 vue-router 基本使用 - [Vue-Router-Next](https://next.router.vuejs.org/) - 熟悉 vue-router 基本使用
- [Naive-ui-admin](https://www.naiveui.com/) - ui 基本使用 - [NaiveUi](https://www.naiveui.com/) - ui 基本使用
- [Mock.js](https://github.com/nuysoft/Mock) - mockjs 基本语法 - [Mock.js](https://github.com/nuysoft/Mock) - mockjs 基本语法
## 使用
## 🏗️ 使用
- 获取项目代码 - 获取项目代码
@@ -78,30 +83,30 @@ git clone https://github.com/jekip/naive-ui-admin.git
```bash ```bash
cd naive-ui-admin cd naive-ui-admin
yarn install pnpm install
``` ```
- 运行 - 运行
```bash ```bash
yarn dev pnpm run dev
``` ```
- 打包 - 打包
```bash ```bash
yarn build pnpm build
``` ```
## 更新日志 ## 📜 更新日志
[CHANGELOG](./CHANGELOG.md) [CHANGELOG](./CHANGELOG.md)
## 如何贡献 ## 🤝 如何贡献
非常欢迎你的加入![提一个 Issue](https://github.com/jekip/naive-ui-admin/issues) 或者提交一个 Pull Request 非常欢迎你的加入![提一个 Issue](https://github.com/jekip/naive-ui-admin/issues) 或者提交一个 `Pull Request`
**Pull Request:** **Pull Request:**
@@ -111,7 +116,7 @@ yarn build
4. 推送您的分支: `git push origin feat/xxxx` 4. 推送您的分支: `git push origin feat/xxxx`
5. 提交`pull request` 5. 提交`pull request`
## Git 贡献提交规范 ## 📋 Git 贡献提交规范
- 参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 规范 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular)) - 参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 规范 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))
@@ -129,7 +134,7 @@ yarn build
- `types` 类型定义文件更改 - `types` 类型定义文件更改
- `wip` 开发中 - `wip` 开发中
## 浏览器支持 ## 🌐 浏览器支持
本地开发推荐使用`Chrome 80+` 浏览器 本地开发推荐使用`Chrome 80+` 浏览器
@@ -139,17 +144,17 @@ yarn build
| :-: | :-: | :-: | :-: | :-: | | :-: | :-: | :-: | :-: | :-: |
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions | | not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
## 维护者 ## 👥 维护者
[@Ah jung](https://github.com/jekip) [@Ah jung](https://github.com/jekip)
## 交流 ## 💬 交流
`Naive Ui Admin` 使用或其他问题,都可以在群内讨论或提问 有关 `Naive Ui Admin` 使用或其他问题,欢迎加入我们的讨论群组或提出问题
![160335146-c28dd205-4600-4d62-b2c6-6456034ab7b1](https://user-images.githubusercontent.com/19426584/217689718-407e6cb9-dd3b-4a11-a025-3c58834b52ff.jpg) ![160335146-c28dd205-4600-4d62-b2c6-6456034ab7b1](https://user-images.githubusercontent.com/19426584/217689718-407e6cb9-dd3b-4a11-a025-3c58834b52ff.jpg)
## 赞助 ## 💖 赞助
#### 如果觉得这个项目帮助到了你,你可以帮作者买一杯果汁表示鼓励 🍹 #### 如果觉得这个项目对您有帮助,可以通过下面的链接为作者买一杯果汁表示感谢!
![donate](https://jekip.github.io/docs/images/sponsor.png) ![donate](https://jekip.github.io/docs/images/sponsor.png)

View File

@@ -1,57 +0,0 @@
module.exports = {
ignores: [(commit) => commit.includes('init')],
extends: ['@commitlint/config-conventional'],
parserPreset: {
parserOpts: {
headerPattern: /^(\w*|[\u4e00-\u9fa5]*)(?:[\(\](.*)[\)\])?[\:\] (.*)/,
headerCorrespondence: ['type', 'scope', 'subject'],
referenceActions: [
'close',
'closes',
'closed',
'fix',
'fixes',
'fixed',
'resolve',
'resolves',
'resolved',
],
issuePrefixes: ['#'],
noteKeywords: ['BREAKING CHANGE'],
fieldPattern: /^-(.*?)-$/,
revertPattern: /^Revert\s"([\s\S]*)"\s*This reverts commit (\w*)\./,
revertCorrespondence: ['header', 'hash'],
warn() {},
mergePattern: null,
mergeCorrespondence: null,
},
},
rules: {
'body-leading-blank': [2, 'always'],
'footer-leading-blank': [1, 'always'],
'header-max-length': [2, 'always', 108],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never'],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release',
],
],
},
};

View File

@@ -1,6 +1,6 @@
{ {
"name": "naive-ui-admin", "name": "naive-ui-admin",
"version": "1.9.0", "version": "1.9.3",
"author": { "author": {
"name": "Ahjung", "name": "Ahjung",
"email": "735878602@qq.com", "email": "735878602@qq.com",
@@ -12,91 +12,89 @@
"serve": "pnpm run dev", "serve": "pnpm run dev",
"dev": "vite", "dev": "vite",
"build": "vite build && esno ./build/script/postBuild.ts", "build": "vite build && esno ./build/script/postBuild.ts",
"build:no-cache": "pnpm clean:cache && npm run build", "build:no-cache": "pnpm clean:cache && pnpm run build",
"report": "cross-env REPORT=true npm run build", "report": "cross-env REPORT=true pnpm run build",
"preview": "npm run build && vite preview", "preview": "pnpm run build && vite preview",
"preview:dist": "vite preview", "preview:dist": "vite preview",
"clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite", "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite",
"clean:lib": "rimraf node_modules", "clean:lib": "rimraf node_modules",
"build typecheck": "vuedx-typecheck . && vite build",
"deploy": "gh-pages -d dist", "deploy": "gh-pages -d dist",
"lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix", "lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"", "lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
"lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/", "lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
"lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js", "lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
"lint:pretty": "pretty-quick --staged", "lint:pretty": "pretty-quick --staged"
"test prod gzip": "http-server dist --cors --gzip -c-1"
}, },
"dependencies": { "dependencies": {
"@vicons/antd": "^0.12.0", "@vicons/antd": "^0.12.0",
"@vicons/ionicons5": "^0.12.0", "@vicons/ionicons5": "^0.12.0",
"@vueup/vue-quill": "^1.2.0", "@vueup/vue-quill": "^1.2.0",
"@vueuse/core": "^9.13.0", "@vueuse/core": "^9.13.0",
"axios": "^1.4.0", "axios": "^1.7.2",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"date-fns": "^2.30.0", "date-fns": "^2.30.0",
"echarts": "^5.4.3", "echarts": "^5.5.1",
"element-resize-detector": "^1.2.4", "element-resize-detector": "^1.2.4",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"naive-ui": "^2.34.4", "naive-ui": "^2.38.2",
"pinia": "^2.1.6", "pinia": "^2.1.7",
"qs": "^6.11.2", "qs": "^6.12.1",
"vfonts": "^0.0.3", "vfonts": "^0.0.3",
"vue": "^3.3.4", "vue": "^3.4.31",
"vue-router": "^4.2.4", "vue-router": "^4.4.0",
"vue-types": "^4.2.1" "vue-types": "^4.2.1"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^17.7.0", "@commitlint/cli": "^17.8.1",
"@commitlint/config-conventional": "^17.7.0", "@commitlint/config-conventional": "^17.8.1",
"@types/lodash": "^4.14.197", "@types/lodash": "^4.17.6",
"@types/node": "^18.17.4", "@types/node": "^18.19.39",
"@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0", "@typescript-eslint/parser": "^5.62.0",
"@vitejs/plugin-vue": "^3.2.0", "@vitejs/plugin-vue": "^3.2.0",
"@vitejs/plugin-vue-jsx": "^2.1.1", "@vitejs/plugin-vue-jsx": "^2.1.1",
"@vue/compiler-sfc": "^3.3.4", "@vue/compiler-sfc": "^3.4.31",
"@vue/eslint-config-typescript": "^11.0.3", "@vue/eslint-config-typescript": "^11.0.3",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.19",
"commitizen": "^4.3.0", "commitizen": "^4.3.0",
"core-js": "^3.32.0", "core-js": "^3.37.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"dotenv": "^16.3.1", "dotenv": "^16.4.5",
"eslint": "^8.46.0", "eslint": "^8.57.0",
"eslint-config-prettier": "^8.10.0", "eslint-config-prettier": "^8.10.0",
"eslint-define-config": "1.12.0", "eslint-define-config": "1.12.0",
"eslint-plugin-jest": "^27.2.3", "eslint-plugin-jest": "^27.9.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.17.0", "eslint-plugin-vue": "^9.26.0",
"esno": "^0.16.3", "esno": "^0.16.3",
"gh-pages": "^4.0.0", "gh-pages": "^4.0.0",
"husky": "^8.0.3", "husky": "^8.0.3",
"jest": "^29.6.2", "jest": "^29.7.0",
"less": "^4.2.0", "less": "^4.2.0",
"less-loader": "^11.1.3", "less-loader": "^11.1.4",
"lint-staged": "^13.2.3", "lint-staged": "^13.3.0",
"postcss": "^8.4.27", "postcss": "^8.4.38",
"prettier": "^2.8.8", "prettier": "^2.8.8",
"pretty-quick": "^3.1.3", "pretty-quick": "^3.3.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"stylelint": "^14.16.1", "stylelint": "^14.16.1",
"stylelint-config-prettier": "^9.0.5", "stylelint-config-prettier": "^9.0.5",
"stylelint-config-standard": "^29.0.0", "stylelint-config-standard": "^29.0.0",
"stylelint-order": "^5.0.0", "stylelint-order": "^5.0.0",
"stylelint-scss": "^4.7.0", "stylelint-scss": "^4.7.0",
"tailwindcss": "^3.3.3", "tailwindcss": "^3.4.4",
"typescript": "^4.9.5", "typescript": "^4.9.5",
"unplugin-vue-components": "^0.22.12", "unplugin-vue-components": "^0.22.12",
"vite": "^3.2.7", "vite": "^5.3.2",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vite-plugin-html": "^3.2.0", "vite-plugin-html": "^3.2.2",
"vite-plugin-mock": "^2.9.8", "vite-plugin-mock": "^2.9.8",
"vite-plugin-style-import": "^2.0.0", "vite-plugin-style-import": "^2.0.0",
"vue-demi": "^0.13.11", "vue-demi": "^0.13.11",
"vue-draggable-next": "^2.2.1", "vue-draggable-next": "^2.2.1",
"vue-eslint-parser": "^9.3.1", "vue-eslint-parser": "^9.4.3",
"vuedraggable": "^4.1.0" "vuedraggable": "^4.1.0"
}, },
"lint-staged": { "lint-staged": {

12133
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -81,7 +81,3 @@
document.removeEventListener('mousedown', timekeeping); document.removeEventListener('mousedown', timekeeping);
}); });
</script> </script>
<style lang="less">
@import 'styles/index.less';
</style>

View File

@@ -90,6 +90,7 @@
v-bind="getSubmitBtnOptions" v-bind="getSubmitBtnOptions"
@click="handleSubmit" @click="handleSubmit"
:loading="loadingSub" :loading="loadingSub"
attr-type="submit"
>{{ getProps.submitButtonText }}</n-button >{{ getProps.submitButtonText }}</n-button
> >
<n-button <n-button

View File

@@ -98,6 +98,8 @@
if (instance) { if (instance) {
emit('register', modalMethods); emit('register', modalMethods);
} }
defineExpose(modalMethods);
</script> </script>
<style lang="less"> <style lang="less">

View File

@@ -156,7 +156,7 @@
const tableElRef = ref<ComponentRef>(null); const tableElRef = ref<ComponentRef>(null);
const wrapRef = ref<Nullable<HTMLDivElement>>(null); const wrapRef = ref<Nullable<HTMLDivElement>>(null);
let paginationEl: HTMLElement | null; let paginationEl: HTMLElement | null;
const isStriped = ref(false); const isStriped = ref(props.striped || false);
const tableData = ref<Recordable[]>([]); const tableData = ref<Recordable[]>([]);
const innerPropsRef = ref<Partial<BasicTableProps>>(); const innerPropsRef = ref<Partial<BasicTableProps>>();

View File

@@ -1,12 +1,6 @@
<template> <template>
<div class="editable-cell"> <div class="editable-cell">
<div v-show="!isEdit" class="editable-cell-content" @click="handleEdit"> <div class="flex editable-cell-content" v-if="isEdit" v-click-outside="onClickOutside">
{{ getValues }}
<n-icon class="edit-icon" v-if="!column.editRow">
<FormOutlined />
</n-icon>
</div>
<div class="flex editable-cell-content" v-show="isEdit" v-click-outside="onClickOutside">
<div class="editable-cell-content-comp"> <div class="editable-cell-content-comp">
<CellComponent <CellComponent
v-bind="getComponentProps" v-bind="getComponentProps"
@@ -29,6 +23,12 @@
</n-icon> </n-icon>
</div> </div>
</div> </div>
<div v-else class="flex items-center editable-cell-content" @click="handleEdit">
{{ getValues }}
<n-icon class="ml-1 edit-icon" v-if="!column.editRow">
<FormOutlined />
</n-icon>
</div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">

View File

@@ -56,4 +56,5 @@ export const basicProps = {
}, },
canResize: propTypes.bool.def(true), canResize: propTypes.bool.def(true),
resizeHeightOffset: propTypes.number.def(0), resizeHeightOffset: propTypes.number.def(0),
striped: propTypes.bool.def(false),
}; };

View File

@@ -1,10 +1,10 @@
export interface PaginationProps { export interface PaginationProps {
page?: number; //受控模式下的当前页 page?: number; //受控模式下的当前页
itemCount?: number; //总条数 itemCount?: number; //总条数
pageCount?: number; //总页数 pageCount?: number; //总页数
pageSize?: number; //受控模式下的分页大小 pageSize?: number; //受控模式下的分页大小
pageSizes?: number[]; //每页条数, 可自定义 pageSizes?: number[]; //每页条数, 可自定义
showSizePicker?: boolean; //是否显示每页条数的选择器 showSizePicker?: boolean; //是否显示每页条数的选择器
showQuickJumper?: boolean; //是否显示快速跳转 showQuickJumper?: boolean; //是否显示快速跳转
prefix?: any; //分页前缀 prefix?: any; //分页前缀
} }

View File

@@ -31,6 +31,7 @@
v-if="imgList.length < maxNumber" v-if="imgList.length < maxNumber"
> >
<n-upload <n-upload
class="w-auto"
v-bind="$props" v-bind="$props"
:file-list-style="{ display: 'none' }" :file-list-style="{ display: 'none' }"
@before-upload="beforeUpload" @before-upload="beforeUpload"

View File

@@ -206,7 +206,7 @@
<n-divider title-placement="center">动画</n-divider> <n-divider title-placement="center">动画</n-divider>
<div class="drawer-setting-item"> <div class="drawer-setting-item">
<div class="drawer-setting-item-title"> 用动画 </div> <div class="drawer-setting-item-title"> 用动画 </div>
<div class="drawer-setting-item-action"> <div class="drawer-setting-item-action">
<n-switch v-model:value="settingStore.isPageAnimate" /> <n-switch v-model:value="settingStore.isPageAnimate" />
</div> </div>

View File

@@ -10,7 +10,7 @@
<h2 v-show="!collapsed" class="title">{{ websiteConfig.title }}</h2> <h2 v-show="!collapsed" class="title">{{ websiteConfig.title }}</h2>
</div> </div>
<AsideMenu <AsideMenu
v-model:collapsed="collapsed" :collapsed="collapsed"
v-model:location="getMenuLocation" v-model:location="getMenuLocation"
:inverted="getInverted" :inverted="getInverted"
mode="horizontal" mode="horizontal"
@@ -21,7 +21,7 @@
<!-- 菜单收起 --> <!-- 菜单收起 -->
<div <div
class="ml-1 layout-header-trigger layout-header-trigger-min" class="ml-1 layout-header-trigger layout-header-trigger-min"
@click="() => $emit('update:collapsed', !collapsed)" @click="handleMenuCollapsed"
> >
<n-icon size="18" v-if="collapsed"> <n-icon size="18" v-if="collapsed">
<MenuUnfoldOutlined /> <MenuUnfoldOutlined />
@@ -101,12 +101,14 @@
<div class="layout-header-trigger layout-header-trigger-min"> <div class="layout-header-trigger layout-header-trigger-min">
<n-dropdown trigger="hover" @select="avatarSelect" :options="avatarOptions"> <n-dropdown trigger="hover" @select="avatarSelect" :options="avatarOptions">
<div class="avatar"> <div class="avatar">
<n-avatar round> <n-avatar round :src="websiteConfig.logo">
{{ username }}
<template #icon> <template #icon>
<UserOutlined /> <UserOutlined />
</template> </template>
</n-avatar> </n-avatar>
<n-divider vertical />
<span>{{ username }}</span>
</div> </div>
</n-dropdown> </n-dropdown>
</div> </div>
@@ -151,19 +153,18 @@
type: Boolean, type: Boolean,
}, },
}, },
setup(props) { emits: ['update:collapsed'],
setup(props, { emit }) {
const userStore = useUserStore(); const userStore = useUserStore();
const useLockscreen = useScreenLockStore(); const useLockscreen = useScreenLockStore();
const message = useMessage(); const message = useMessage();
const dialog = useDialog(); const dialog = useDialog();
const { navMode, navTheme, headerSetting, menuSetting, crumbsSetting } = useProjectSetting(); const { navMode, navTheme, headerSetting, menuSetting, crumbsSetting } = useProjectSetting();
const { name } = userStore?.info || {};
const drawerSetting = ref(); const drawerSetting = ref();
const state = reactive({ const state = reactive({
username: name ?? '', username: userStore?.info?.username ?? '',
fullscreenIcon: 'FullscreenOutlined', fullscreenIcon: 'FullscreenOutlined',
navMode, navMode,
navTheme, navTheme,
@@ -323,6 +324,10 @@
openDrawer(); openDrawer();
} }
function handleMenuCollapsed() {
emit('update:collapsed', !props.collapsed);
}
return { return {
...toRefs(state), ...toRefs(state),
iconList, iconList,
@@ -341,6 +346,7 @@
getMenuLocation, getMenuLocation,
mixMenu, mixMenu,
websiteConfig, websiteConfig,
handleMenuCollapsed,
}; };
}, },
}); });

View File

@@ -1,12 +1,20 @@
<template> <template>
<RouterView> <RouterView>
<template #default="{ Component, route }"> <template #default="{ Component, route }">
<transition :name="getTransitionName" mode="out-in" appear> <template v-if="mode === 'production'">
<transition :name="getTransitionName" mode="out-in" appear>
<keep-alive v-if="keepAliveComponents.length" :include="keepAliveComponents">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
<component v-else :is="Component" :key="route.fullPath" />
</transition>
</template>
<template v-else>
<keep-alive v-if="keepAliveComponents.length" :include="keepAliveComponents"> <keep-alive v-if="keepAliveComponents.length" :include="keepAliveComponents">
<component :is="Component" :key="route.fullPath" /> <component :is="Component" :key="route.fullPath" />
</keep-alive> </keep-alive>
<component v-else :is="Component" :key="route.fullPath" /> <component v-else :is="Component" :key="route.fullPath" />
</transition> </template>
</template> </template>
</RouterView> </RouterView>
</template> </template>
@@ -39,9 +47,11 @@
return unref(isPageAnimate) ? unref(pageAnimateType) : ''; return unref(isPageAnimate) ? unref(pageAnimateType) : '';
}); });
const mode = import.meta.env.MODE;
return { return {
keepAliveComponents, keepAliveComponents,
getTransitionName, getTransitionName,
mode,
}; };
}, },
}); });

View File

@@ -1,4 +1,5 @@
import './styles/tailwind.css'; import './styles/tailwind.css';
import './styles/index.less';
import { createApp } from 'vue'; import { createApp } from 'vue';
import { setupNaiveDiscreteApi, setupNaive, setupDirectives } from '@/plugins'; import { setupNaiveDiscreteApi, setupNaive, setupDirectives } from '@/plugins';
import App from './App.vue'; import App from './App.vue';

View File

@@ -8,7 +8,7 @@ import { storage } from '@/utils/Storage';
export type UserInfoType = { export type UserInfoType = {
// TODO: add your own data // TODO: add your own data
name: string; username: string;
email: string; email: string;
}; };

View File

@@ -1 +1 @@
@import 'transition/index.less'; @import url('./transition/index.less');

View File

@@ -54,8 +54,8 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, ref, reactive, toRefs } from 'vue'; import { ref, reactive } from 'vue';
import { useMessage } from 'naive-ui'; import { useMessage } from 'naive-ui';
import { basicModal, useModal } from '@/components/Modal'; import { basicModal, useModal } from '@/components/Modal';
import { BasicForm, FormSchema, useForm } from '@/components/Form/index'; import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
@@ -205,90 +205,62 @@
}, },
]; ];
export default defineComponent({ const modalRef: any = ref(null);
components: { basicModal, BasicForm }, const message = useMessage();
setup() {
const modalRef: any = ref(null);
const message = useMessage();
const [modalRegister, { openModal, closeModal, setSubLoading }] = useModal({ const [modalRegister, { openModal, closeModal, setSubLoading }] = useModal({
title: '新增预约', title: '新增预约',
});
const [
lightModalRegister,
{
openModal: lightOpenModal,
closeModal: lightCloseModal,
setSubLoading: lightSetSubLoading,
},
] = useModal({
title: '确认对话框',
showIcon: true,
type: 'warning',
closable: false,
maskClosable: true,
});
const [register, { submit }] = useForm({
gridProps: { cols: 1 },
collapsedRows: 3,
labelWidth: 120,
layout: 'horizontal',
submitButtonText: '提交预约',
showActionButtonGroup: false,
schemas,
});
const state = reactive({
formValue: {
name: '小马哥',
},
});
async function okModal() {
const formRes = await submit();
if (formRes) {
closeModal();
console.log('formRes', formRes);
message.success('提交成功');
} else {
message.error('验证失败,请填写完整信息');
setSubLoading(false);
}
}
function lightOkModal() {
lightCloseModal();
lightSetSubLoading(false);
}
function showLightModal() {
lightOpenModal();
}
function showModal() {
openModal();
}
function handleReset(values: Recordable) {
console.log(values);
}
return {
...toRefs(state),
modalRef,
register,
modalRegister,
lightModalRegister,
handleReset,
showModal,
okModal,
lightOkModal,
showLightModal,
};
},
}); });
const [
lightModalRegister,
{ openModal: lightOpenModal, closeModal: lightCloseModal, setSubLoading: lightSetSubLoading },
] = useModal({
title: '确认对话框',
showIcon: true,
type: 'warning',
closable: false,
maskClosable: true,
});
const [register, { submit }] = useForm({
gridProps: { cols: 1 },
collapsedRows: 3,
labelWidth: 120,
layout: 'horizontal',
submitButtonText: '提交预约',
showActionButtonGroup: false,
schemas,
});
async function okModal() {
const formRes = await submit();
if (formRes) {
closeModal();
console.log('formRes', formRes);
message.success('提交成功');
} else {
message.error('验证失败,请填写完整信息');
setSubLoading(false);
}
}
function lightOkModal() {
lightCloseModal();
lightSetSubLoading(false);
}
function showLightModal() {
lightOpenModal();
}
function showModal() {
openModal();
}
function handleReset(values: Recordable) {
console.log(values);
}
</script> </script>
<style lang="less"> <style lang="less">

View File

@@ -51,7 +51,7 @@
actionRef.value.reload(); actionRef.value.reload();
} }
function editEnd({ record, index, key, value }) { function editEnd({ value }) {
console.log(value); console.log(value);
} }
</script> </script>

View File

@@ -106,7 +106,7 @@
actionRef.value.reload(); actionRef.value.reload();
} }
function editEnd({ record, index, key, value }) { function editEnd({ value }) {
console.log(value); console.log(value);
} }
</script> </script>

View File

@@ -7,7 +7,7 @@
<n-grid cols="2 s:1 m:3 l:3 xl:3 2xl:3" responsive="screen"> <n-grid cols="2 s:1 m:3 l:3 xl:3 2xl:3" responsive="screen">
<n-grid-item offset="0 s:0 m:1 l:1 xl:1 2xl:1"> <n-grid-item offset="0 s:0 m:1 l:1 xl:1 2xl:1">
<n-form <n-form
:label-width="80" :label-width="90"
:model="formValue" :model="formValue"
:rules="rules" :rules="rules"
label-placement="left" label-placement="left"

View File

@@ -1,111 +1,108 @@
<template> <template>
<div ref="chartRef" :style="{ height, width }"></div> <div ref="chartRef" :style="{ height, width }"></div>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, onMounted, ref, Ref } from 'vue'; import { onMounted, ref, Ref } from 'vue';
import { useECharts } from '@/hooks/web/useECharts'; import { useECharts } from '@/hooks/web/useECharts';
import { basicProps } from './props'; import { basicProps } from './props';
export default defineComponent({ defineProps({
props: basicProps, ...basicProps,
setup() { });
const chartRef = ref<HTMLDivElement | null>(null); const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
onMounted(() => { onMounted(() => {
setOptions({ setOptions({
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
axisPointer: { axisPointer: {
lineStyle: { lineStyle: {
width: 1, width: 1,
color: '#019680', color: '#019680',
}, },
},
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [
'6:00',
'7:00',
'8:00',
'9:00',
'10:00',
'11:00',
'12:00',
'13:00',
'14:00',
'15:00',
'16:00',
'17:00',
'18:00',
'19:00',
'20:00',
'21:00',
'22:00',
'23:00',
],
splitLine: {
show: true,
lineStyle: {
width: 1,
type: 'solid',
color: 'rgba(226,226,226,0.5)',
},
},
axisTick: {
show: false,
},
},
yAxis: [
{
type: 'value',
max: 80000,
splitNumber: 4,
axisTick: {
show: false,
},
splitArea: {
show: true,
areaStyle: {
color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],
}, },
}, },
xAxis: { },
type: 'category', ],
boundaryGap: false, grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true },
data: [ series: [
'6:00', {
'7:00', smooth: true,
'8:00', data: [
'9:00', 111, 222, 4000, 18000, 33333, 55555, 66666, 33333, 14000, 36000, 66666, 44444, 22222,
'10:00', 11111, 4000, 2000, 500, 333, 222, 111,
'11:00', ],
'12:00', type: 'line',
'13:00', areaStyle: {},
'14:00', itemStyle: {
'15:00', color: '#5ab1ef',
'16:00',
'17:00',
'18:00',
'19:00',
'20:00',
'21:00',
'22:00',
'23:00',
],
splitLine: {
show: true,
lineStyle: {
width: 1,
type: 'solid',
color: 'rgba(226,226,226,0.5)',
},
},
axisTick: {
show: false,
},
}, },
yAxis: [ },
{ {
type: 'value', smooth: true,
max: 80000, data: [
splitNumber: 4, 33, 66, 88, 333, 3333, 5000, 18000, 3000, 1200, 13000, 22000, 11000, 2221, 1201, 390,
axisTick: { 198, 60, 30, 22, 11,
show: false,
},
splitArea: {
show: true,
areaStyle: {
color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],
},
},
},
], ],
grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, type: 'line',
series: [ areaStyle: {},
{ itemStyle: {
smooth: true, color: '#019680',
data: [ },
111, 222, 4000, 18000, 33333, 55555, 66666, 33333, 14000, 36000, 66666, 44444, },
22222, 11111, 4000, 2000, 500, 333, 222, 111, ],
], });
type: 'line',
areaStyle: {},
itemStyle: {
color: '#5ab1ef',
},
},
{
smooth: true,
data: [
33, 66, 88, 333, 3333, 5000, 18000, 3000, 1200, 13000, 22000, 11000, 2221, 1201,
390, 198, 60, 30, 22, 11,
],
type: 'line',
areaStyle: {},
itemStyle: {
color: '#019680',
},
},
],
});
});
return { chartRef };
},
}); });
</script> </script>

View File

@@ -16,15 +16,7 @@
</NRow> </NRow>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent } from 'vue';
import FluxTrend from './FluxTrend.vue'; import FluxTrend from './FluxTrend.vue';
import VisitAmount from './VisitAmount.vue'; import VisitAmount from './VisitAmount.vue';
export default defineComponent({
components: { FluxTrend, VisitAmount },
setup() {
return {};
},
});
</script> </script>

View File

@@ -1,61 +1,59 @@
<template> <template>
<div ref="chartRef" :style="{ height, width }"></div> <div ref="chartRef" :style="{ height, width }"></div>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, onMounted, ref, Ref } from 'vue'; import { onMounted, ref, Ref } from 'vue';
import { useECharts } from '@/hooks/web/useECharts'; import { useECharts } from '@/hooks/web/useECharts';
import { basicProps } from './props'; import { basicProps } from './props';
export default defineComponent({ defineProps({
props: basicProps, ...basicProps,
setup() { });
const chartRef = ref<HTMLDivElement | null>(null);
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
onMounted(() => { const chartRef = ref<HTMLDivElement | null>(null);
setOptions({ const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
tooltip: {
trigger: 'axis', onMounted(() => {
axisPointer: { setOptions({
lineStyle: { tooltip: {
width: 1, trigger: 'axis',
color: '#019680', axisPointer: {
}, lineStyle: {
}, width: 1,
color: '#019680',
}, },
grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true }, },
xAxis: { },
type: 'category', grid: { left: '1%', right: '1%', top: '2 %', bottom: 0, containLabel: true },
data: [ xAxis: {
'1月', type: 'category',
'2月', data: [
'3月', '1月',
'4月', '2月',
'5月', '3月',
'6月', '4月',
'7月', '5月',
'8月', '6月',
'9月', '7月',
'10月', '8月',
'11月', '9月',
'12月', '10月',
], '11月',
}, '12月',
yAxis: { ],
type: 'value', },
max: 8000, yAxis: {
splitNumber: 4, type: 'value',
}, max: 8000,
series: [ splitNumber: 4,
{ },
data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200, 4800], series: [
type: 'bar', {
barMaxWidth: 80, data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200, 4800],
}, type: 'bar',
], barMaxWidth: 80,
}); },
}); ],
return { chartRef }; });
},
}); });
</script> </script>

View File

@@ -241,11 +241,38 @@
SettingOutlined, SettingOutlined,
} from '@vicons/antd'; } from '@vicons/antd';
interface InVisits {
dayVisits: number;
rise: number;
decline: number;
amount: number;
}
interface InSaleroom {
weekSaleroom: number;
amount: number;
degree: number;
}
interface InOrderLarge {
weekLarge: number;
rise: number;
decline: number;
amount: number;
}
interface InVolume {
weekLarge: number;
rise: number;
decline: number;
amount: number;
}
const loading = ref(true); const loading = ref(true);
const visits = ref<any>({}); const visits = ref({} as InVisits);
const saleroom = ref<any>({}); const saleroom = ref({} as InSaleroom);
const orderLarge = ref<any>({}); const orderLarge = ref({} as InOrderLarge);
const volume = ref(<any>{}); const volume = ref({} as InVolume);
// 图标列表 // 图标列表
const iconList = [ const iconList = [

View File

@@ -9,7 +9,7 @@
<n-grid cols="1 s:1 m:3 l:3 xl:3 2xl:3" responsive="screen"> <n-grid cols="1 s:1 m:3 l:3 xl:3 2xl:3" responsive="screen">
<n-grid-item offset="0 s:0 m:1 l:1 xl:1 2xl:1"> <n-grid-item offset="0 s:0 m:1 l:1 xl:1 2xl:1">
<n-form <n-form
:label-width="80" :label-width="90"
:model="formValue" :model="formValue"
:rules="rules" :rules="rules"
label-placement="left" label-placement="left"

View File

@@ -1,6 +1,6 @@
<template> <template>
<n-form <n-form
:label-width="90" :label-width="100"
:model="formValue" :model="formValue"
:rules="rules" :rules="rules"
label-placement="left" label-placement="left"

View File

@@ -13,7 +13,7 @@
<n-step title="完成转账" description="恭喜您,转账成功" /> <n-step title="完成转账" description="恭喜您,转账成功" />
</n-steps> </n-steps>
<step1 v-if="currentTab === 1" @next-step="nextStep" /> <step1 v-if="currentTab === 1" @next-step="nextStep" />
<step2 v-if="currentTab === 2" @next-step="nextStep" @prevStep="prevStep" /> <step2 v-if="currentTab === 2" @next-step="nextStep" @prev-step="prevStep" />
<step3 v-if="currentTab === 3" @prev-step="prevStep" @finish="finish" /> <step3 v-if="currentTab === 3" @prev-step="prevStep" @finish="finish" />
</n-space> </n-space>
</n-card> </n-card>
@@ -21,7 +21,7 @@
</template> </template>
<script setup> <script setup>
import { defineComponent, ref } from 'vue'; import { ref } from 'vue';
import step1 from './Step1.vue'; import step1 from './Step1.vue';
import step2 from './Step2.vue'; import step2 from './Step2.vue';
import step3 from './Step3.vue'; import step3 from './Step3.vue';

View File

@@ -14,6 +14,7 @@
:actionColumn="actionColumn" :actionColumn="actionColumn"
@update:checked-row-keys="onCheckedRow" @update:checked-row-keys="onCheckedRow"
:scroll-x="1090" :scroll-x="1090"
:striped="true"
> >
<template #tableTitle> <template #tableTitle>
<n-button type="primary" @click="addTable"> <n-button type="primary" @click="addTable">

View File

@@ -3,7 +3,7 @@
<div class="n-layout-page-header"> <div class="n-layout-page-header">
<n-card :bordered="false" title="基础详情"> 基础详情有时也用于显示只读信息 </n-card> <n-card :bordered="false" title="基础详情"> 基础详情有时也用于显示只读信息 </n-card>
</div> </div>
<n-card :bordered="false" class="proCard mt-4" size="small" :segmented="{ content: true }"> <n-card :bordered="false" class="mt-4 proCard" size="small" :segmented="{ content: true }">
<n-descriptions label-placement="left" class="py-2"> <n-descriptions label-placement="left" class="py-2">
<n-descriptions-item> <n-descriptions-item>
<template #label>收款人姓名</template> <template #label>收款人姓名</template>
@@ -21,14 +21,6 @@
</div> </div>
</template> </template>
<script> <script lang="ts" setup></script>
import { defineComponent } from 'vue';
export default defineComponent({
setup() {
return {};
},
});
</script>
<style lang="less" scoped></style> <style lang="less" scoped></style>

View File

@@ -53,8 +53,8 @@
</n-grid> </n-grid>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, reactive, ref, toRefs } from 'vue'; import { reactive, ref, toRefs } from 'vue';
import { useDialog, useMessage } from 'naive-ui'; import { useDialog, useMessage } from 'naive-ui';
const rules = { const rules = {
@@ -70,64 +70,49 @@
}, },
}; };
export default defineComponent({ const formRef: any = ref(null);
setup() { const message = useMessage();
const formRef: any = ref(null); const dialog = useDialog();
const message = useMessage();
const dialog = useDialog();
const state = reactive({ const formValue = ref({
formValue: { name: '',
name: '', mobile: '',
mobile: '', icpCode: '',
icpCode: '', address: '',
address: '', loginCode: 0,
loginCode: 0, closeText:
closeText: '网站维护中,暂时无法访问!本网站正在进行系统维护和技术升级,网站暂时无法访问,敬请谅解!',
'网站维护中,暂时无法访问!本网站正在进行系统维护和技术升级,网站暂时无法访问,敬请谅解!', systemOpen: true,
systemOpen: true, });
function systemOpenChange(value) {
if (!value) {
dialog.warning({
title: '提示',
content: '您确定要关闭系统访问吗?该操作立马生效,请慎重操作!',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
message.success('操作成功');
},
onNegativeClick: () => {
formValue.value.systemOpen = true;
}, },
}); });
}
}
function systemOpenChange(value) { function formSubmit() {
if (!value) { formRef.value.validate((errors) => {
dialog.warning({ if (!errors) {
title: '提示', message.success('验证成功');
content: '您确定要关闭系统访问吗?该操作立马生效,请慎重操作!', } else {
positiveText: '确定', message.error('验证失败,请填写完整信息');
negativeText: '取消',
onPositiveClick: () => {
message.success('操作成功');
},
onNegativeClick: () => {
state.formValue.systemOpen = true;
},
});
}
} }
});
}
function formSubmit() { function resetForm() {
formRef.value.validate((errors) => { formRef.value.restoreValidation();
if (!errors) { }
message.success('验证成功');
} else {
message.error('验证失败,请填写完整信息');
}
});
}
function resetForm() {
formRef.value.restoreValidation();
}
return {
formRef,
...toRefs(state),
rules,
formSubmit,
resetForm,
systemOpenChange,
};
},
});
</script> </script>

View File

@@ -36,8 +36,8 @@
</n-grid> </n-grid>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, reactive, ref, toRefs } from 'vue'; import { reactive, ref, toRefs } from 'vue';
import { useMessage } from 'naive-ui'; import { useMessage } from 'naive-ui';
const rules = { const rules = {
@@ -47,33 +47,21 @@
trigger: 'blur', trigger: 'blur',
}, },
}; };
export default defineComponent({
setup() {
const formRef: any = ref(null);
const message = useMessage();
const state = reactive({ const formRef: any = ref(null);
formValue: { const message = useMessage();
originator: '',
},
});
function formSubmit() { const formValue = ref({
formRef.value.validate((errors) => { originator: '',
if (!errors) {
message.success('验证成功');
} else {
message.error('验证失败,请填写完整信息');
}
});
}
return {
formRef,
...toRefs(state),
rules,
formSubmit,
};
},
}); });
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
message.success('验证成功');
} else {
message.error('验证失败,请填写完整信息');
}
});
}
</script> </script>

View File

@@ -88,8 +88,8 @@
</n-grid> </n-grid>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, reactive, ref, toRefs } from 'vue'; import { reactive, ref, toRefs } from 'vue';
import { useDialog, useMessage } from 'naive-ui'; import { useDialog, useMessage } from 'naive-ui';
const rules = { const rules = {
@@ -152,67 +152,49 @@
}, },
]; ];
export default defineComponent({ const formRef: any = ref(null);
setup() { const message = useMessage();
const formRef: any = ref(null); const dialog = useDialog();
const message = useMessage();
const dialog = useDialog();
const state = reactive({ const formValue = ref({
formValue: { bigWidth: '',
bigWidth: '', bigHeight: '',
bigHeight: '', smallWidth: '',
smallWidth: '', smallHeight: '',
smallHeight: '', watermarkClarity: null,
watermarkClarity: null, pricePrecise: 1,
pricePrecise: 1, isMarketPrice: true,
isMarketPrice: true, pricePreciseNum: null,
pricePreciseNum: null, });
function systemOpenChange(value) {
if (!value) {
dialog.warning({
title: '提示',
content: '您确定要关闭系统访问吗?该操作立马生效,请慎重操作!',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
message.success('操作成功');
},
onNegativeClick: () => {
formValue.value.systemOpen = true;
}, },
}); });
}
}
function systemOpenChange(value) { function formSubmit() {
if (!value) { formRef.value.validate((errors) => {
dialog.warning({ if (!errors) {
title: '提示', message.success('验证成功');
content: '您确定要关闭系统访问吗?该操作立马生效,请慎重操作!', } else {
positiveText: '确定', message.error('验证失败,请填写完整信息');
negativeText: '取消',
onPositiveClick: () => {
message.success('操作成功');
},
onNegativeClick: () => {
state.formValue.systemOpen = true;
},
});
}
} }
});
}
function formSubmit() { function resetForm() {
formRef.value.validate((errors) => { formRef.value.restoreValidation();
if (!errors) { }
message.success('验证成功');
} else {
message.error('验证失败,请填写完整信息');
}
});
}
function resetForm() {
formRef.value.restoreValidation();
}
return {
formRef,
...toRefs(state),
pricePreciseList,
watermarkPlaceList,
pricePreciseNumList,
rules,
formSubmit,
resetForm,
systemOpenChange,
};
},
});
</script> </script>

View File

@@ -25,8 +25,8 @@
</n-grid> </n-grid>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, reactive, toRefs } from 'vue'; import { reactive, toRefs } from 'vue';
import BasicSetting from './BasicSetting.vue'; import BasicSetting from './BasicSetting.vue';
import RevealSetting from './RevealSetting.vue'; import RevealSetting from './RevealSetting.vue';
import EmailSetting from './EmailSetting.vue'; import EmailSetting from './EmailSetting.vue';
@@ -48,26 +48,16 @@
key: 3, key: 3,
}, },
]; ];
export default defineComponent({
components: { BasicSetting, RevealSetting, EmailSetting },
setup() {
const state = reactive({
type: 1,
typeTitle: '基本设置',
});
function switchType(e) { const state = reactive({
state.type = e.key; type: 1,
state.typeTitle = e.name; typeTitle: '基本设置',
}
return {
...toRefs(state),
switchType,
typeTabList,
};
},
}); });
function switchType(e) {
state.type = e.key;
state.typeTitle = e.name;
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.thing-cell { .thing-cell {

View File

@@ -1,5 +1,5 @@
<template> <template>
<n-drawer v-model:show="isDrawer" :width="width" :placement="placement"> <n-drawer v-model:show="state.isDrawer" :width="width" :placement="state.placement">
<n-drawer-content :title="title" closable> <n-drawer-content :title="title" closable>
<n-form <n-form
:model="formParams" :model="formParams"
@@ -38,7 +38,7 @@
<template #footer> <template #footer>
<n-space> <n-space>
<n-button type="primary" :loading="subLoading" @click="formSubmit">提交</n-button> <n-button type="primary" :loading="state.subLoading" @click="formSubmit">提交</n-button>
<n-button @click="handleReset">重置</n-button> <n-button @click="handleReset">重置</n-button>
</n-space> </n-space>
</template> </template>
@@ -46,8 +46,8 @@
</n-drawer> </n-drawer>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, reactive, ref, toRefs } from 'vue'; import { reactive, ref, toRefs } from 'vue';
import { useMessage } from 'naive-ui'; import { useMessage } from 'naive-ui';
const rules = { const rules = {
@@ -62,75 +62,58 @@
trigger: 'blur', trigger: 'blur',
}, },
}; };
export default defineComponent({
name: 'CreateDrawer', defineProps({
components: {}, title: {
props: { type: String,
title: { default: '添加顶级菜单',
type: String,
default: '添加顶级菜单',
},
width: {
type: Number,
default: 450,
},
}, },
setup() { width: {
const message = useMessage(); type: Number,
const formRef: any = ref(null); default: 450,
const defaultValueRef = () => ({
label: '',
type: 1,
subtitle: '',
openType: 1,
auth: '',
path: '',
hidden: false,
});
const state = reactive({
isDrawer: false,
subLoading: false,
formParams: defaultValueRef(),
placement: 'right' as const,
alertText:
'该功能主要实时预览各种布局效果,更多完整配置在 projectSetting.ts 中设置,建议在生产环境关闭该布局预览功能。',
});
function openDrawer() {
state.isDrawer = true;
}
function closeDrawer() {
state.isDrawer = false;
}
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
message.success('添加成功');
handleReset();
closeDrawer();
} else {
message.error('请填写完整信息');
}
});
}
function handleReset() {
formRef.value.restoreValidation();
state.formParams = Object.assign(state.formParams, defaultValueRef());
}
return {
...toRefs(state),
formRef,
rules,
formSubmit,
handleReset,
openDrawer,
closeDrawer,
};
}, },
}); });
const message = useMessage();
const formRef: any = ref(null);
const defaultValueRef = () => ({
label: '',
type: 1,
subtitle: '',
openType: 1,
auth: '',
path: '',
hidden: false,
});
const formParams = ref(defaultValueRef());
const state = reactive({
isDrawer: false,
subLoading: false,
placement: 'right' as const,
});
function openDrawer() {
state.isDrawer = true;
}
function closeDrawer() {
state.isDrawer = false;
}
function formSubmit() {
formRef.value.validate((errors) => {
if (!errors) {
message.success('添加成功');
handleReset();
closeDrawer();
} else {
message.error('请填写完整信息');
}
});
}
function handleReset() {
formRef.value.restoreValidation();
formParams.value = Object.assign(formParams.value, defaultValueRef());
}
</script> </script>