发布 vite 版本

This commit is contained in:
icssoa 2021-03-30 18:23:08 +08:00
parent b603cc571f
commit 0d42e17999
144 changed files with 4625 additions and 9485 deletions

View File

@ -1,3 +0,0 @@
> 1%
last 2 versions
not dead

View File

@ -1,21 +0,0 @@
module.exports = {
root: true,
env: {
node: true
},
extends: [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended",
"@vue/prettier",
"@vue/prettier/@typescript-eslint"
],
parserOptions: {
ecmaVersion: 2020
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
"@typescript-eslint/no-explicit-any": ["off"]
}
};

26
.gitignore vendored
View File

@ -1,23 +1,5 @@
.DS_Store
node_modules node_modules
/dist .DS_Store
dist
dist-ssr
# local env files *.local
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -1,9 +0,0 @@
{
"tabWidth": 4,
"useTabs": true,
"semi": true,
"jsxBracketSameLine": true,
"singleQuote": false,
"printWidth": 100,
"trailingComma": "none"
}

View File

@ -1,67 +1,27 @@
<p align="center"> # Vue 3 + Typescript + Vite
<a href="https://show.cool-admin.com/" target="blank"><img src="https://admin.cool-js.com/logo.png" width="200" alt="cool-admin Logo" /></a>
</p>
<p align="center">cool-admin 一个很酷的后台权限管理系统,开源免费,模块化、插件化、极速开发 CRUD方便快速构建迭代后台管理系统 到论坛 进一步了解</p> This template should help get you started developing with Vue 3 and Typescript in Vite.
<p align="center"> ## Recommended IDE Setup
<a href="https://github.com/cool-team-official/cool-admin-vue/blob/master/LICENSE" target="_blank"><img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="GitHub license" />
<a href=""><img src="https://img.shields.io/github/package-json/v/cool-team-official/cool-admin-vue?style=flat-square" alt="GitHub tag"></a>
<img src="https://img.shields.io/github/last-commit/cool-team-official/cool-admin-vue?style=flat-square" alt="GitHub tag"></a>
</p>
## 地址 [VSCode](https://code.visualstudio.com/) + [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur). Make sure to enable `vetur.experimental.templateInterpolationService` in settings!
- [⚡️ vue2.x + element-ui免费商用支持 PC、平板、手机](https://github.com/cool-team-official/cool-admin-vue) ### If Using `<script setup>`
- [⚡️ vue3.x + element-plus + ts + webpack免费商用支持 PC、平板、手机](https://github.com/cool-team-official/cool-admin-vue/tree/vue3-ts-webpack) [`<script setup>`](https://github.com/vuejs/rfcs/pull/227) is a feature that is currently in RFC stage. To get proper IDE support for the syntax, use [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) instead of Vetur (and disable Vetur).
- [📌 vue3.x + element-plus + ts + vite测试中]() ## Type Support For `.vue` Imports in TS
- [🌐 码云仓库地址](https://gitee.com/cool-team-official/cool-admin-vue) Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can use the following:
## 演示 ### If Using Volar
[https://show.cool-admin.com](https://show.cool-admin.com) Run `Volar: Switch TS Plugin on/off` from VSCode command palette.
账户admin密码123456 ### If Using Vetur
<img src="https://cool-show.oss-cn-shanghai.aliyuncs.com/admin/home-mini.png" alt="Admin Home" ></a> 1. Install and add `@vuedx/typescript-plugin-vue` to the [plugins section](https://www.typescriptlang.org/tsconfig#plugins) in `tsconfig.json`
2. Delete `src/shims-vue.d.ts` as it is no longer needed to provide module info to Typescript
## 项目后端 3. Open `src/main.ts` in VSCode
4. Open the VSCode command palette
[https://github.com/cool-team-official/cool-admin-midway](https://github.com/cool-team-official/cool-admin-midway) 5. Search and run "Select TypeScript version" -> "Use workspace version"
## 微信群
<img width="260" src="https://cool-show.oss-cn-shanghai.aliyuncs.com/admin/wechat.jpeg" alt="Admin Wechat"></a>
## 微信公众号
<img width="260" src="https://cool-show.oss-cn-shanghai.aliyuncs.com/admin/mp.jpg" alt="Admin Wechat"></a>
## 在线社区
[https://bbs.cool-js.com/](https://bbs.cool-js.com/)
## 安装项目依赖
推荐使用 `yarn`
```shell
yarn
```
解决 `node-sass` 网络慢的方法:
```shell
yarn config set sass-binary-site http://npm.taobao.org/mirrors/node-sass
```
## 运行应用程序
安装过程完成后,运行以下命令启动服务。您可以在浏览器中预览网站 [http://localhost:9000](http://localhost:9000)
```shell
yarn serve
```

View File

@ -1,3 +0,0 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"]
};

90
index.html Normal file
View File

@ -0,0 +1,90 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="referer" content="never" />
<meta name="renderer" content="webkit" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0"
/>
<link rel="icon" href="favicon.ico" />
<style>
html,
body,
#app {
height: 100%;
margin: 0;
padding: 0;
}
.preload {
display: flex;
flex-direction: column;
height: 100%;
letter-spacing: 1px;
background-color: #2f3447;
}
.preload .container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
user-select: none;
flex-grow: 1;
}
.preload .name {
font-size: 30px;
color: #fff;
letter-spacing: 5px;
font-weight: bold;
}
.preload .title {
color: #fff;
font-size: 14px;
margin-bottom: 10px;
}
.preload .sub-title {
color: #ababab;
font-size: 12px;
}
.preload .footer {
text-align: center;
padding: 10px 0 20px 0;
}
.preload .footer a {
font-size: 12px;
color: #ababab;
text-decoration: none;
}
</style>
</head>
<body>
<div id="app">
<div class="preload">
<div class="container">
<p class="name">COOL-ADMIN</p>
<p class="title">正在加载资源...</p>
<p class="sub-title">
初次加载资源可能需要较多时间 请耐心等待
</p>
</div>
<div class="footer">
<a href="https://cool-js.com/" target="_blank">
https://cool-js.com
</a>
</div>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@ -1,11 +1,10 @@
{ {
"name": "front-next-vue3", "name": "front-next-vue3-vite",
"version": "0.1.2", "version": "0.0.0",
"private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "dev": "vite",
"build": "vue-cli-service build", "build": "vue-tsc --noEmit && vite build",
"lint": "vue-cli-service lint" "serve": "vite preview"
}, },
"dependencies": { "dependencies": {
"array.prototype.flat": "^1.2.4", "array.prototype.flat": "^1.2.4",
@ -25,6 +24,7 @@
"quill": "^1.3.7", "quill": "^1.3.7",
"socket.io-client": "^4.0.0", "socket.io-client": "^4.0.0",
"store": "^2.0.12", "store": "^2.0.12",
"uuid": "^8.3.2",
"vue": "^3.0.9", "vue": "^3.0.9",
"vue-echarts": "^6.0.0-rc.3", "vue-echarts": "^6.0.0-rc.3",
"vue-router": "^4.0.5", "vue-router": "^4.0.5",
@ -32,29 +32,15 @@
"vuex": "^4.0.0-0" "vuex": "^4.0.0-0"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash": "^4.14.168", "@vitejs/plugin-vue": "^1.1.5",
"@typescript-eslint/eslint-plugin": "^2.33.0", "@vitejs/plugin-vue-jsx": "^1.1.2",
"@typescript-eslint/parser": "^2.33.0", "@vue/compiler-sfc": "^3.0.5",
"@vue/cli-plugin-babel": "~4.5.0", "sass": "^1.32.8",
"@vue/cli-plugin-eslint": "~4.5.0", "sass-loader": "^11.0.1",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/composition-api": "^1.0.0-rc.5",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^7.0.0-0",
"hard-source-webpack-plugin": "^0.13.1",
"lint-staged": "^9.5.0",
"node-sass": "^4.12.0",
"prettier": "^1.19.1",
"sass-loader": "^8.0.2",
"svg-sprite-loader": "^6.0.2", "svg-sprite-loader": "^6.0.2",
"typescript": "~3.9.3" "typescript": "^4.1.3",
}, "vite": "^2.1.3",
"typings": "types/index.d.ts" "vite-svg-loader": "^1.5.1",
"vue-tsc": "^0.0.8"
}
} }

View File

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@ -1426,6 +1426,7 @@
margin: 0 3px; margin: 0 3px;
} }
.el-dropdown-menu { .el-dropdown-menu {
position: absolute;
top: 0; top: 0;
left: 0; left: 0;
padding: 10px 0; padding: 10px 0;

View File

@ -1426,6 +1426,7 @@
margin: 0 3px; margin: 0 3px;
} }
.el-dropdown-menu { .el-dropdown-menu {
position: absolute;
top: 0; top: 0;
left: 0; left: 0;
padding: 10px 0; padding: 10px 0;

View File

@ -1426,6 +1426,7 @@
margin: 0 3px; margin: 0 3px;
} }
.el-dropdown-menu { .el-dropdown-menu {
position: absolute;
top: 0; top: 0;
left: 0; left: 0;
padding: 10px 0; padding: 10px 0;

View File

@ -1426,6 +1426,7 @@
margin: 0 3px; margin: 0 3px;
} }
.el-dropdown-menu { .el-dropdown-menu {
position: absolute;
top: 0; top: 0;
left: 0; left: 0;
padding: 10px 0; padding: 10px 0;

View File

@ -4,6 +4,6 @@ $--color-danger: $color-danger;
$--color-warning: $color-warning; $--color-warning: $color-warning;
$--color-info: $color-info; $--color-info: $color-info;
$--font-path: "~element-plus/lib/theme-chalk/fonts"; $--font-path: "element-plus/lib/theme-chalk/fonts";
@import "~element-plus/packages/theme-chalk/src/index"; @import "element-plus/packages/theme-chalk/src/index";

View File

@ -1,8 +1,8 @@
* { * {
padding: 0; padding: 0;
margin: 0; margin: 0;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
"微软雅黑", Arial, sans-serif; "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
} }
*::-webkit-scrollbar { *::-webkit-scrollbar {

View File

@ -1,18 +1,19 @@
import store from "store"; import store from "store";
import { getUrlParam } from "@/core/utils"; import { getUrlParam } from "/@/core/utils";
import { MenuItem } from "@/cool/modules/base/types"; import { MenuItem } from "/@/cool/modules/base/types";
// 路由模式 // 路由模式
const routerMode = "history"; const routerMode = "history";
// 开发模式 // 开发模式
const isDev: boolean = process.env.NODE_ENV == "development"; const isDev: boolean = true;
// Host // Host
const host = "https://show.cool-admin.com"; const host = "https://show.cool-admin.com";
// 请求地址 // 请求地址
const baseUrl: string = (function() { const baseUrl: string = (function () {
let proxy = getUrlParam("proxy"); let proxy = getUrlParam("proxy");
if (proxy) { if (proxy) {
@ -38,13 +39,13 @@ const app: any = store.get("__app__") || {
showAMenu: false, // 是否显示一级菜单栏 showAMenu: false, // 是否显示一级菜单栏
showRouteNav: true, // 是否显示路由导航栏 showRouteNav: true, // 是否显示路由导航栏
showProcess: true, // 是否显示页面进程栏 showProcess: true, // 是否显示页面进程栏
customMenu: false // 自定义菜单 customMenu: false, // 自定义菜单
}, },
theme: { theme: {
color: "", // 主题色 color: "", // 主题色
url: "" // 主题样式地址 url: "", // 主题样式地址
} },
}; };
// 自定义菜单列表 // 自定义菜单列表

View File

@ -9,8 +9,8 @@ export default {
name: "upload", name: "upload",
options: { options: {
icon: "el-icon-picture", icon: "el-icon-picture",
text: "选择图片" text: "选择图片",
} },
}, },
{ {
name: "crud", name: "crud",
@ -20,11 +20,11 @@ export default {
dict: { dict: {
sort: { sort: {
prop: "order", prop: "order",
order: "sort" order: "sort",
} },
} },
} },
} },
}, },
// 客服聊天 // 客服聊天
"chat", "chat",
@ -35,6 +35,6 @@ export default {
// 示例页 // 示例页
"demo", "demo",
// 主题切换 // 主题切换
"theme" "theme",
] ],
}; };

View File

@ -1,4 +1,4 @@
import store from "@/store"; import store from "/@/store";
const lock: any = { const lock: any = {
menuCollapse: null, menuCollapse: null,

View File

@ -1,6 +1,6 @@
import { iconfontUrl, app } from "@/config/env"; import { iconfontUrl, app } from "/@/config/env";
import { basename } from "/@/core/utils";
import { createLink } from "../utils"; import { createLink } from "../utils";
import { colorPrimary } from "@/assets/css/common.scss";
// 主题初始化 // 主题初始化
@ -13,7 +13,7 @@ if (app.theme) {
document document
.getElementsByTagName("body")[0] .getElementsByTagName("body")[0]
.style.setProperty("--color-primary", color || colorPrimary); .style.setProperty("--color-primary", color);
} }
// 字体图标库加载 // 字体图标库加载
@ -24,17 +24,16 @@ if (iconfontUrl) {
// svg 图标加载 // svg 图标加载
const req = require.context("@/icons/svg/", false, /\.svg$/); const svgFiles = import.meta.globEager("/src/icons/svg/**/*.svg");
req.keys().map(req);
function iconList() { function iconList() {
return req let list: string[] = [];
.keys()
.map(req) for (const i in svgFiles) {
.map((e: any) => e.default.id) list.push(basename(i).replace(".svg", ""));
.filter(e => e.includes("icon")) }
.sort();
return list;
} }
export { iconList }; export { iconList };

View File

@ -12,7 +12,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from "vue"; import { computed, defineComponent } from "vue";
import { isNumber } from "@/core/utils"; import { isNumber } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
name: "cl-avatar", name: "cl-avatar",
@ -21,12 +21,12 @@ export default defineComponent({
src: String, src: String,
size: { size: {
type: String, type: String,
default: "large" default: "large",
}, },
shape: { shape: {
type: String, type: String,
default: "circle" default: "circle",
} },
}, },
setup(props) { setup(props) {
@ -35,14 +35,14 @@ export default defineComponent({
const style = computed(() => { const style = computed(() => {
return { return {
height: size, height: size,
width: size width: size,
}; };
}); });
return { return {
style style,
}; };
} },
}); });
</script> </script>
@ -83,7 +83,7 @@ export default defineComponent({
height: 100%; height: 100%;
width: 100%; width: 100%;
:deep(.image-slot) { .image-slot {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;

View File

@ -1,6 +1,11 @@
<template> <template>
<div class="cl-codemirror" ref="editorRef"> <div class="cl-codemirror" ref="editorRef">
<textarea class="cl-code" id="editor" :height="height" :width="width"></textarea> <textarea
class="cl-code"
id="editor"
:height="height"
:width="width"
></textarea>
</div> </div>
</template> </template>
@ -22,7 +27,7 @@ export default defineComponent({
modelValue: null, modelValue: null,
height: String, height: String,
width: String, width: String,
options: Object options: Object,
}, },
emits: ["update:modelValue", "load"], emits: ["update:modelValue", "load"],
@ -56,18 +61,21 @@ export default defineComponent({
} }
); );
onMounted(function() { onMounted(function () {
nextTick(() => { nextTick(() => {
// //
editor = CodeMirror.fromTextArea(editorRef.value.querySelector("#editor"), { editor = CodeMirror.fromTextArea(
mode: "javascript", editorRef.value.querySelector("#editor"),
theme: "ambiance", {
styleActiveLine: true, mode: "javascript",
lineNumbers: true, theme: "ambiance",
lineWrapping: true, styleActiveLine: true,
indentUnit: 4, lineNumbers: true,
...props.options lineWrapping: true,
}); indentUnit: 4,
...props.options,
}
);
// //
editor.on("change", (e: any) => { editor.on("change", (e: any) => {
@ -97,9 +105,9 @@ export default defineComponent({
}); });
return { return {
editorRef editorRef,
}; };
} },
}); });
</script> </script>

View File

@ -35,7 +35,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { deepTree } from "@/core/utils"; import { deepTree } from "/@/core/utils";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { defineComponent, inject, nextTick, onMounted, ref, watch } from "vue"; import { defineComponent, inject, nextTick, onMounted, ref, watch } from "vue";

View File

@ -1,5 +1,5 @@
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
import { deepTree } from "@/core/utils"; import { deepTree } from "/@/core/utils";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import { defineComponent, h, inject, ref } from "vue"; import { defineComponent, h, inject, ref } from "vue";

View File

@ -12,13 +12,20 @@
<li v-if="drag && !isMini"> <li v-if="drag && !isMini">
<el-tooltip content="拖动排序"> <el-tooltip content="拖动排序">
<i class="el-icon-s-operation" @click="isDrag = true"></i> <i
class="el-icon-s-operation"
@click="isDrag = true"
></i>
</el-tooltip> </el-tooltip>
</li> </li>
<li class="no" v-show="isDrag"> <li class="no" v-show="isDrag">
<el-button type="text" size="mini" @click="treeOrder(true)">保存</el-button> <el-button type="text" size="mini" @click="treeOrder(true)"
<el-button type="text" size="mini" @click="treeOrder(false)">取消</el-button> >保存</el-button
>
<el-button type="text" size="mini" @click="treeOrder(false)"
>取消</el-button
>
</li> </li>
</ul> </ul>
</div> </div>
@ -30,7 +37,7 @@
default-expand-all default-expand-all
:data="list" :data="list"
:props="{ :props="{
label: 'name' label: 'name',
}" }"
:draggable="isDrag" :draggable="isDrag"
:allow-drag="allowDrag" :allow-drag="allowDrag"
@ -41,9 +48,11 @@
> >
<template #default="{ node, data }"> <template #default="{ node, data }">
<div class="cl-dept-tree__node"> <div class="cl-dept-tree__node">
<span class="cl-dept-tree__node-label" @click="rowClick(data)">{{ <span
node.label class="cl-dept-tree__node-label"
}}</span> @click="rowClick(data)"
>{{ node.label }}</span
>
<span <span
class="cl-dept-tree__node-icon" class="cl-dept-tree__node-icon"
v-if="isMini" v-if="isMini"
@ -63,9 +72,9 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, inject, onMounted, ref } from "vue"; import { defineComponent, inject, onMounted, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import { ContextMenu } from "@/crud"; import { ContextMenu } from "/@/crud";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
import { deepTree, isArray, revDeepTree, isPc } from "@/core/utils"; import { deepTree, isArray, revDeepTree, isPc } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
name: "cl-dept-tree", name: "cl-dept-tree",
@ -73,12 +82,12 @@ export default defineComponent({
props: { props: {
drag: { drag: {
type: Boolean, type: Boolean,
default: true default: true,
}, },
level: { level: {
type: Number, type: Number,
default: 99 default: 99,
} },
}, },
setup(props, { emit }) { setup(props, { emit }) {
@ -125,7 +134,9 @@ export default defineComponent({
// ids // ids
function rowClick(e: any) { function rowClick(e: any) {
ContextMenu.close(); ContextMenu.close();
const ids = e.children ? revDeepTree(e.children).map(e => e.id) : []; const ids = e.children
? revDeepTree(e.children).map((e) => e.id)
: [];
ids.unshift(e.id); ids.unshift(e.id);
emit("row-click", { item: e, ids }); emit("row-click", { item: e, ids });
} }
@ -138,7 +149,7 @@ export default defineComponent({
title: "编辑部门", title: "编辑部门",
width: "550px", width: "550px",
props: { props: {
labelWidth: "100px" labelWidth: "100px",
}, },
items: [ items: [
{ {
@ -148,13 +159,13 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
placeholder: "请填写部门名称" placeholder: "请填写部门名称",
} },
}, },
rules: { rules: {
required: true, required: true,
message: "部门名称不能为空" message: "部门名称不能为空",
} },
}, },
{ {
label: "上级部门", label: "上级部门",
@ -163,9 +174,9 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
disabled: true disabled: true,
} },
} },
}, },
{ {
label: "排序", label: "排序",
@ -176,10 +187,10 @@ export default defineComponent({
props: { props: {
"controls-position": "right", "controls-position": "right",
min: 0, min: 0,
max: 100 max: 100,
} },
} },
} },
], ],
on: { on: {
submit: (data: any, { done, close }: any) => { submit: (data: any, { done, close }: any) => {
@ -187,7 +198,7 @@ export default defineComponent({
id: e.id, id: e.id,
parentId: e.parentId, parentId: e.parentId,
name: data.name, name: data.name,
orderNum: data.orderNum orderNum: data.orderNum,
}) })
.then(() => { .then(() => {
ElMessage.success(`新增部门${data.name}成功`); ElMessage.success(`新增部门${data.name}成功`);
@ -198,8 +209,8 @@ export default defineComponent({
ElMessage.error(err); ElMessage.error(err);
done(); done();
}); });
} },
} },
}); });
} }
@ -209,7 +220,7 @@ export default defineComponent({
$service.system.dept $service.system.dept
.delete({ .delete({
ids: [e.id], ids: [e.id],
deleteUser: f deleteUser: f,
}) })
.then(() => { .then(() => {
if (f) { if (f) {
@ -226,12 +237,16 @@ export default defineComponent({
}); });
}; };
ElMessageBox.confirm(`该操作会删除 “${e.name}” 部门的所有用户,是否确认?`, "提示", { ElMessageBox.confirm(
type: "warning", `该操作会删除 “${e.name}” 部门的所有用户,是否确认?`,
confirmButtonText: "直接删除", "提示",
cancelButtonText: "保留用户", {
distinguishCancelAndClose: true type: "warning",
}) confirmButtonText: "直接删除",
cancelButtonText: "保留用户",
distinguishCancelAndClose: true,
}
)
.then(() => { .then(() => {
del(true); del(true);
}) })
@ -246,13 +261,13 @@ export default defineComponent({
function treeOrder(f: boolean) { function treeOrder(f: boolean) {
if (f) { if (f) {
ElMessageBox.confirm("部门架构已发生改变,是否保存?", "提示", { ElMessageBox.confirm("部门架构已发生改变,是否保存?", "提示", {
type: "warning" type: "warning",
}) })
.then(() => { .then(() => {
const ids: any[] = []; const ids: any[] = [];
const deep = (list: any[], pid: any) => { const deep = (list: any[], pid: any) => {
list.forEach(e => { list.forEach((e) => {
e.parentId = pid; e.parentId = pid;
ids.push(e); ids.push(e);
@ -270,7 +285,7 @@ export default defineComponent({
return { return {
id: e.id, id: e.id,
parentId: e.parentId, parentId: e.parentId,
orderNum: i orderNum: i,
}; };
}) })
) )
@ -307,10 +322,10 @@ export default defineComponent({
rowEdit({ rowEdit({
name: "", name: "",
parentName: d.name, parentName: d.name,
parentId: d.id parentId: d.id,
}); });
done(); done();
} },
}, },
{ {
label: "编辑", label: "编辑",
@ -318,7 +333,7 @@ export default defineComponent({
callback: (_: any, done: Function) => { callback: (_: any, done: Function) => {
rowEdit(d); rowEdit(d);
done(); done();
} },
}, },
{ {
label: "删除", label: "删除",
@ -327,7 +342,7 @@ export default defineComponent({
callback: (_: any, done: Function) => { callback: (_: any, done: Function) => {
rowDel(d); rowDel(d);
done(); done();
} },
}, },
{ {
label: "新增成员", label: "新增成员",
@ -335,13 +350,13 @@ export default defineComponent({
callback: (_: any, done: Function) => { callback: (_: any, done: Function) => {
emit("user-add", d); emit("user-add", d);
done(); done();
} },
} },
] ],
}); });
} }
onMounted(function() { onMounted(function () {
refresh(); refresh();
}); });
@ -359,13 +374,13 @@ export default defineComponent({
rowClick, rowClick,
rowEdit, rowEdit,
rowDel, rowDel,
treeOrder treeOrder,
}; };
} },
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.cl-dept-tree { .cl-dept-tree {
height: 100%; height: 100%;
width: 100%; width: 100%;
@ -414,7 +429,7 @@ export default defineComponent({
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
:deep(.el-tree-node__content) { .el-tree-node__content {
height: 36px; height: 36px;
margin: 0 5px; margin: 0 5px;
} }

View File

@ -16,8 +16,8 @@
import { computed, defineComponent, onMounted, ref, watch } from "vue"; import { computed, defineComponent, onMounted, ref, watch } from "vue";
import Quill from "quill"; import Quill from "quill";
import "quill/dist/quill.snow.css"; import "quill/dist/quill.snow.css";
import { isNumber } from "@/core/utils"; import { isNumber } from "/@/core/utils";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
export default defineComponent({ export default defineComponent({
name: "cl-editor-quill", name: "cl-editor-quill",
@ -26,7 +26,7 @@ export default defineComponent({
options: Object, options: Object,
modelValue: null, modelValue: null,
height: [String, Number], height: [String, Number],
width: [String, Number] width: [String, Number],
}, },
emits: ["update:modelValue", "load"], emits: ["update:modelValue", "load"],
@ -60,7 +60,12 @@ export default defineComponent({
files.forEach((file, i) => { files.forEach((file, i) => {
const [type] = file.type.split("/"); const [type] = file.type.split("/");
quill.insertEmbed(cursorIndex.value + i, type, file.url, Quill.sources.USER); quill.insertEmbed(
cursorIndex.value + i,
type,
file.url,
Quill.sources.USER
);
}); });
// //
@ -75,12 +80,16 @@ export default defineComponent({
// //
const style = computed<any>(() => { const style = computed<any>(() => {
const height = isNumber(props.height) ? props.height + "px" : props.height; const height = isNumber(props.height)
const width = isNumber(props.width) ? props.width + "px" : props.width; ? props.height + "px"
: props.height;
const width = isNumber(props.width)
? props.width + "px"
: props.width;
return { return {
height, height,
width width,
}; };
}); });
@ -98,7 +107,7 @@ export default defineComponent({
} }
); );
onMounted(function() { onMounted(function () {
// //
quill = new Quill(refs.value.editor, { quill = new Quill(refs.value.editor, {
theme: "snow", theme: "snow",
@ -118,10 +127,10 @@ export default defineComponent({
[{ font: [] }], [{ font: [] }],
[{ align: [] }], [{ align: [] }],
["clean"], ["clean"],
["link", "image"] ["link", "image"],
] ],
}, },
...props.options ...props.options,
}); });
// //
@ -148,9 +157,9 @@ export default defineComponent({
style, style,
setRefs, setRefs,
setContent, setContent,
onUploadSpaceConfirm onUploadSpaceConfirm,
}; };
} },
}); });
</script> </script>
@ -250,8 +259,12 @@ export default defineComponent({
content: "衬线字体"; content: "衬线字体";
} }
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before, .ql-snow
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before { .ql-picker.ql-font
.ql-picker-label[data-value="monospace"]::before,
.ql-snow
.ql-picker.ql-font
.ql-picker-item[data-value="monospace"]::before {
content: "等宽字体"; content: "等宽字体";
} }
} }

View File

@ -6,39 +6,43 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, ref } from "vue"; import { computed, defineComponent, ref } from "vue";
import { isNumber } from "@/core/utils"; import { isNumber } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
name: "icon-svg", name: "icon-svg",
props: { props: {
name: { name: {
type: String type: String,
}, },
className: { className: {
type: String type: String,
}, },
size: { size: {
type: [String, Number] type: [String, Number],
} },
}, },
setup(props) { setup(props) {
const style = ref<any>({ const style = ref<any>({
fontSize: isNumber(props.size) ? props.size + "px" : props.size fontSize: isNumber(props.size) ? props.size + "px" : props.size,
}); });
const iconName = computed<string>(() => `#${props.name}`); const iconName = computed<string>(() => `#icon-${props.name}`);
const svgClass = computed<Array<string>>(() => { const svgClass = computed<Array<string>>(() => {
return ["icon-svg", `icon-svg__${props.name}`, String(props.className || "")]; return [
"icon-svg",
`icon-svg__${props.name}`,
String(props.className || ""),
];
}); });
return { return {
style, style,
iconName, iconName,
svgClass svgClass,
}; };
} },
}); });
</script> </script>

View File

@ -1,6 +1,12 @@
<template> <template>
<div class="cl-menu-file"> <div class="cl-menu-file">
<el-select v-model="path" allow-create filterable clearable placeholder="请选择"> <el-select
v-model="path"
allow-create
filterable
clearable
placeholder="请选择"
>
<el-option <el-option
v-for="(item, index) in list" v-for="(item, index) in list"
:key="index" :key="index"
@ -17,15 +23,18 @@ import { defineComponent, ref, watch } from "vue";
// //
function findFiles() { function findFiles() {
const files = require const files = import.meta.globEager("/**/views/**/*.vue");
.context("@/", true, /views\/(?!(components)|(.*\/components)|(index\.js)).*.(js|vue)/) let list = [];
.keys();
return files.map(e => { for (const i in files) {
return { if (!i.includes("components")) {
value: e.substr(2) list.push({
}; value: i.substr(5),
}); });
}
}
return list;
} }
export default defineComponent({ export default defineComponent({
@ -34,8 +43,8 @@ export default defineComponent({
props: { props: {
modelValue: { modelValue: {
type: String, type: String,
default: "" default: "",
} },
}, },
emits: ["update:modelValue"], emits: ["update:modelValue"],
@ -49,20 +58,20 @@ export default defineComponent({
watch( watch(
() => props.modelValue, () => props.modelValue,
val => { (val) => {
path.value = val || ""; path.value = val || "";
} }
); );
watch(path, val => { watch(path, (val) => {
emit("update:modelValue", val); emit("update:modelValue", val);
}); });
return { return {
path, path,
list list,
}; };
} },
}); });
</script> </script>
@ -70,7 +79,7 @@ export default defineComponent({
.cl-menu-file { .cl-menu-file {
width: 100%; width: 100%;
:deep(.el-select) { .el-select {
width: 100%; width: 100%;
} }

View File

@ -34,7 +34,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, watch } from "vue"; import { defineComponent, ref, watch } from "vue";
import { iconList } from "@/cool/modules/base"; import { iconList } from "/@/cool/modules/base";
export default defineComponent({ export default defineComponent({
name: "cl-menu-icons", name: "cl-menu-icons",

View File

@ -21,8 +21,8 @@ export default defineComponent({
props: { props: {
modelValue: { modelValue: {
type: String, type: String,
default: "" default: "",
} },
}, },
emits: ["update:modelValue"], emits: ["update:modelValue"],
@ -38,7 +38,10 @@ export default defineComponent({
// //
function onChange(row: any) { function onChange(row: any) {
emit("update:modelValue", row.map((e: any) => e.join(":")).join(",")); emit(
"update:modelValue",
row.map((e: any) => e.join(":")).join(",")
);
} }
// //
@ -61,9 +64,9 @@ export default defineComponent({
flat($service); flat($service);
perms perms
.filter(e => e.includes(":")) .filter((e) => e.includes(":"))
.map(e => e.split(":")) .map((e) => e.split(":"))
.forEach(arr => { .forEach((arr) => {
const col = (i: number, d: any[]) => { const col = (i: number, d: any[]) => {
const key = arr[i]; const key = arr[i];
@ -77,7 +80,7 @@ export default defineComponent({
d.push({ d.push({
label: key, label: key,
value: key, value: key,
children: isLast ? null : [] children: isLast ? null : [],
}); });
if (!isLast) { if (!isLast) {
@ -96,25 +99,27 @@ export default defineComponent({
watch( watch(
() => props.modelValue, () => props.modelValue,
(val: string) => { (val: string) => {
value.value = val ? val.split(",").map((e: string) => e.split(":")) : []; value.value = val
? val.split(",").map((e: string) => e.split(":"))
: [];
}, },
{ {
immediate: true immediate: true,
} }
); );
return { return {
value, value,
options, options,
onChange onChange,
}; };
} },
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.cl-menu-perms { .cl-menu-perms {
:deep(.el-cascader) { .el-cascader {
width: 100%; width: 100%;
} }
} }

View File

@ -6,8 +6,16 @@
background-color="transparent" background-color="transparent"
@select="onSelect" @select="onSelect"
> >
<el-menu-item v-for="(item, index) in list" :index="`${index}`" :key="index"> <el-menu-item
<icon-svg v-if="item.icon" :name="item.icon" :size="18"></icon-svg> v-for="(item, index) in list"
:index="`${index}`"
:key="index"
>
<icon-svg
v-if="item.icon"
:name="item.icon"
:size="18"
></icon-svg>
<span>{{ item.name }}</span> <span>{{ item.name }}</span>
</el-menu-item> </el-menu-item>
</el-menu> </el-menu>
@ -37,7 +45,9 @@ export default defineComponent({
const index = ref<string>("0"); const index = ref<string>("0");
// //
const list = computed(() => store.getters.menuGroup.filter((e: any) => e.isShow)); const list = computed(() =>
store.getters.menuGroup.filter((e: any) => e.isShow)
);
// //
function onSelect(index: number) { function onSelect(index: number) {
@ -48,7 +58,7 @@ export default defineComponent({
router.push(url); router.push(url);
} }
onMounted(function() { onMounted(function () {
// //
function deep(e: any, i: number) { function deep(e: any, i: number) {
switch (e.type) { switch (e.type) {
@ -77,27 +87,26 @@ export default defineComponent({
return { return {
index, index,
list, list,
onSelect onSelect,
}; };
} },
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.cl-menu-topbar { .cl-menu-topbar {
margin-right: 10px; margin-right: 10px;
:deep(.el-menu) { .el-menu {
height: 50px; height: 50px;
background: transparent; background: transparent;
border-bottom: 0;
overflow: hidden; overflow: hidden;
.el-menu-item { .el-menu-item {
display: flex; display: flex;
align-items: center; align-items: center;
height: 50px; height: 50px;
border-bottom: 0; border-bottom: 0 !important;
padding: 0 20px; padding: 0 20px;
background: transparent; background: transparent;
@ -111,7 +120,7 @@ export default defineComponent({
color: $color-primary; color: $color-primary;
} }
:deep(.icon-svg) { .icon-svg {
margin-right: 5px; margin-right: 5px;
} }
} }

View File

@ -37,7 +37,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, inject, onMounted, ref, watch } from "vue"; import { computed, defineComponent, inject, onMounted, ref, watch } from "vue";
import { deepTree } from "@/core/utils"; import { deepTree } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
name: "cl-menu-tree", name: "cl-menu-tree",

View File

@ -30,9 +30,9 @@
import { computed, reactive, watch } from "vue"; import { computed, reactive, watch } from "vue";
import { useStore } from "vuex"; import { useStore } from "vuex";
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import { last } from "@/core/utils"; import { last } from "/@/core/utils";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
import { ContextMenu } from "@/crud"; import { ContextMenu } from "/@/crud";
export default { export default {
name: "cl-process", name: "cl-process",

View File

@ -27,7 +27,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, inject, onMounted, ref, watch } from "vue"; import { defineComponent, inject, onMounted, ref, watch } from "vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { deepTree } from "@/core/utils"; import { deepTree } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
name: "cl-role-perms", name: "cl-role-perms",

View File

@ -11,7 +11,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, inject, onMounted, ref, watch } from "vue"; import { defineComponent, inject, onMounted, ref, watch } from "vue";
import { isArray } from "@/core/utils"; import { isArray } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
name: "cl-role-select", name: "cl-role-select",

View File

@ -6,10 +6,16 @@
<template v-else> <template v-else>
<el-breadcrumb> <el-breadcrumb>
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item> <el-breadcrumb-item :to="{ path: '/' }"
<el-breadcrumb-item v-for="(item, index) in list" :key="index">{{ >首页</el-breadcrumb-item
(item.meta && item.meta.label) || item.name >
}}</el-breadcrumb-item> <el-breadcrumb-item
v-for="(item, index) in list"
:key="index"
>{{
(item.meta && item.meta.label) || item.name
}}</el-breadcrumb-item
>
</el-breadcrumb> </el-breadcrumb>
</template> </template>
</div> </div>
@ -20,7 +26,7 @@ import { computed, defineComponent, ref, watch } from "vue";
import { useStore } from "vuex"; import { useStore } from "vuex";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import _ from "lodash"; import _ from "lodash";
import { isEmpty } from "@/core/utils"; import { isEmpty } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
name: "cl-route-nav", name: "cl-route-nav",
@ -69,7 +75,7 @@ export default defineComponent({
} }
}, },
{ {
immediate: true immediate: true,
} }
); );
@ -81,17 +87,17 @@ export default defineComponent({
return { return {
list, list,
lastName, lastName,
browser browser,
}; };
} },
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.cl-route-nav { .cl-route-nav {
white-space: nowrap; white-space: nowrap;
:deep(.el-breadcrumb) { .el-breadcrumb {
margin: 0 10px; margin: 0 10px;
&__inner { &__inner {

View File

@ -21,7 +21,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent } from "vue"; import { computed, defineComponent } from "vue";
import { getBrowser } from "@/core/utils"; import { getBrowser } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
name: "cl-scrollbar", name: "cl-scrollbar",

View File

@ -1,4 +1,4 @@
import store from "@/store"; import store from "/@/store";
function parse(value: any) { function parse(value: any) {
const permission = store.getters.permission; const permission = store.getters.permission;

View File

@ -3,7 +3,7 @@
</template> </template>
<script> <script>
import ErrorPage from "./components/error-page"; import ErrorPage from "./components/error-page.vue";
export default { export default {
components: { components: {

View File

@ -3,7 +3,7 @@
</template> </template>
<script> <script>
import ErrorPage from "./components/error-page"; import ErrorPage from "./components/error-page.vue";
export default { export default {
components: { components: {

View File

@ -3,7 +3,7 @@
</template> </template>
<script> <script>
import ErrorPage from "./components/error-page"; import ErrorPage from "./components/error-page.vue";
export default { export default {
components: { components: {

View File

@ -3,7 +3,7 @@
</template> </template>
<script> <script>
import ErrorPage from "./components/error-page"; import ErrorPage from "./components/error-page.vue";
export default { export default {
components: { components: {

View File

@ -36,7 +36,7 @@
import { useStore } from "vuex"; import { useStore } from "vuex";
import { computed, defineComponent, ref } from "vue"; import { computed, defineComponent, ref } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { href } from "@/core/utils"; import { href } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
props: { props: {

View File

@ -46,7 +46,12 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-button round size="mini" class="submit-btn" @click="toLogin" :loading="saving" <el-button
round
size="mini"
class="submit-btn"
@click="toLogin"
:loading="saving"
>登录</el-button >登录</el-button
> >
</div> </div>
@ -59,11 +64,11 @@ import { ElMessage } from "element-plus";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useStore } from "vuex"; import { useStore } from "vuex";
import Captcha from "./components/captcha.vue"; import Captcha from "./components/captcha.vue";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
export default defineComponent({ export default defineComponent({
components: { components: {
Captcha Captcha,
}, },
setup() { setup() {
@ -78,7 +83,7 @@ export default defineComponent({
username: "admin", username: "admin",
password: "123456", password: "123456",
captchaId: "", captchaId: "",
verifyCode: "" verifyCode: "",
}); });
// //
@ -125,13 +130,13 @@ export default defineComponent({
form, form,
saving, saving,
toLogin, toLogin,
setRefs setRefs,
}; };
} },
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.page-login { .page-login {
height: 100vh; height: 100vh;
width: 100vw; width: 100vw;
@ -161,7 +166,7 @@ export default defineComponent({
letter-spacing: 1px; letter-spacing: 1px;
} }
:deep(.el-form) { .el-form {
width: 300px; width: 300px;
border-radius: 3px; border-radius: 3px;

View File

@ -1,4 +1,4 @@
import { BaseService, Service } from "@/core"; import { BaseService, Service } from "/@/core";
@Service("base/comm") @Service("base/comm")
class Common extends BaseService { class Common extends BaseService {

View File

@ -1,4 +1,4 @@
import { BaseService, Service } from "@/core"; import { BaseService, Service } from "/@/core";
@Service("base/open") @Service("base/open")
class Open extends BaseService { class Open extends BaseService {

View File

@ -1,4 +1,4 @@
import { BaseService, Service, Permission } from "@/core"; import { BaseService, Service, Permission } from "/@/core";
@Service("base/plugin/info") @Service("base/plugin/info")
class PluginInfo extends BaseService { class PluginInfo extends BaseService {

View File

@ -1,4 +1,4 @@
import { BaseService, Service, Permission } from "@/core"; import { BaseService, Service, Permission } from "/@/core";
@Service("base/sys/department") @Service("base/sys/department")
class SysDepartment extends BaseService { class SysDepartment extends BaseService {

View File

@ -1,4 +1,4 @@
import { BaseService, Service, Permission } from "@/core"; import { BaseService, Service, Permission } from "/@/core";
@Service("base/sys/log") @Service("base/sys/log")
class SysLog extends BaseService { class SysLog extends BaseService {

View File

@ -1,4 +1,4 @@
import { BaseService, Service } from "@/core"; import { BaseService, Service } from "/@/core";
@Service("base/sys/menu") @Service("base/sys/menu")
class SysMenu extends BaseService {} class SysMenu extends BaseService {}

View File

@ -1,4 +1,4 @@
import { BaseService, Service } from "@/core"; import { BaseService, Service } from "/@/core";
@Service("base/sys/param") @Service("base/sys/param")
class SysParam extends BaseService {} class SysParam extends BaseService {}

View File

@ -1,4 +1,4 @@
import { BaseService, Service } from "@/core"; import { BaseService, Service } from "/@/core";
@Service("base/sys/role") @Service("base/sys/role")
class SysRole extends BaseService {} class SysRole extends BaseService {}

View File

@ -1,4 +1,4 @@
import { BaseService, Service, Permission } from "@/core"; import { BaseService, Service, Permission } from "/@/core";
@Service("base/sys/task") @Service("base/sys/task")
class SysTask extends BaseService { class SysTask extends BaseService {

View File

@ -1,4 +1,4 @@
import { BaseService, Service, Permission } from "@/core"; import { BaseService, Service, Permission } from "/@/core";
@Service("base/sys/user") @Service("base/sys/user")
class SysUser extends BaseService { class SysUser extends BaseService {

View File

@ -1,6 +1,6 @@
import store from "store"; import store from "store";
import { deepMerge, getBrowser } from "@/core/utils"; import { deepMerge, getBrowser } from "/@/core/utils";
import { app } from "@/config/env"; import { app } from "/@/config/env";
const browser = getBrowser(); const browser = getBrowser();

View File

@ -1,9 +1,9 @@
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import storage from "store"; import storage from "store";
import store from "@/store"; import store from "/@/store";
import router from "@/router"; import router from "/@/router";
import { deepTree, revDeepTree, isArray, isEmpty } from "@/core/utils"; import { deepTree, revDeepTree, isArray, isEmpty } from "/@/core/utils";
import { menuList } from "@/config/env"; import { menuList } from "/@/config/env";
import { revisePath } from "../utils"; import { revisePath } from "../utils";
import { MenuItem } from "../types"; import { MenuItem } from "../types";
@ -17,7 +17,7 @@ const state = {
// 左侧菜单 // 左侧菜单
menu: [], menu: [],
// 权限列表 // 权限列表
permission: storage.get("permission") || [] permission: storage.get("permission") || [],
}; };
const getters = { const getters = {
@ -28,7 +28,7 @@ const getters = {
// 视图路由 // 视图路由
routes: (state: any) => state.routes, routes: (state: any) => state.routes,
// 权限列表 // 权限列表
permission: (state: any) => state.permission permission: (state: any) => state.permission,
}; };
const actions = { const actions = {
@ -59,9 +59,9 @@ const actions = {
isShow: isEmpty(e.isShow) ? true : e.isShow, isShow: isEmpty(e.isShow) ? true : e.isShow,
meta: { meta: {
label: e.name, label: e.name,
keepAlive: e.keepAlive keepAlive: e.keepAlive,
}, },
children: [] children: [],
}; };
}); });
@ -97,11 +97,11 @@ const actions = {
}); });
} else { } else {
next({ next({
menus: revDeepTree(menuList) menus: revDeepTree(menuList),
}); });
} }
}); });
} },
}; };
const mutations = { const mutations = {
@ -141,12 +141,12 @@ const mutations = {
SET_PERMIESSION(state: any, list: Array<any>) { SET_PERMIESSION(state: any, list: Array<any>) {
state.permission = list; state.permission = list;
storage.set("permission", list); storage.set("permission", list);
} },
}; };
export default { export default {
state, state,
getters, getters,
actions, actions,
mutations mutations,
}; };

View File

@ -1,5 +1,5 @@
import { storage, href } from "@/core/utils"; import { storage, href } from "/@/core/utils";
import store from "@/store"; import store from "/@/store";
import { Token } from "../types"; import { Token } from "../types";
const state: any = { const state: any = {

View File

@ -2,13 +2,21 @@
<div class="page-my-info"> <div class="page-my-info">
<div class="title">基本信息</div> <div class="title">基本信息</div>
<el-form size="small" label-width="100px" :model="form" :disabled="saving"> <el-form
size="small"
label-width="100px"
:model="form"
:disabled="saving"
>
<el-form-item label="头像"> <el-form-item label="头像">
<cl-upload v-model="form.headImg"></cl-upload> <cl-upload v-model="form.headImg"></cl-upload>
</el-form-item> </el-form-item>
<el-form-item label="昵称"> <el-form-item label="昵称">
<el-input v-model="form.nickName" placeholder="请填写昵称"></el-input> <el-input
v-model="form.nickName"
placeholder="请填写昵称"
></el-input>
</el-form-item> </el-form-item>
<el-form-item label="密码"> <el-form-item label="密码">
@ -16,7 +24,9 @@
</el-form-item> </el-form-item>
<el-form-item label=""> <el-form-item label="">
<el-button type="primary" @click="save" :disabled="saving">保存修改</el-button> <el-button type="primary" @click="save" :disabled="saving"
>保存修改</el-button
>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -50,7 +60,7 @@ export default defineComponent({
.userUpdate({ .userUpdate({
headImg, headImg,
nickName, nickName,
password password,
}) })
.then(() => { .then(() => {
form.password = ""; form.password = "";
@ -68,9 +78,9 @@ export default defineComponent({
return { return {
form, form,
saving, saving,
save save,
}; };
} },
}); });
</script> </script>

View File

@ -41,8 +41,8 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, inject, reactive, ref } from "vue"; import { defineComponent, inject, reactive, ref } from "vue";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
import { CrudLoad, Table } from "@/crud/types"; import { CrudLoad, Table } from "/@/crud/types";
export default defineComponent({ export default defineComponent({
name: "sys-log", name: "sys-log",

View File

@ -77,11 +77,11 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
import { deepTree } from "@/core/utils"; import { deepTree } from "/@/core/utils";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { defineComponent, inject, reactive } from "vue"; import { defineComponent, inject, reactive } from "vue";
import { CrudLoad, Table, Upsert, RefreshOp } from "@/crud/types"; import { CrudLoad, Table, Upsert, RefreshOp } from "/@/crud/types";
export default defineComponent({ export default defineComponent({
name: "sys-menu", name: "sys-menu",

View File

@ -40,8 +40,8 @@
<script lang="ts"> <script lang="ts">
import { ElMessageBox } from "element-plus"; import { ElMessageBox } from "element-plus";
import { defineComponent, inject, nextTick, reactive } from "vue"; import { defineComponent, inject, nextTick, reactive } from "vue";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
import { CrudLoad, Table, Upsert } from "@/crud/types"; import { CrudLoad, Table, Upsert } from "/@/crud/types";
export default defineComponent({ export default defineComponent({
name: "sys-param", name: "sys-param",

View File

@ -49,9 +49,9 @@
<script lang="ts"> <script lang="ts">
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { defineComponent, inject, reactive } from "vue"; import { defineComponent, inject, reactive } from "vue";
import { checkPerm } from "@/cool/modules/base"; import { checkPerm } from "/@/cool/modules/base";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
import { CrudLoad, RefreshOp, Table } from "@/crud/types"; import { CrudLoad, RefreshOp, Table } from "/@/crud/types";
export default defineComponent({ export default defineComponent({
name: "plugin", name: "plugin",
@ -65,9 +65,9 @@ export default defineComponent({
const perms = reactive<any>({ const perms = reactive<any>({
edit: checkPerm({ edit: checkPerm({
and: [config, getConfig] and: [config, getConfig],
}), }),
enable: checkPerm(enable) enable: checkPerm(enable),
}); });
// crud // crud
@ -75,8 +75,8 @@ export default defineComponent({
ctx.service($service.plugin.info) ctx.service($service.plugin.info)
.set("dict", { .set("dict", {
api: { api: {
page: "list" page: "list",
} },
}) })
.done(); .done();
app.refresh(); app.refresh();
@ -91,7 +91,7 @@ export default defineComponent({
}); });
render(list, { render(list, {
total: res.length total: res.length,
}); });
}); });
} }
@ -101,7 +101,7 @@ export default defineComponent({
$service.plugin.info $service.plugin.info
.enable({ .enable({
namespace: item.namespace, namespace: item.namespace,
enable: val enable: val,
}) })
.then(() => { .then(() => {
ElMessage.success(val ? "开启成功" : "关闭成功"); ElMessage.success(val ? "开启成功" : "关闭成功");
@ -114,7 +114,7 @@ export default defineComponent({
// //
async function openConf({ name, namespace, view }: any) { async function openConf({ name, namespace, view }: any) {
const form = await $service.plugin.info.getConfig({ const form = await $service.plugin.info.getConfig({
namespace namespace,
}); });
let items = []; let items = [];
@ -134,7 +134,7 @@ export default defineComponent({
$service.plugin.info $service.plugin.info
.config({ .config({
namespace, namespace,
config: data config: data,
}) })
.then(() => { .then(() => {
ElMessage.success("保存成功"); ElMessage.success("保存成功");
@ -144,8 +144,8 @@ export default defineComponent({
ElMessage.error(err); ElMessage.error(err);
done(); done();
}); });
} },
} },
}); });
} }
@ -154,8 +154,8 @@ export default defineComponent({
props: { props: {
"default-sort": { "default-sort": {
prop: "createTime", prop: "createTime",
order: "descending" order: "descending",
} },
}, },
"context-menu": [ "context-menu": [
"refresh", "refresh",
@ -166,47 +166,47 @@ export default defineComponent({
callback: (_: any, done: Function) => { callback: (_: any, done: Function) => {
openConf(scope); openConf(scope);
done(); done();
} },
}; };
} },
], ],
columns: [ columns: [
{ {
label: "名称", label: "名称",
prop: "name", prop: "name",
minWidth: 140 minWidth: 140,
}, },
{ {
label: "作者", label: "作者",
prop: "author", prop: "author",
minWidth: 120 minWidth: 120,
}, },
{ {
label: "联系方式", label: "联系方式",
prop: "contact", prop: "contact",
showOverflowTooltip: true, showOverflowTooltip: true,
minWidth: 180 minWidth: 180,
}, },
{ {
label: "功能描述", label: "功能描述",
prop: "description", prop: "description",
showOverflowTooltip: true, showOverflowTooltip: true,
minWidth: 150 minWidth: 150,
}, },
{ {
label: "版本号", label: "版本号",
prop: "version", prop: "version",
minWidth: 110 minWidth: 110,
}, },
{ {
label: "是否启用", label: "是否启用",
prop: "enable", prop: "enable",
minWidth: 110 minWidth: 110,
}, },
{ {
label: "命名空间", label: "命名空间",
prop: "namespace", prop: "namespace",
minWidth: 110 minWidth: 110,
}, },
{ {
label: "状态", label: "状态",
@ -216,37 +216,37 @@ export default defineComponent({
{ {
label: "缺少配置", label: "缺少配置",
value: 0, value: 0,
type: "warning" type: "warning",
}, },
{ {
label: "可用", label: "可用",
value: 1, value: 1,
type: "success" type: "success",
}, },
{ {
label: "配置错误", label: "配置错误",
value: 2, value: 2,
type: "danger" type: "danger",
}, },
{ {
label: "未知错误", label: "未知错误",
value: 3, value: 3,
type: "danger" type: "danger",
} },
] ],
}, },
{ {
label: "创建时间", label: "创建时间",
prop: "createTime", prop: "createTime",
width: 150, width: 150,
sortable: "custom" sortable: "custom",
}, },
{ {
type: "op", type: "op",
width: 120, width: 120,
buttons: ["slot-conf"] buttons: ["slot-conf"],
} },
] ],
}); });
return { return {
@ -257,8 +257,8 @@ export default defineComponent({
onLoad, onLoad,
onRefresh, onRefresh,
onEnableChange, onEnableChange,
openConf openConf,
}; };
} },
}); });
</script> </script>

View File

@ -22,7 +22,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { CrudLoad, Table, Upsert } from "@/crud/types"; import { CrudLoad, Table, Upsert } from "/@/crud/types";
import { defineComponent, inject, reactive } from "vue"; import { defineComponent, inject, reactive } from "vue";
export default defineComponent({ export default defineComponent({

View File

@ -22,13 +22,19 @@
</div> </div>
<div class="container"> <div class="container">
<cl-crud :ref="setRefs('crud')" :on-refresh="onRefresh" @load="onLoad"> <cl-crud
:ref="setRefs('crud')"
:on-refresh="onRefresh"
@load="onLoad"
>
<el-row type="flex"> <el-row type="flex">
<cl-refresh-btn></cl-refresh-btn> <cl-refresh-btn></cl-refresh-btn>
<cl-add-btn></cl-add-btn> <cl-add-btn></cl-add-btn>
<cl-multi-delete-btn></cl-multi-delete-btn> <cl-multi-delete-btn></cl-multi-delete-btn>
<el-button <el-button
v-permission="$service.system.user.permission.move" v-permission="
$service.system.user.permission.move
"
size="mini" size="mini"
type="success" type="success"
:disabled="selects.ids.length == 0" :disabled="selects.ids.length == 0"
@ -59,7 +65,8 @@
<!-- 权限 --> <!-- 权限 -->
<template #column-roleName="{ scope }"> <template #column-roleName="{ scope }">
<el-tag <el-tag
v-for="(item, index) in scope.row.roleNameList" v-for="(item, index) in scope.row
.roleNameList"
:key="index" :key="index"
disable-transitions disable-transitions
size="small" size="small"
@ -72,7 +79,9 @@
<!-- 单个转移 --> <!-- 单个转移 -->
<template #slot-move-btn="{ scope }"> <template #slot-move-btn="{ scope }">
<el-button <el-button
v-permission="$service.system.user.permission.move" v-permission="
$service.system.user.permission.move
"
type="text" type="text"
size="mini" size="mini"
@click="toMove(scope.row)" @click="toMove(scope.row)"
@ -95,7 +104,9 @@
<template #slot-tips> <template #slot-tips>
<div> <div>
<i class="el-icon-warning"></i> <i class="el-icon-warning"></i>
<span style="margin-left: 6px">新增用户默认密码为123456</span> <span style="margin-left: 6px"
>新增用户默认密码为123456</span
>
</div> </div>
</template> </template>
</cl-upsert> </cl-upsert>
@ -105,15 +116,18 @@
</div> </div>
<!-- 部门移动 --> <!-- 部门移动 -->
<cl-dept-move :ref="setRefs('dept-move')" @success="refresh({ page: 1 })"></cl-dept-move> <cl-dept-move
:ref="setRefs('dept-move')"
@success="refresh({ page: 1 })"
></cl-dept-move>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, inject, reactive, ref, watch } from "vue"; import { computed, defineComponent, inject, reactive, ref, watch } from "vue";
import { useStore } from "vuex"; import { useStore } from "vuex";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
import { Table, Upsert } from "@/crud/types"; import { Table, Upsert } from "/@/crud/types";
export default defineComponent({ export default defineComponent({
name: "sys-user", name: "sys-user",
@ -129,7 +143,7 @@ export default defineComponent({
// //
const selects = reactive<any>({ const selects = reactive<any>({
dept: {}, dept: {},
ids: [] ids: [],
}); });
// //
@ -140,53 +154,53 @@ export default defineComponent({
props: { props: {
"default-sort": { "default-sort": {
prop: "createTime", prop: "createTime",
order: "descending" order: "descending",
} },
}, },
columns: [ columns: [
{ {
type: "selection", type: "selection",
width: 60 width: 60,
}, },
{ {
prop: "headImg", prop: "headImg",
label: "头像" label: "头像",
}, },
{ {
prop: "name", prop: "name",
label: "姓名", label: "姓名",
minWidth: 150 minWidth: 150,
}, },
{ {
prop: "username", prop: "username",
label: "用户名", label: "用户名",
minWidth: 150 minWidth: 150,
}, },
{ {
prop: "nickName", prop: "nickName",
label: "昵称", label: "昵称",
minWidth: 150 minWidth: 150,
}, },
{ {
prop: "departmentName", prop: "departmentName",
label: "部门名称", label: "部门名称",
minWidth: 150 minWidth: 150,
}, },
{ {
prop: "roleName", prop: "roleName",
label: "角色", label: "角色",
headerAlign: "center", headerAlign: "center",
minWidth: 200 minWidth: 200,
}, },
{ {
prop: "phone", prop: "phone",
label: "手机号码", label: "手机号码",
minWidth: 150 minWidth: 150,
}, },
{ {
prop: "remark", prop: "remark",
label: "备注", label: "备注",
minWidth: 150 minWidth: 150,
}, },
{ {
prop: "status", prop: "status",
@ -196,27 +210,27 @@ export default defineComponent({
{ {
label: "启用", label: "启用",
value: 1, value: 1,
type: "success" type: "success",
}, },
{ {
label: "禁用", label: "禁用",
value: 0, value: 0,
type: "danger" type: "danger",
} },
] ],
}, },
{ {
prop: "createTime", prop: "createTime",
label: "创建时间", label: "创建时间",
sortable: "custom", sortable: "custom",
minWidth: 150 minWidth: 150,
}, },
{ {
type: "op", type: "op",
buttons: ["slot-move-btn", "edit", "delete"], buttons: ["slot-move-btn", "edit", "delete"],
width: 160 width: 160,
} },
] ],
}); });
// //
@ -230,9 +244,9 @@ export default defineComponent({
name: "cl-upload", name: "cl-upload",
props: { props: {
text: "选择头像", text: "选择头像",
icon: "el-icon-picture" icon: "el-icon-picture",
} },
} },
}, },
{ {
prop: "name", prop: "name",
@ -241,13 +255,13 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
placeholder: "请填写姓名" placeholder: "请填写姓名",
} },
}, },
rules: { rules: {
required: true, required: true,
message: "姓名不能为空" message: "姓名不能为空",
} },
}, },
{ {
prop: "nickName", prop: "nickName",
@ -256,13 +270,13 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
placeholder: "请填写昵称" placeholder: "请填写昵称",
} },
}, },
rules: { rules: {
required: true, required: true,
message: "昵称不能为空" message: "昵称不能为空",
} },
}, },
{ {
prop: "username", prop: "username",
@ -271,15 +285,15 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
placeholder: "请填写用户名" placeholder: "请填写用户名",
} },
}, },
rules: [ rules: [
{ {
required: true, required: true,
message: "用户名不能为空" message: "用户名不能为空",
} },
] ],
}, },
{ {
prop: "password", prop: "password",
@ -290,16 +304,16 @@ export default defineComponent({
name: "el-input", name: "el-input",
props: { props: {
placeholder: "请填写密码", placeholder: "请填写密码",
type: "password" type: "password",
} },
}, },
rules: [ rules: [
{ {
min: 6, min: 6,
max: 16, max: 16,
message: "密码长度在 6 到 16 个字符" message: "密码长度在 6 到 16 个字符",
} },
] ],
}, },
{ {
prop: "roleIdList", prop: "roleIdList",
@ -310,14 +324,14 @@ export default defineComponent({
name: "cl-role-select", name: "cl-role-select",
props: { props: {
props: { props: {
"multiple-limit": 3 "multiple-limit": 3,
} },
} },
}, },
rules: { rules: {
required: true, required: true,
message: "角色不能为空" message: "角色不能为空",
} },
}, },
{ {
prop: "phone", prop: "phone",
@ -326,9 +340,9 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
placeholder: "请填写手机号码" placeholder: "请填写手机号码",
} },
} },
}, },
{ {
prop: "email", prop: "email",
@ -337,9 +351,9 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
placeholder: "请填写邮箱" placeholder: "请填写邮箱",
} },
} },
}, },
{ {
prop: "remark", prop: "remark",
@ -350,9 +364,9 @@ export default defineComponent({
props: { props: {
placeholder: "请填写备注", placeholder: "请填写备注",
type: "textarea", type: "textarea",
rows: 4 rows: 4,
} },
} },
}, },
{ {
prop: "status", prop: "status",
@ -363,23 +377,23 @@ export default defineComponent({
options: [ options: [
{ {
label: "开启", label: "开启",
value: 1 value: 1,
}, },
{ {
label: "关闭", label: "关闭",
value: 0 value: 0,
} },
] ],
} },
}, },
{ {
prop: "tips", prop: "tips",
hidden: ":isEdit", hidden: ":isEdit",
component: { component: {
name: "slot-tips" name: "slot-tips",
} },
} },
] ],
}); });
// //
@ -392,7 +406,7 @@ export default defineComponent({
isExpand.value = !val; isExpand.value = !val;
}, },
{ {
immediate: true immediate: true,
} }
); );
@ -436,13 +450,13 @@ export default defineComponent({
next({ next({
...data, ...data,
departmentId departmentId,
}); });
} }
// //
function onSelectionChange(selection: any[]) { function onSelectionChange(selection: any[]) {
selects.ids = selection.map(e => e.id); selects.ids = selection.map((e) => e.id);
} }
// //
@ -451,7 +465,7 @@ export default defineComponent({
refresh({ refresh({
page: 1, page: 1,
departmentIds: ids departmentIds: ids,
}); });
// //
@ -463,7 +477,7 @@ export default defineComponent({
// //
function onDeptUserAdd(item: any) { function onDeptUserAdd(item: any) {
refs.value.crud.rowAppend({ refs.value.crud.rowAppend({
departmentId: item.id departmentId: item.id,
}); });
} }
@ -508,9 +522,9 @@ export default defineComponent({
onDeptUserAdd, onDeptUserAdd,
onDeptListChange, onDeptListChange,
deptExpand, deptExpand,
toMove toMove,
}; };
} },
}); });
</script> </script>

View File

@ -55,12 +55,12 @@ import { useStore } from "vuex";
import { ElNotification } from "element-plus"; import { ElNotification } from "element-plus";
import dayjs from "dayjs"; import dayjs from "dayjs";
// import io from "socket.io-client"; // import io from "socket.io-client";
// import { socketUrl } from "@/config/env"; // import { socketUrl } from "/@/config/env";
import Session from "./session.vue"; import Session from "./session.vue";
import Message from "./message.vue"; import Message from "./message.vue";
import Input from "./input.vue"; import Input from "./input.vue";
import { parseContent } from "../utils"; import { parseContent } from "../utils";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
export default defineComponent({ export default defineComponent({
name: "cl-chat", name: "cl-chat",

View File

@ -13,7 +13,7 @@
accept="image/*" accept="image/*"
list-type list-type
:before-upload=" :before-upload="
file => { (file) => {
onBeforeUpload(file, 'image'); onBeforeUpload(file, 'image');
} }
" "
@ -33,7 +33,7 @@
accept="video/*" accept="video/*"
list-type list-type
:before-upload=" :before-upload="
file => { (file) => {
onBeforeUpload(file, 'video'); onBeforeUpload(file, 'video');
} }
" "
@ -61,7 +61,11 @@
@keyup.enter="onTextSend" @keyup.enter="onTextSend"
></el-input> ></el-input>
<el-button type="primary" size="mini" :disabled="!text" @click="onTextSend" <el-button
type="primary"
size="mini"
:disabled="!text"
@click="onTextSend"
>发送</el-button >发送</el-button
> >
</div> </div>
@ -75,7 +79,7 @@ import Emoji from "./emoji.vue";
export default defineComponent({ export default defineComponent({
components: { components: {
Emoji Emoji,
}, },
setup() { setup() {
@ -88,7 +92,7 @@ export default defineComponent({
// //
const emoji = reactive<any>({ const emoji = reactive<any>({
visible: false visible: false,
}); });
// //
@ -112,7 +116,7 @@ export default defineComponent({
contentType: data.contentType, contentType: data.contentType,
type: 0, type: 0,
content: data.content, content: data.content,
sessionId: id sessionId: id,
}); });
} }
@ -127,14 +131,14 @@ export default defineComponent({
function next(options = {}) { function next(options = {}) {
const data = { const data = {
content: { content: {
[`${key}Url`]: "" [`${key}Url`]: "",
}, },
type: 0, type: 0,
uid: file.uid, uid: file.uid,
loading: true, loading: true,
progress: "0%", progress: "0%",
contentType: chat.modes.indexOf(key), contentType: chat.modes.indexOf(key),
...options ...options,
}; };
append(data); append(data);
@ -159,12 +163,12 @@ export default defineComponent({
next({ next({
content: { content: {
imageUrl imageUrl,
}, },
style: { style: {
height: height + "px", height: height + "px",
width: width + "px" width: width + "px",
} },
}); });
}; };
@ -182,8 +186,8 @@ export default defineComponent({
store.commit("UPDATE_MESSAGE", { store.commit("UPDATE_MESSAGE", {
file, file,
data: { data: {
progress: e.percent + "%" progress: e.percent + "%",
} },
}); });
} }
@ -194,10 +198,10 @@ export default defineComponent({
data: { data: {
loading: false, loading: false,
content: { content: {
[`${key}Url`]: res.data [`${key}Url`]: res.data,
} },
}, },
callback: send callback: send,
}); });
} }
@ -209,8 +213,8 @@ export default defineComponent({
type: 0, type: 0,
contentType: 0, contentType: 0,
content: { content: {
text: text.value text: text.value,
} },
}; };
send(data, true); send(data, true);
@ -227,10 +231,10 @@ export default defineComponent({
send( send(
{ {
content: { content: {
imageUrl: res.data imageUrl: res.data,
}, },
type: 0, type: 0,
contentType: 1 contentType: 1,
}, },
true true
); );
@ -242,10 +246,10 @@ export default defineComponent({
send( send(
{ {
content: { content: {
imageUrl: url imageUrl: url,
}, },
type: 0, type: 0,
contentType: 2 contentType: 2,
}, },
true true
); );
@ -256,10 +260,10 @@ export default defineComponent({
send( send(
{ {
content: { content: {
videoUrl: url videoUrl: url,
}, },
type: 0, type: 0,
contentType: 4 contentType: 4,
}, },
true true
); );
@ -275,13 +279,13 @@ export default defineComponent({
onTextSend, onTextSend,
onImageSelect, onImageSelect,
onEmojiSelect, onEmojiSelect,
onVideoSelect onVideoSelect,
}; };
} },
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.cl-chat-input { .cl-chat-input {
background-color: #fff; background-color: #fff;
padding: 10px; padding: 10px;
@ -302,7 +306,7 @@ export default defineComponent({
opacity: 0.7; opacity: 0.7;
} }
:deep(img) { img {
height: 26px; height: 26px;
width: 26px; width: 26px;
} }

View File

@ -1,15 +1,23 @@
<template> <template>
<div class="cl-chat-message" v-loading="!visible && loading" element-loading-text="消息加载中"> <div
class="cl-chat-message"
v-loading="!visible && loading"
element-loading-text="消息加载中"
>
<div <div
class="cl-chat-message__scroller scroller1" class="cl-chat-message__scroller scroller1"
:ref="setRefs('scroller')" :ref="setRefs('scroller')"
:style="{ :style="{
opacity: visible ? 1 : 0 opacity: visible ? 1 : 0,
}" }"
> >
<!-- 加载更多 --> <!-- 加载更多 -->
<div class="cl-chat-message__more" v-show="list.length > 0"> <div class="cl-chat-message__more" v-show="list.length > 0">
<el-button round size="mini" :loading="loading" @click="onLoadmore" <el-button
round
size="mini"
:loading="loading"
@click="onLoadmore"
>加载更多</el-button >加载更多</el-button
> >
</div> </div>
@ -20,7 +28,10 @@
class="cl-chat-message__item" class="cl-chat-message__item"
v-for="item in list" v-for="item in list"
:key="item.id || item.uid" :key="item.id || item.uid"
:class="[item.type == 0 ? `is-right` : `is-left`, `is-${item.mode}`]" :class="[
item.type == 0 ? `is-right` : `is-left`,
`is-${item.mode}`,
]"
> >
<!-- 日期 --> <!-- 日期 -->
<div class="date" v-if="item._date"> <div class="date" v-if="item._date">
@ -54,7 +65,9 @@
<el-image <el-image
:key="item.uid" :key="item.uid"
:src="item.content.imageUrl" :src="item.content.imageUrl"
:preview-src-list="[item.content.imageUrl]" :preview-src-list="[
item.content.imageUrl,
]"
:z-index="3000" :z-index="3000"
:style="item.style" :style="item.style"
> >
@ -75,8 +88,12 @@
<!-- 语音 --> <!-- 语音 -->
<template v-else-if="item.mode === 'voice'"> <template v-else-if="item.mode === 'voice'">
<icon-voice :play="item.isPlay"></icon-voice> <icon-voice
<span class="duration">{{ item.content.duration }}"</span> :play="item.isPlay"
></icon-voice>
<span class="duration"
>{{ item.content.duration }}"</span
>
</template> </template>
<!-- 视频 --> <!-- 视频 -->
@ -102,7 +119,12 @@
<!-- 音频 --> <!-- 音频 -->
<div class="voice"> <div class="voice">
<audio style="display: none" ref="voice" :src="voice.url" controls></audio> <audio
style="display: none"
ref="voice"
:src="voice.url"
controls
></audio>
</div> </div>
</div> </div>
</div> </div>
@ -110,17 +132,27 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, inject, nextTick, onUnmounted, reactive, ref } from "vue"; import {
computed,
defineComponent,
inject,
nextTick,
onUnmounted,
reactive,
ref,
} from "vue";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useStore } from "vuex"; import { useStore } from "vuex";
import { isString } from "@/core/utils"; import { isString } from "/@/core/utils";
import { useRefs } from "/@/core";
import IconVoice from "./icon-voice.vue"; import IconVoice from "./icon-voice.vue";
import { useRefs } from "@/core";
import AvatarUrl from "../static/images/custom-avatar.png";
export default defineComponent({ export default defineComponent({
components: { components: {
IconVoice IconVoice,
}, },
setup() { setup() {
@ -143,13 +175,13 @@ export default defineComponent({
const pagination = reactive<any>({ const pagination = reactive<any>({
page: 1, page: 1,
size: 20, size: 20,
total: 0 total: 0,
}); });
// //
const voice = reactive<any>({ const voice = reactive<any>({
url: "", url: "",
timer: null timer: null,
}); });
// //
@ -178,15 +210,18 @@ export default defineComponent({
} }
// //
const content = isString(e.content) ? JSON.parse(e.content) : e.content; const content = isString(e.content)
? JSON.parse(e.content)
: e.content;
// //
const nickName = e.type == 0 ? userInfo.nickName : session.value.nickname; const nickName =
e.type == 0 ? userInfo.nickName : session.value.nickname;
// //
const avatarUrl = const avatarUrl =
e.type == 0 e.type == 0
? userInfo.avatarUrl || require("../static/images/custom-avatar.png") ? userInfo.avatarUrl || AvatarUrl
: session.value.headimgurl; : session.value.headimgurl;
return { return {
@ -195,7 +230,7 @@ export default defineComponent({
content, content,
avatarUrl, avatarUrl,
nickName, nickName,
mode: chat.modes[e.contentType] mode: chat.modes[e.contentType],
}; };
}); });
}); });
@ -235,7 +270,7 @@ export default defineComponent({
if (refs.value.scroller) { if (refs.value.scroller) {
refs.value.scroller.scrollTo({ refs.value.scroller.scrollTo({
top: 99999, top: 99999,
behavior: visible.value ? "smooth" : "auto" behavior: visible.value ? "smooth" : "auto",
}); });
} }
}); });
@ -252,7 +287,7 @@ export default defineComponent({
...params, ...params,
sessionId: session.value.id, sessionId: session.value.id,
order: "createTime", order: "createTime",
sort: "desc" sort: "desc",
}; };
// //
@ -310,7 +345,7 @@ export default defineComponent({
mitt.on("message.scrollToBottom", scrollToBottom); mitt.on("message.scrollToBottom", scrollToBottom);
// //
onUnmounted(function() { onUnmounted(function () {
// //
clearTimeout(voice.timer); clearTimeout(voice.timer);
@ -336,9 +371,9 @@ export default defineComponent({
onTap, onTap,
refresh, refresh,
onLoadmore, onLoadmore,
scrollToBottom scrollToBottom,
}; };
} },
}); });
</script> </script>
@ -513,7 +548,7 @@ export default defineComponent({
.content { .content {
background-color: #fff; background-color: #fff;
:deep(.el-image) { .el-image {
display: block; display: block;
border-radius: 6px; border-radius: 6px;
max-width: 200px; max-width: 200px;

View File

@ -16,7 +16,7 @@ export default {
data() { data() {
return { return {
visible: false, visible: false,
number: 0 number: 0,
}; };
}, },
@ -26,7 +26,7 @@ export default {
methods: { methods: {
refresh() { refresh() {
this.$service.im.session.unreadCount().then(res => { this.$service.im.session.unreadCount().then((res) => {
this.number = Number(res); this.number = Number(res);
}); });
}, },
@ -38,8 +38,8 @@ export default {
openChatBox() { openChatBox() {
this.$refs["chat"].open(); this.$refs["chat"].open();
this.number = 0; this.number = 0;
} },
} },
}; };
</script> </script>

View File

@ -56,8 +56,8 @@
import { computed, defineComponent, inject, onUnmounted, reactive, ref } from "vue"; import { computed, defineComponent, inject, onUnmounted, reactive, ref } from "vue";
import { useStore } from "vuex"; import { useStore } from "vuex";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { isEmpty } from "@/core/utils"; import { isEmpty } from "/@/core/utils";
import { ContextMenu } from "@/crud"; import { ContextMenu } from "/@/crud";
import { parseContent } from "../utils"; import { parseContent } from "../utils";
export default defineComponent({ export default defineComponent({

View File

@ -1,4 +1,4 @@
import { BaseService, Service, Permission } from "@/core"; import { BaseService, Service, Permission } from "/@/core";
@Service({ @Service({
namespace: "im/message", namespace: "im/message",

View File

@ -1,4 +1,4 @@
import { BaseService, Service, Permission } from "@/core"; import { BaseService, Service, Permission } from "/@/core";
@Service({ @Service({
namespace: "im/session", namespace: "im/session",

View File

@ -1,4 +1,4 @@
import { isArray } from "@/core/utils"; import { isArray } from "/@/core/utils";
const state = { const state = {
list: [] list: []

View File

@ -1,4 +1,4 @@
import { isBoolean } from "@/core/utils"; import { isBoolean } from "/@/core/utils";
const state = { const state = {
list: [], list: [],

View File

@ -1,4 +1,4 @@
import { isObject } from "@/core/utils"; import { isObject } from "/@/core/utils";
export function parseContent({ content, contentType }: any) { export function parseContent({ content, contentType }: any) {
const data = isObject(content) ? content : JSON.parse(content); const data = isObject(content) ? content : JSON.parse(content);

View File

@ -6,7 +6,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { AdvSearchItem } from "@/crud/types"; import { AdvSearchItem } from "/@/crud/types";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({

View File

@ -5,7 +5,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ContextMenu } from "@/crud"; import { ContextMenu } from "/@/crud";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { defineComponent } from "vue"; import { defineComponent } from "vue";

View File

@ -50,9 +50,9 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, resolveComponent, h } from "vue"; import { defineComponent, ref, resolveComponent, h } from "vue";
import Test from "./components/test.vue"; import Test from "./test.vue";
import { TestService } from "../../utils/service"; import { TestService } from "../../utils/service";
import { CrudLoad, FormItem, FormRef } from "@/crud/types"; import { CrudLoad, FormItem, FormRef } from "/@/crud/types";
export default defineComponent({ export default defineComponent({
name: "demo-form", name: "demo-form",

View File

@ -3,7 +3,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { QueryList } from "@/crud/types"; import { QueryList } from "/@/crud/types";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({

View File

@ -5,7 +5,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { TableColumn } from "@/crud/types"; import { TableColumn } from "/@/crud/types";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({

View File

@ -5,7 +5,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { UpsertItem, UpsertRef } from "@/crud/types"; import { UpsertItem, UpsertRef } from "/@/crud/types";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({

View File

@ -1,142 +0,0 @@
<template>
<div class="scope">
<div class="h">
<span>cl-form</span>
自定义表单
</div>
<div class="c">
<el-button size="small" @click="openForm">填写邀请码</el-button>
</div>
<div class="f">
<span class="date">2019/10/11</span>
</div>
<cl-form ref="form"></cl-form>
</div>
</template>
<script>
export default {
methods: {
openForm() {
this.$refs.form.open({
title: "填写邀请码",
width: "450px",
dialog: {
controls: ["close"]
},
items: [
{
props: {
labelWidth: "0px"
},
component: (
<div>
<i></i>
<span>如无邀请码请联系客服icssoa</span>
</div>
)
},
{
props: {
labelWidth: "0px"
},
prop: "code",
component: {
name: "login-invite-code",
data() {
return {
list: ["", "", "", ""]
};
},
methods: {
onInput(i) {
if (this.list[i] && i <= 4 - i) {
this.$refs[`input-${i + 1}`].focus();
}
this.$emit("input", this.list.join(""));
},
nativeOnInput(e, i) {
if (e.code == "Backspace") {
if (!this.list[i]) {
if (i - 1 >= 0) {
this.$refs[`input-${i - 1}`].focus();
}
}
}
this.$emit("input", this.list.join(""));
}
},
mounted() {
this.$refs[`input-0`].focus();
},
render() {
return (
<div class="invite-code">
{this.list.map((e, i) => {
return (
<el-input
maxlength="1"
ref={`input-${i}`}
{...{
on: {
input: () => {
this.onInput(i);
}
},
nativeOn: {
keydown: e => {
this.nativeOnInput(e, i);
}
}
}}
v-model={this.list[i]}></el-input>
);
})}
</div>
);
}
}
}
],
on: {
submit: (data, done) => {
this.$message.success(data.code);
done();
}
}
});
}
}
};
</script>
<style lang="scss">
.invite-code {
display: flex;
.el-input {
flex: 1;
margin: 0 15px;
input {
border: 0;
border-radius: 0;
border-bottom: 1px solid #000;
text-align: center;
font-size: 18px;
}
}
}
</style>

View File

@ -30,15 +30,15 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from "vue"; import { defineComponent } from "vue";
import { CrudLoad } from "@/crud/types"; import { CrudLoad } from "/@/crud/types";
import { TestService } from "../utils/service"; import { TestService } from "../utils/service";
import Dialog from "./crud/dialog.vue"; import Dialog from "../components/crud/dialog.vue";
import ContextMenu from "./crud/context-menu.vue"; import ContextMenu from "../components/crud/context-menu.vue";
import Query from "./crud/query.vue"; import Query from "../components/crud/query.vue";
import AdvSearch from "./crud/adv-search.vue"; import AdvSearch from "../components/crud/adv-search.vue";
import Table from "./crud/table.vue"; import Table from "../components/crud/table.vue";
import Upsert from "./crud/upsert.vue"; import Upsert from "../components/crud/upsert.vue";
import Form from "./crud/form.vue"; import Form from "../components/crud/form.vue";
export default defineComponent({ export default defineComponent({
name: "crud", name: "crud",
@ -50,7 +50,7 @@ export default defineComponent({
"demo-adv-search": AdvSearch, "demo-adv-search": AdvSearch,
"demo-table": Table, "demo-table": Table,
"demo-upsert": Upsert, "demo-upsert": Upsert,
"demo-form": Form "demo-form": Form,
}, },
setup() { setup() {
@ -60,9 +60,9 @@ export default defineComponent({
} }
return { return {
onLoad onLoad,
}; };
} },
}); });
</script> </script>

View File

@ -1,22 +1,28 @@
<template> <template>
<div class="demo scroller1"> <div class="demo scroller1">
<el-row :gutter="10"> <el-row :gutter="10">
<el-col v-for="(item, index) in list" :key="index" :xs="24" :sm="12" :md="8" :lg="6"> <el-col
v-for="(item, index) in list"
:key="index"
:xs="24"
:sm="12"
:md="8"
:lg="6"
>
<component :is="item"></component> <component :is="item"></component>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
</template> </template>
<script> <script lang="ts">
import BClUpload from "./components/b-cl-upload"; import BClUpload from "../components/demo/b-cl-upload.vue";
import BVCopy from "./components/b-v-copy"; import BVCopy from "../components/demo/b-v-copy.vue";
import BIconSvg from "./components/b-icon-svg"; import BIconSvg from "../components/demo/b-icon-svg.vue";
import BClCrud from "./components/b-cl-crud"; import BClCrud from "../components/demo/b-cl-crud.vue";
import BClForm from "./components/b-cl-form"; import BClContextMenu from "../components/demo/b-cl-context-menu.vue";
import BClContextMenu from "./components/b-cl-context-menu"; import BErrorPage from "../components/demo/b-error-page.vue";
import BErrorPage from "./components/b-error-page"; import BClEditorQuill from "../components/demo/b-cl-editor-quill.vue";
import BClEditorQuill from "./components/b-cl-editor-quill";
export default { export default {
name: "demo", name: "demo",
@ -26,26 +32,24 @@ export default {
BVCopy, BVCopy,
BIconSvg, BIconSvg,
BClCrud, BClCrud,
BClForm,
BClContextMenu, BClContextMenu,
BErrorPage, BErrorPage,
BClEditorQuill BClEditorQuill,
}, },
data() { setup() {
return { return {
list: [ list: [
"b-cl-upload", "b-cl-upload",
"b-cl-crud", "b-cl-crud",
"b-icon-svg", "b-icon-svg",
"b-v-copy", "b-v-copy",
"b-cl-form",
"b-cl-context-menu", "b-cl-context-menu",
"b-error-page", "b-error-page",
"b-cl-editor-quill" "b-cl-editor-quill",
] ],
}; };
} },
}; };
</script> </script>

View File

@ -2,7 +2,9 @@
<div class="vue-cron"> <div class="vue-cron">
<el-tabs type="border-card"> <el-tabs type="border-card">
<el-tab-pane> <el-tab-pane>
<template #label> <i class="el-icon-date"></i> {{ text.Seconds.name }} </template> <template #label>
<i class="el-icon-date"></i> {{ text.Seconds.name }}
</template>
<div class="vue-cron__item"> <div class="vue-cron__item">
<el-row> <el-row>
<el-radio v-model="second.cronEvery" label="1">{{ <el-radio v-model="second.cronEvery" label="1">{{
@ -29,12 +31,22 @@
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio class="long" v-model="second.cronEvery" label="3" <el-radio
class="long"
v-model="second.cronEvery"
label="3"
>{{ text.Seconds.specific }} >{{ text.Seconds.specific }}
<el-select size="small" multiple v-model="second.specificSpecific"> <el-select
<el-option v-for="val in 60" :key="val" :value="val - 1">{{ size="small"
val - 1 multiple
}}</el-option> v-model="second.specificSpecific"
>
<el-option
v-for="val in 60"
:key="val"
:value="val - 1"
>{{ val - 1 }}</el-option
>
</el-select> </el-select>
</el-radio> </el-radio>
</el-row> </el-row>
@ -90,12 +102,22 @@
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio class="long" v-model="minute.cronEvery" label="3" <el-radio
class="long"
v-model="minute.cronEvery"
label="3"
>{{ text.Minutes.specific }} >{{ text.Minutes.specific }}
<el-select size="small" multiple v-model="minute.specificSpecific"> <el-select
<el-option v-for="val in 60" :key="val" :value="val - 1">{{ size="small"
val - 1 multiple
}}</el-option> v-model="minute.specificSpecific"
>
<el-option
v-for="val in 60"
:key="val"
:value="val - 1"
>{{ val - 1 }}</el-option
>
</el-select> </el-select>
</el-radio> </el-radio>
</el-row> </el-row>
@ -121,7 +143,9 @@
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane> <el-tab-pane>
<template #label> <i class="el-icon-date"></i> {{ text.Hours.name }} </template> <template #label>
<i class="el-icon-date"></i> {{ text.Hours.name }}
</template>
<div class="vue-cron__item"> <div class="vue-cron__item">
<el-row> <el-row>
<el-radio v-model="hour.cronEvery" label="1">{{ <el-radio v-model="hour.cronEvery" label="1">{{
@ -148,12 +172,22 @@
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio class="long" v-model="hour.cronEvery" label="3" <el-radio
class="long"
v-model="hour.cronEvery"
label="3"
>{{ text.Hours.specific }} >{{ text.Hours.specific }}
<el-select size="small" multiple v-model="hour.specificSpecific"> <el-select
<el-option v-for="val in 24" :key="val" :value="val - 1">{{ size="small"
val - 1 multiple
}}</el-option> v-model="hour.specificSpecific"
>
<el-option
v-for="val in 24"
:key="val"
:value="val - 1"
>{{ val - 1 }}</el-option
>
</el-select> </el-select>
</el-radio> </el-radio>
</el-row> </el-row>
@ -179,10 +213,14 @@
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane> <el-tab-pane>
<template #label> <i class="el-icon-date"></i> {{ text.Day.name }} </template> <template #label>
<i class="el-icon-date"></i> {{ text.Day.name }}
</template>
<div class="vue-cron__item"> <div class="vue-cron__item">
<el-row> <el-row>
<el-radio v-model="day.cronEvery" label="1">{{ text.Day.every }}</el-radio> <el-radio v-model="day.cronEvery" label="1">{{
text.Day.every
}}</el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio v-model="day.cronEvery" label="2" <el-radio v-model="day.cronEvery" label="2"
@ -194,7 +232,10 @@
:max="7" :max="7"
></el-input-number> ></el-input-number>
{{ text.Day.intervalWeek[1] }} {{ text.Day.intervalWeek[1] }}
<el-select size="small" v-model="week.incrementStart"> <el-select
size="small"
v-model="week.incrementStart"
>
<el-option <el-option
v-for="val in 7" v-for="val in 7"
:key="val" :key="val"
@ -227,13 +268,25 @@
<el-row> <el-row>
<el-radio class="long" v-model="day.cronEvery" label="4" <el-radio class="long" v-model="day.cronEvery" label="4"
>{{ text.Day.specificWeek }} >{{ text.Day.specificWeek }}
<el-select size="small" multiple v-model="week.specificSpecific"> <el-select
size="small"
multiple
v-model="week.specificSpecific"
>
<el-option <el-option
v-for="val in 7" v-for="val in 7"
:key="val" :key="val"
:label="text.Week[val - 1]" :label="text.Week[val - 1]"
:value=" :value="
['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'][val - 1] [
'SUN',
'MON',
'TUE',
'WED',
'THU',
'FRI',
'SAT',
][val - 1]
" "
></el-option> ></el-option>
</el-select> </el-select>
@ -242,10 +295,17 @@
<el-row> <el-row>
<el-radio class="long" v-model="day.cronEvery" label="5" <el-radio class="long" v-model="day.cronEvery" label="5"
>{{ text.Day.specificDay }} >{{ text.Day.specificDay }}
<el-select size="small" multiple v-model="day.specificSpecific"> <el-select
<el-option v-for="val in 31" :key="val" :value="val">{{ size="small"
val multiple
}}</el-option> v-model="day.specificSpecific"
>
<el-option
v-for="val in 31"
:key="val"
:value="val"
>{{ val }}</el-option
>
</el-select> </el-select>
</el-radio> </el-radio>
</el-row> </el-row>
@ -262,7 +322,10 @@
<el-row> <el-row>
<el-radio v-model="day.cronEvery" label="8" <el-radio v-model="day.cronEvery" label="8"
>{{ text.Day.lastWeek[0] }} >{{ text.Day.lastWeek[0] }}
<el-select size="small" v-model="day.cronLastSpecificDomDay"> <el-select
size="small"
v-model="day.cronLastSpecificDomDay"
>
<el-option <el-option
v-for="val in 7" v-for="val in 7"
:key="val" :key="val"
@ -352,9 +415,16 @@
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio class="long" v-model="month.cronEvery" label="3" <el-radio
class="long"
v-model="month.cronEvery"
label="3"
>{{ text.Month.specific }} >{{ text.Month.specific }}
<el-select size="small" multiple v-model="month.specificSpecific"> <el-select
size="small"
multiple
v-model="month.specificSpecific"
>
<el-option <el-option
v-for="val in 12" v-for="val in 12"
:key="val" :key="val"
@ -385,7 +455,9 @@
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="showYear || false"> <el-tab-pane v-if="showYear || false">
<template #label> <i class="el-icon-date"></i> {{ text.Year.name }} </template> <template #label>
<i class="el-icon-date"></i> {{ text.Year.name }}
</template>
<div class="vue-cron__item"> <div class="vue-cron__item">
<el-row> <el-row>
<el-radio v-model="year.cronEvery" label="1">{{ <el-radio v-model="year.cronEvery" label="1">{{
@ -411,7 +483,10 @@
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio class="long" v-model="year.cronEvery" label="3" <el-radio
class="long"
v-model="year.cronEvery"
label="3"
>{{ text.Year.specific }} >{{ text.Year.specific }}
<el-select <el-select
size="small" size="small"
@ -466,9 +541,9 @@ export default {
props: { props: {
modelValue: { modelValue: {
type: String, type: String,
default: "" default: "",
}, },
showYear: Boolean showYear: Boolean,
}, },
emits: ["update:modelValue", "change", "close"], emits: ["update:modelValue", "change", "close"],
@ -481,7 +556,7 @@ export default {
incrementIncrement: 5, incrementIncrement: 5,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [] specificSpecific: [],
}, },
minute: { minute: {
cronEvery: "", cronEvery: "",
@ -489,7 +564,7 @@ export default {
incrementIncrement: 5, incrementIncrement: 5,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [] specificSpecific: [],
}, },
hour: { hour: {
cronEvery: "", cronEvery: "",
@ -497,7 +572,7 @@ export default {
incrementIncrement: 5, incrementIncrement: 5,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [] specificSpecific: [],
}, },
day: { day: {
cronEvery: "", cronEvery: "",
@ -508,7 +583,7 @@ export default {
specificSpecific: [], specificSpecific: [],
cronLastSpecificDomDay: 1, cronLastSpecificDomDay: 1,
cronDaysBeforeEomMinus: "", cronDaysBeforeEomMinus: "",
cronDaysNearestWeekday: "" cronDaysNearestWeekday: "",
}, },
week: { week: {
cronEvery: "", cronEvery: "",
@ -516,7 +591,7 @@ export default {
incrementIncrement: 1, incrementIncrement: 1,
specificSpecific: [], specificSpecific: [],
cronNthDayDay: 1, cronNthDayDay: 1,
cronNthDayNth: 1 cronNthDayNth: 1,
}, },
month: { month: {
cronEvery: "", cronEvery: "",
@ -524,7 +599,7 @@ export default {
incrementIncrement: 5, incrementIncrement: 5,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [] specificSpecific: [],
}, },
year: { year: {
cronEvery: "", cronEvery: "",
@ -532,7 +607,7 @@ export default {
incrementIncrement: 1, incrementIncrement: 1,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [] specificSpecific: [],
}, },
output: { output: {
second: "", second: "",
@ -541,15 +616,15 @@ export default {
day: "", day: "",
month: "", month: "",
Week: "", Week: "",
year: "" year: "",
} },
}; };
}, },
watch: { watch: {
data() { data() {
this.rest(this.$data); this.rest(this.$data);
} },
}, },
computed: { computed: {
@ -564,16 +639,20 @@ export default {
seconds = "*"; seconds = "*";
break; break;
case "2": case "2":
seconds = this.second.incrementStart + "/" + this.second.incrementIncrement; seconds =
this.second.incrementStart +
"/" +
this.second.incrementIncrement;
break; break;
case "3": case "3":
this.second.specificSpecific.forEach(val => { this.second.specificSpecific.forEach((val) => {
seconds += val + ","; seconds += val + ",";
}); });
seconds = seconds.slice(0, -1); seconds = seconds.slice(0, -1);
break; break;
case "4": case "4":
seconds = this.second.rangeStart + "-" + this.second.rangeEnd; seconds =
this.second.rangeStart + "-" + this.second.rangeEnd;
break; break;
} }
return seconds; return seconds;
@ -586,16 +665,20 @@ export default {
minutes = "*"; minutes = "*";
break; break;
case "2": case "2":
minutes = this.minute.incrementStart + "/" + this.minute.incrementIncrement; minutes =
this.minute.incrementStart +
"/" +
this.minute.incrementIncrement;
break; break;
case "3": case "3":
this.minute.specificSpecific.forEach(val => { this.minute.specificSpecific.forEach((val) => {
minutes += val + ","; minutes += val + ",";
}); });
minutes = minutes.slice(0, -1); minutes = minutes.slice(0, -1);
break; break;
case "4": case "4":
minutes = this.minute.rangeStart + "-" + this.minute.rangeEnd; minutes =
this.minute.rangeStart + "-" + this.minute.rangeEnd;
break; break;
} }
return minutes; return minutes;
@ -608,10 +691,13 @@ export default {
hours = "*"; hours = "*";
break; break;
case "2": case "2":
hours = this.hour.incrementStart + "/" + this.hour.incrementIncrement; hours =
this.hour.incrementStart +
"/" +
this.hour.incrementIncrement;
break; break;
case "3": case "3":
this.hour.specificSpecific.forEach(val => { this.hour.specificSpecific.forEach((val) => {
hours += val + ","; hours += val + ",";
}); });
hours = hours.slice(0, -1); hours = hours.slice(0, -1);
@ -634,10 +720,13 @@ export default {
days = "?"; days = "?";
break; break;
case "3": case "3":
days = this.day.incrementStart + "/" + this.day.incrementIncrement; days =
this.day.incrementStart +
"/" +
this.day.incrementIncrement;
break; break;
case "5": case "5":
this.day.specificSpecific.forEach(val => { this.day.specificSpecific.forEach((val) => {
days += val + ","; days += val + ",";
}); });
days = days.slice(0, -1); days = days.slice(0, -1);
@ -670,10 +759,13 @@ export default {
weeks = "?"; weeks = "?";
break; break;
case "2": case "2":
weeks = this.week.incrementStart + "/" + this.week.incrementIncrement; weeks =
this.week.incrementStart +
"/" +
this.week.incrementIncrement;
break; break;
case "4": case "4":
this.week.specificSpecific.forEach(val => { this.week.specificSpecific.forEach((val) => {
weeks += val + ","; weeks += val + ",";
}); });
weeks = weeks.slice(0, -1); weeks = weeks.slice(0, -1);
@ -686,7 +778,8 @@ export default {
weeks = "?"; weeks = "?";
break; break;
case "11": case "11":
weeks = this.week.cronNthDayDay + "#" + this.week.cronNthDayNth; weeks =
this.week.cronNthDayDay + "#" + this.week.cronNthDayNth;
break; break;
} }
return weeks; return weeks;
@ -699,10 +792,13 @@ export default {
months = "*"; months = "*";
break; break;
case "2": case "2":
months = this.month.incrementStart + "/" + this.month.incrementIncrement; months =
this.month.incrementStart +
"/" +
this.month.incrementIncrement;
break; break;
case "3": case "3":
this.month.specificSpecific.forEach(val => { this.month.specificSpecific.forEach((val) => {
months += val + ","; months += val + ",";
}); });
months = months.slice(0, -1); months = months.slice(0, -1);
@ -721,10 +817,13 @@ export default {
years = "*"; years = "*";
break; break;
case "2": case "2":
years = this.year.incrementStart + "/" + this.year.incrementIncrement; years =
this.year.incrementStart +
"/" +
this.year.incrementIncrement;
break; break;
case "3": case "3":
this.year.specificSpecific.forEach(val => { this.year.specificSpecific.forEach((val) => {
years += val + ","; years += val + ",";
}); });
years = years.slice(0, -1); years = years.slice(0, -1);
@ -736,11 +835,12 @@ export default {
return years; return years;
}, },
cron() { cron() {
return `${this.secondsText || "*"} ${this.minutesText || "*"} ${this.hoursText || return `${this.secondsText || "*"} ${this.minutesText || "*"} ${
"*"} ${this.daysText || "*"} ${this.monthsText || "*"} ${this.weeksText || "?"} ${ this.hoursText || "*"
this.showYear ? this.yearsText || "*" : "" } ${this.daysText || "*"} ${this.monthsText || "*"} ${
}`; this.weeksText || "?"
} } ${this.showYear ? this.yearsText || "*" : ""}`;
},
}, },
methods: { methods: {
@ -769,8 +869,8 @@ export default {
} }
} }
} }
} },
} },
}; };
</script> </script>

View File

@ -1,4 +1,4 @@
import { BaseService, Service, Permission } from "@/core"; import { BaseService, Service, Permission } from "/@/core";
@Service("task/info") @Service("task/info")
class SysTask extends BaseService { class SysTask extends BaseService {

View File

@ -217,10 +217,10 @@
import { computed, defineComponent, inject, onMounted, reactive } from "vue"; import { computed, defineComponent, inject, onMounted, reactive } from "vue";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import Draggable from "vuedraggable"; import Draggable from "vuedraggable";
import { checkPerm } from "@/cool/modules/base"; import { checkPerm } from "/@/cool/modules/base";
import { ContextMenu } from "@/crud"; import { ContextMenu } from "/@/crud";
import Cron from "../components/cron"; import Cron from "../components/cron";
import { useRefs } from "@/core"; import { useRefs } from "/@/core";
export default defineComponent({ export default defineComponent({
name: "task", name: "task",

View File

@ -19,7 +19,7 @@
> >
<li <li
:style="{ :style="{
backgroundColor: item.color backgroundColor: item.color,
}" }"
@click="setTheme(item)" @click="setTheme(item)"
> >
@ -38,15 +38,24 @@
<ul> <ul>
<li v-if="!browser.isMini"> <li v-if="!browser.isMini">
<span>显示一级菜单栏</span> <span>显示一级菜单栏</span>
<el-switch size="mini" v-model="form.conf.showAMenu"></el-switch> <el-switch
size="mini"
v-model="form.conf.showAMenu"
></el-switch>
</li> </li>
<li> <li>
<span>显示路由导航栏</span> <span>显示路由导航栏</span>
<el-switch size="mini" v-model="form.conf.showRouteNav"></el-switch> <el-switch
size="mini"
v-model="form.conf.showRouteNav"
></el-switch>
</li> </li>
<li> <li>
<span>显示页面进程栏</span> <span>显示页面进程栏</span>
<el-switch size="mini" v-model="form.conf.showProcess"></el-switch> <el-switch
size="mini"
v-model="form.conf.showProcess"
></el-switch>
</li> </li>
</ul> </ul>
</div> </div>
@ -82,7 +91,7 @@
title="修改说明" title="修改说明"
width="800px" width="800px"
:props="{ :props="{
'append-to-body': true 'append-to-body': true,
}" }"
> >
<ul class="cl-theme__desc"> <ul class="cl-theme__desc">
@ -102,50 +111,50 @@
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import { isDev } from "@/config/env"; import { isDev } from "/@/config/env";
import { isArray, cloneDeep } from "@/core/utils"; import { isArray, cloneDeep } from "/@/core/utils";
export default { export default {
name: "cl-theme", name: "cl-theme",
props: { props: {
list: Array list: Array,
}, },
data() { data() {
return { return {
drawer: { drawer: {
visible: false visible: false,
}, },
desc: { desc: {
visible: false, visible: false,
color: "", color: "",
conf: "" conf: "",
}, },
themes: [ themes: [
{ {
label: "钴蓝", label: "钴蓝",
name: "blue", name: "blue",
color: "#4165d7" color: "#4165d7",
}, },
{ {
label: "极黑", label: "极黑",
name: "black", name: "black",
color: "#2f3447" color: "#2f3447",
}, },
{ {
label: "果绿", label: "果绿",
name: "green", name: "green",
color: "#51C21A" color: "#51C21A",
}, },
{ {
label: "酱紫", label: "酱紫",
name: "purple", name: "purple",
color: "#d0378d" color: "#d0378d",
} },
], ],
isDev, isDev,
form: {} form: {},
}; };
}, },
@ -154,7 +163,7 @@ export default {
themeList() { themeList() {
return isArray(this.list) ? this.list : this.themes; return isArray(this.list) ? this.list : this.themes;
} },
}, },
watch: { watch: {
@ -163,15 +172,15 @@ export default {
immediate: true, immediate: true,
handler(val) { handler(val) {
this.form = cloneDeep(val); this.form = cloneDeep(val);
} },
}, },
form: { form: {
deep: true, deep: true,
handler(val) { handler(val) {
this.$store.commit("UPDATE_APP", val); this.$store.commit("UPDATE_APP", val);
} },
} },
}, },
methods: { methods: {
@ -194,7 +203,9 @@ export default {
const theme = document.getElementById("theme-style"); const theme = document.getElementById("theme-style");
const style = theme || document.createElement("link"); const style = theme || document.createElement("link");
style.href = `${this.modules.theme.options.sourceUrl || "/theme/"}${name}.css`; style.href = `${
this.modules.theme.options.sourceUrl || "/theme/"
}${name}.css`;
if (!theme) { if (!theme) {
style.type = "text/css"; style.type = "text/css";
@ -212,7 +223,9 @@ export default {
this.form.theme.url = style.href; this.form.theme.url = style.href;
// css // css
document.getElementsByTagName("body")[0].style.setProperty("--color-primary", color); document
.getElementsByTagName("body")[0]
.style.setProperty("--color-primary", color);
}, },
// //
@ -233,14 +246,14 @@ export default {
} }
} }
`; `;
} },
} },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.cl-theme { .cl-theme {
:deep(.el-drawer) { .el-drawer {
&__header { &__header {
margin-bottom: 20px; margin-bottom: 20px;
} }

View File

@ -6,8 +6,8 @@
`cl-upload--${listType}`, `cl-upload--${listType}`,
{ {
'is-multiple': multiple, 'is-multiple': multiple,
'is-drag': drag 'is-drag': drag,
} },
]" ]"
> >
<el-input class="cl-upload__hidden" type="hidden"></el-input> <el-input class="cl-upload__hidden" type="hidden"></el-input>
@ -27,7 +27,7 @@
:disabled="disabled" :disabled="disabled"
:headers="{ :headers="{
Authorization: token, Authorization: token,
...headers ...headers,
}" }"
:http-request="action ? undefined : httpRequest" :http-request="action ? undefined : httpRequest"
:on-remove="_onRemove" :on-remove="_onRemove"
@ -44,7 +44,9 @@
<!-- 多图上传 --> <!-- 多图上传 -->
<template v-if="listType == 'picture-card'"> <template v-if="listType == 'picture-card'">
<i :class="['cl-upload__icon', _icon]"></i> <i :class="['cl-upload__icon', _icon]"></i>
<span class="cl-upload__text" v-if="_text">{{ _text }}</span> <span class="cl-upload__text" v-if="_text">{{
_text
}}</span>
</template> </template>
<!-- 文件上传 --> <!-- 文件上传 -->
@ -59,7 +61,10 @@
<template v-if="_file"> <template v-if="_file">
<div class="cl-upload__cover"> <div class="cl-upload__cover">
<!-- 图片 --> <!-- 图片 -->
<img v-if="_file.type == 'image'" :src="_file.url" /> <img
v-if="_file.type == 'image'"
:src="_file.url"
/>
<!-- 文件名 --> <!-- 文件名 -->
<span v-else>{{ _file.name }}</span> <span v-else>{{ _file.name }}</span>
@ -87,7 +92,9 @@
<!-- 空态 --> <!-- 空态 -->
<template v-else> <template v-else>
<i :class="['cl-upload__icon', _icon]"></i> <i :class="['cl-upload__icon', _icon]"></i>
<span class="cl-upload__text" v-if="_text">{{ _text }}</span> <span class="cl-upload__text" v-if="_text">{{
_text
}}</span>
</template> </template>
</template> </template>
</slot> </slot>
@ -98,7 +105,7 @@
title="图片预览" title="图片预览"
v-model="preview.visible" v-model="preview.visible"
:props="{ :props="{
width: previewWidth width: previewWidth,
}" }"
> >
<img style="width: 100%" :src="preview.url" alt="" /> <img style="width: 100%" :src="preview.url" alt="" />
@ -108,9 +115,9 @@
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import { last, isArray, isNumber, isBoolean, basename } from "@/core/utils"; import { last, isArray, isNumber, isBoolean, basename } from "/@/core/utils";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import { clone } from "@/core/utils"; import { clone } from "/@/core/utils";
export default { export default {
name: "cl-upload", name: "cl-upload",
@ -126,19 +133,19 @@ export default {
// uuid // uuid
rename: { rename: {
type: Boolean, type: Boolean,
default: undefined default: undefined,
}, },
// (MB) // (MB)
limitSize: Number, limitSize: Number,
// //
previewWidth: { previewWidth: {
type: String, type: String,
default: "500px" default: "500px",
}, },
// //
action: { action: {
type: String, type: String,
default: "" default: "",
}, },
// //
headers: Object, headers: Object,
@ -153,7 +160,7 @@ export default {
// //
showFileList: { showFileList: {
type: Boolean, type: Boolean,
default: undefined default: undefined,
}, },
// //
drag: Boolean, drag: Boolean,
@ -162,12 +169,12 @@ export default {
// //
listType: { listType: {
type: String, type: String,
default: "default" default: "default",
}, },
// //
autoUpload: { autoUpload: {
type: Boolean, type: Boolean,
default: true default: true,
}, },
// //
disabled: Boolean, disabled: Boolean,
@ -190,7 +197,7 @@ export default {
// //
beforeUpload: Function, beforeUpload: Function,
// //
beforeRemove: Function beforeRemove: Function,
}, },
emits: ["update:modelValue", "change"], emits: ["update:modelValue", "change"],
@ -202,8 +209,8 @@ export default {
loading: false, loading: false,
preview: { preview: {
visible: false, visible: false,
url: null url: null,
} },
}; };
}, },
@ -271,12 +278,12 @@ export default {
_urls() { _urls() {
const format = { const format = {
image: ["bmp", "jpg", "jpeg", "png", "tif", "gif", "svg"] image: ["bmp", "jpg", "jpeg", "png", "tif", "gif", "svg"],
}; };
return this.urls return this.urls
.filter(e => Boolean(e.url)) .filter((e) => Boolean(e.url))
.map(e => { .map((e) => {
const arr = e.url.split("."); const arr = e.url.split(".");
const suf = last(arr); const suf = last(arr);
e.type = format.image.includes(suf) ? "image" : null; e.type = format.image.includes(suf) ? "image" : null;
@ -297,24 +304,26 @@ export default {
arr = [this._size, this._size]; arr = [this._size, this._size];
} }
const [height, width] = arr.map(e => (isNumber(e) ? `${e}px` : e)); const [height, width] = arr.map((e) =>
isNumber(e) ? `${e}px` : e
);
if (this.listType == "default" && !this.drag) { if (this.listType == "default" && !this.drag) {
return { return {
height, height,
width width,
}; };
} else { } else {
return {}; return {};
} }
} },
}, },
watch: { watch: {
modelValue: { modelValue: {
immediate: true, immediate: true,
handler: "parseValue" handler: "parseValue",
} },
}, },
methods: { methods: {
@ -336,15 +345,15 @@ export default {
// //
if ( if (
!this.urls.some(e => { !this.urls.some((e) => {
return list.includes(e.url); return list.includes(e.url);
}) })
) { ) {
this.fileList = list.filter(Boolean).map(url => { this.fileList = list.filter(Boolean).map((url) => {
return { return {
url, url,
name: basename(url), name: basename(url),
uid: url uid: url,
}; };
}); });
@ -356,8 +365,8 @@ export default {
// //
update() { update() {
const urls = this.urls const urls = this.urls
.filter(e => Boolean(e.url)) .filter((e) => Boolean(e.url))
.map(e => e.url) .map((e) => e.url)
.join(","); .join(",");
this.$emit("update:modelValue", urls); this.$emit("update:modelValue", urls);
@ -383,7 +392,7 @@ export default {
// //
_onRemove(file) { _onRemove(file) {
this.urls.splice( this.urls.splice(
this.urls.findIndex(e => e.uid === file.uid), this.urls.findIndex((e) => e.uid === file.uid),
1 1
); );
this.update(); this.update();
@ -400,7 +409,7 @@ export default {
this.preview.url = file.url; this.preview.url = file.url;
if (!file.url) { if (!file.url) {
const item = this.urls.find(e => e.uid == file.uid); const item = this.urls.find((e) => e.uid == file.uid);
if (item) { if (item) {
this.preview.url = item.url; this.preview.url = item.url;
@ -414,7 +423,9 @@ export default {
if (this._limitSize) { if (this._limitSize) {
if (file.size / 1024 / 1024 >= this._limitSize) { if (file.size / 1024 / 1024 >= this._limitSize) {
this.$message.error(`上传文件大小不能超过 ${this._limitSize}MB!`); this.$message.error(
`上传文件大小不能超过 ${this._limitSize}MB!`
);
this.done(); this.done();
return false; return false;
} }
@ -422,7 +433,7 @@ export default {
if (this.beforeUpload) { if (this.beforeUpload) {
return this.beforeUpload(file, { return this.beforeUpload(file, {
done: this.done done: this.done,
}); });
} }
@ -436,7 +447,7 @@ export default {
this.append({ this.append({
url: res.data, url: res.data,
name: file.raw.name, name: file.raw.name,
uid: file.raw.uid uid: file.raw.uid,
}); });
// //
@ -450,9 +461,9 @@ export default {
const mode = await this.uploadMode(); const mode = await this.uploadMode();
// //
const upload = file => { const upload = (file) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const next = res => { const next = (res) => {
const data = new FormData(); const data = new FormData();
for (const i in res) { for (const i in res) {
@ -465,7 +476,10 @@ export default {
// uuid // uuid
if (this._rename) { if (this._rename) {
fileName = uuidv4() + "." + last((file.name || "").split(".")); fileName =
uuidv4() +
"." +
last((file.name || "").split("."));
} }
data.append("key", `app/${fileName}`); data.append("key", `app/${fileName}`);
@ -477,36 +491,38 @@ export default {
url: res.host, url: res.host,
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "multipart/form-data" "Content-Type": "multipart/form-data",
}, },
data, data,
onUploadProgress: e => { onUploadProgress: (e) => {
if (this.onProgress) { if (this.onProgress) {
e.percent = parseInt((e.loaded / e.total) * 100); e.percent = parseInt(
(e.loaded / e.total) * 100
);
this.onProgress(e, req.file); this.onProgress(e, req.file);
} }
} },
}) })
.then(url => { .then((url) => {
if (mode === "local") { if (mode === "local") {
resolve(url); resolve(url);
} else { } else {
resolve(`${res.host}/app/${fileName}`); resolve(`${res.host}/app/${fileName}`);
} }
}) })
.catch(err => { .catch((err) => {
reject(err); reject(err);
}); });
}; };
if (mode == "local") { if (mode == "local") {
next({ next({
host: "/upload" host: "/upload",
}); });
} else { } else {
this.$service.common this.$service.common
.upload() .upload()
.then(res => { .then((res) => {
next(res); next(res);
}) })
.catch(reject); .catch(reject);
@ -517,10 +533,10 @@ export default {
this.loading = true; this.loading = true;
upload(req.file) upload(req.file)
.then(url => { .then((url) => {
this._onSuccess({ data: url }, { raw: req.file }); this._onSuccess({ data: url }, { raw: req.file });
}) })
.catch(err => { .catch((err) => {
console.error("upload error", err); console.error("upload error", err);
this.$message.error(err); this.$message.error(err);
@ -536,9 +552,9 @@ export default {
// //
uploadMode() { uploadMode() {
return this.$service.common.uploadMode().then(res => res.mode); return this.$service.common.uploadMode().then((res) => res.mode);
} },
} },
}; };
</script> </script>

View File

@ -34,7 +34,7 @@
<script> <script>
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
import { isEmpty } from "@/core/utils"; import { isEmpty } from "/@/core/utils";
export default { export default {
name: "cl-upload-space-category", name: "cl-upload-space-category",

View File

@ -1,7 +1,9 @@
<template> <template>
<div class="cl-upload-space__wrap"> <div class="cl-upload-space__wrap">
<slot> <slot>
<el-button v-if="showButton" size="mini" @click="open">点击上传</el-button> <el-button v-if="showButton" size="mini" @click="open"
>点击上传</el-button
>
</slot> </slot>
<!-- 弹框 --> <!-- 弹框 -->
@ -14,7 +16,7 @@
:props="{ :props="{
'close-on-click-modal': false, 'close-on-click-modal': false,
'append-to-body': true, 'append-to-body': true,
customClass: 'dialog-upload-space' customClass: 'dialog-upload-space',
}" }"
:controls="['slot-expand', 'cl-flex1', 'fullscreen', 'close']" :controls="['slot-expand', 'cl-flex1', 'fullscreen', 'close']"
> >
@ -26,7 +28,9 @@
<div class="cl-upload-space__content"> <div class="cl-upload-space__content">
<!-- 操作栏 --> <!-- 操作栏 -->
<div class="cl-upload-space__header scroller1"> <div class="cl-upload-space__header scroller1">
<el-button size="mini" @click="refresh()">刷新</el-button> <el-button size="mini" @click="refresh()"
>刷新</el-button
>
<cl-upload <cl-upload
style="margin: 0 10px" style="margin: 0 10px"
@ -44,7 +48,9 @@
:on-progress="onProgress" :on-progress="onProgress"
:before-upload="beforeUpload" :before-upload="beforeUpload"
> >
<el-button size="mini" type="primary">点击上传</el-button> <el-button size="mini" type="primary"
>点击上传</el-button
>
</cl-upload> </cl-upload>
<el-button <el-button
@ -117,7 +123,7 @@
:current-page="pagination.page" :current-page="pagination.page"
:total="pagination.total" :total="pagination.total"
@current-change=" @current-change="
page => { (page) => {
refresh({ page }); refresh({ page });
} }
" "
@ -134,7 +140,11 @@
v-if="category.visible" v-if="category.visible"
@click="category.visible = false" @click="category.visible = false"
></i> ></i>
<i class="el-icon-arrow-left" v-else @click="category.visible = true"></i> <i
class="el-icon-arrow-left"
v-else
@click="category.visible = true"
></i>
</button> </button>
</template> </template>
</cl-dialog> </cl-dialog>
@ -142,9 +152,9 @@
</template> </template>
<script> <script>
import { isEmpty } from "@/core/utils"; import { isEmpty } from "/@/core/utils";
import Category from "./category"; import Category from "./category.vue";
import FileItem from "./file-item"; import FileItem from "./file-item.vue";
import { mapGetters } from "vuex"; import { mapGetters } from "vuex";
export default { export default {
@ -156,12 +166,12 @@ export default {
// //
limit: { limit: {
type: Number, type: Number,
default: 9 default: 9,
}, },
// (MB) // (MB)
limitSize: { limitSize: {
type: Number, type: Number,
default: 10 default: 10,
}, },
// //
disabled: Boolean, disabled: Boolean,
@ -178,18 +188,18 @@ export default {
// //
showButton: { showButton: {
type: Boolean, type: Boolean,
default: true default: true,
} },
}, },
components: { components: {
Category, Category,
FileItem FileItem,
}, },
provide() { provide() {
return { return {
space: this space: this,
}; };
}, },
@ -199,15 +209,15 @@ export default {
loading: false, loading: false,
category: { category: {
id: null, id: null,
visible: true visible: true,
}, },
selection: [], selection: [],
list: [], list: [],
pagination: { pagination: {
page: 1, page: 1,
size: 12, size: 12,
total: 0 total: 0,
} },
}; };
}, },
@ -220,7 +230,7 @@ export default {
isSelected() { isSelected() {
return !isEmpty(this.selection); return !isEmpty(this.selection);
} },
}, },
watch: { watch: {
@ -228,8 +238,8 @@ export default {
immediate: true, immediate: true,
handler(val) { handler(val) {
this.category.visible = val ? false : true; this.category.visible = val ? false : true;
} },
} },
}, },
methods: { methods: {
@ -248,7 +258,7 @@ export default {
// //
onSuccess(res, file) { onSuccess(res, file) {
const item = this.list.find(e => file.uid == e.uid); const item = this.list.find((e) => file.uid == e.uid);
if (item) { if (item) {
item.url = res.data; item.url = res.data;
@ -257,13 +267,13 @@ export default {
.add({ .add({
url: res.data, url: res.data,
type: item.type, type: item.type,
classifyId: item.classifyId classifyId: item.classifyId,
}) })
.then(res => { .then((res) => {
item.loading = false; item.loading = false;
item.id = res.id; item.id = res.id;
}) })
.catch(err => { .catch((err) => {
this.$message.error(err); this.$message.error(err);
}); });
} }
@ -271,7 +281,7 @@ export default {
// //
onError(err, file) { onError(err, file) {
const item = this.list.find(e => file.uid == e.uid); const item = this.list.find((e) => file.uid == e.uid);
if (item) { if (item) {
item.loading = false; item.loading = false;
@ -287,7 +297,7 @@ export default {
uid, uid,
classifyId: this.category.id, classifyId: this.category.id,
loading: true, loading: true,
progress: "0%" progress: "0%",
}); });
}, },
@ -312,12 +322,12 @@ export default {
...this.pagination, ...this.pagination,
...params, ...params,
classifyId: this.category.id, classifyId: this.category.id,
type: this.accept type: this.accept,
}) })
.then(res => { .then((res) => {
this.pagination = res.pagination; this.pagination = res.pagination;
this.list = res.list.map(e => { this.list = res.list.map((e) => {
e.loading = false; e.loading = false;
return e; return e;
}); });
@ -329,7 +339,7 @@ export default {
// //
confirm() { confirm() {
const urls = this.selection.map(e => e.url).join(","); const urls = this.selection.map((e) => e.url).join(",");
this.$emit("update:modelValue", urls); this.$emit("update:modelValue", urls);
this.$emit("confirm", this.detailData ? this.selection : urls); this.$emit("confirm", this.detailData ? this.selection : urls);
@ -339,7 +349,7 @@ export default {
// //
select(item) { select(item) {
const index = this.selection.findIndex(e => e.id === item.id); const index = this.selection.findIndex((e) => e.id === item.id);
if (index >= 0) { if (index >= 0) {
this.selection.splice(index, 1); this.selection.splice(index, 1);
@ -357,18 +367,18 @@ export default {
} }
// id // id
const ids = selection.map(e => e.id); const ids = selection.map((e) => e.id);
this.$confirm("此操作将删除文件, 是否继续?", "提示", { this.$confirm("此操作将删除文件, 是否继续?", "提示", {
type: "warning" type: "warning",
}) })
.then(() => { .then(() => {
this.$message.success("删除成功"); this.$message.success("删除成功");
// //
ids.forEach(id => { ids.forEach((id) => {
[this.list, this.selection].forEach(list => { [this.list, this.selection].forEach((list) => {
const index = list.findIndex(e => e.id === id); const index = list.findIndex((e) => e.id === id);
list.splice(index, 1); list.splice(index, 1);
}); });
}); });
@ -376,15 +386,15 @@ export default {
// //
this.$service.space.info this.$service.space.info
.delete({ .delete({
ids ids,
}) })
.catch(err => { .catch((err) => {
this.$message.error(err); this.$message.error(err);
}); });
}) })
.catch(() => null); .catch(() => null);
} },
} },
}; };
</script> </script>
@ -396,9 +406,7 @@ export default {
} }
} }
} }
</style>
<style lang="scss" scoped>
.cl-upload-space { .cl-upload-space {
display: flex; display: flex;
height: 100%; height: 100%;
@ -439,7 +447,7 @@ export default {
top: calc(50% - 90px); top: calc(50% - 90px);
left: calc(50% - 160px); left: calc(50% - 160px);
:deep(.cl-upload) { .cl-upload {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;

View File

@ -1,4 +1,4 @@
import { BaseService, Service } from "@/core"; import { BaseService, Service } from "/@/core";
@Service("space/info") @Service("space/info")
class SpaceInfo extends BaseService {} class SpaceInfo extends BaseService {}

View File

@ -1,4 +1,4 @@
import { BaseService, Service } from "@/core"; import { BaseService, Service } from "/@/core";
@Service("space/type") @Service("space/type")
class SpaceType extends BaseService {} class SpaceType extends BaseService {}

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