添加 lint,解决 /@/ 找不到路径问题

This commit is contained in:
icssoa 2021-03-31 16:48:59 +08:00
parent 43d3d9a89a
commit a6b3e9118e
101 changed files with 2701 additions and 1281 deletions

76
.eslintrc.js Normal file
View File

@ -0,0 +1,76 @@
module.exports = {
root: true,
env: {
browser: true,
node: true,
es6: true,
},
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
jsxPragma: 'React',
ecmaFeatures: {
jsx: true,
tsx: true,
},
},
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:prettier/recommended',
],
rules: {
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-function': 'off',
'vue/component-name-in-template-casing': ["error", "kebab-case"],
'vue/component-definition-name-casing': ["error", "kebab-case"],
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^h$',
varsIgnorePattern: '^h$',
},
],
'no-unused-vars': [
'error',
{
argsIgnorePattern: '^h$',
varsIgnorePattern: '^h$',
},
],
'space-before-function-paren': 'off',
'vue/attributes-order': 'off',
'vue/one-component-per-file': 'off',
'vue/html-closing-bracket-newline': 'off',
'vue/max-attributes-per-line': 'off',
'vue/multiline-html-element-content-newline': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/attribute-hyphenation': 'off',
// 'vue/html-self-closing': 'off',
'vue/require-default-prop': 'off',
'vue/html-self-closing': [
'error',
{
html: {
void: 'always',
normal: 'never',
component: 'always',
},
svg: 'always',
math: 'always',
},
],
},
};

9
.prettierrc Normal file
View File

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

View File

@ -34,8 +34,8 @@
"", "",
"<script lang=\"ts\">", "<script lang=\"ts\">",
"import { defineComponent, inject, reactive } from \"vue\";", "import { defineComponent, inject, reactive } from \"vue\";",
"import { CrudLoad, Upsert, Table } from \"@/crud/types\";", "import { CrudLoad, Upsert, Table } from \"/@/crud/types\";",
"import { useRefs } from \"@/core\";", "import { useRefs } from \"/@/core\";",
"", "",
"export default defineComponent({", "export default defineComponent({",
" setup() {", " setup() {",

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"editor.cursorSmoothCaretAnimation": true
}

View File

@ -4,7 +4,9 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vue-tsc --noEmit && vite build", "build": "vue-tsc --noEmit && vite build",
"serve": "vite preview" "serve": "vite preview",
"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
"lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix"
}, },
"dependencies": { "dependencies": {
"array.prototype.flat": "^1.2.4", "array.prototype.flat": "^1.2.4",
@ -32,9 +34,16 @@
"vuex": "^4.0.0-0" "vuex": "^4.0.0-0"
}, },
"devDependencies": { "devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.20.0",
"@vitejs/plugin-vue": "^1.1.5", "@vitejs/plugin-vue": "^1.1.5",
"@vitejs/plugin-vue-jsx": "^1.1.2", "@vitejs/plugin-vue-jsx": "^1.1.2",
"@vue/compiler-sfc": "^3.0.5", "@vue/compiler-sfc": "^3.0.5",
"eslint": "^7.23.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.8.0",
"prettier": "^2.2.1",
"sass": "^1.32.8", "sass": "^1.32.8",
"sass-loader": "^11.0.1", "sass-loader": "^11.0.1",
"svg-sprite-loader": "^6.0.2", "svg-sprite-loader": "^6.0.2",

View File

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

View File

@ -6,8 +6,7 @@ import { MenuItem } from "/@/cool/modules/base/types";
const routerMode = "history"; const routerMode = "history";
// 开发模式 // 开发模式
const isDev: boolean = true; const isDev = import.meta.env.MODE === "development";
// Host // Host
const host = "https://show.cool-admin.com"; const host = "https://show.cool-admin.com";
@ -39,13 +38,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

@ -11,9 +11,7 @@ if (app.theme) {
createLink(url, "theme-style"); createLink(url, "theme-style");
} }
document document.getElementsByTagName("body")[0].style.setProperty("--color-primary", color);
.getElementsByTagName("body")[0]
.style.setProperty("--color-primary", color);
} }
// 字体图标库加载 // 字体图标库加载
@ -27,7 +25,7 @@ if (iconfontUrl) {
const svgFiles = import.meta.globEager("/src/icons/svg/**/*.svg"); const svgFiles = import.meta.globEager("/src/icons/svg/**/*.svg");
function iconList() { function iconList() {
let list: string[] = []; const list: string[] = [];
for (const i in svgFiles) { for (const i in svgFiles) {
list.push(basename(i).replace(".svg", "")); list.push(basename(i).replace(".svg", ""));

View File

@ -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>

View File

@ -1,11 +1,6 @@
<template> <template>
<div class="cl-codemirror" ref="editorRef"> <div ref="editorRef" class="cl-codemirror">
<textarea <textarea id="editor" class="cl-code" :height="height" :width="width"></textarea>
class="cl-code"
id="editor"
:height="height"
:width="width"
></textarea>
</div> </div>
</template> </template>
@ -27,7 +22,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"],
@ -64,18 +59,15 @@ export default defineComponent({
onMounted(function () { onMounted(function () {
nextTick(() => { nextTick(() => {
// //
editor = CodeMirror.fromTextArea( editor = CodeMirror.fromTextArea(editorRef.value.querySelector("#editor"), {
editorRef.value.querySelector("#editor"),
{
mode: "javascript", mode: "javascript",
theme: "ambiance", theme: "ambiance",
styleActiveLine: true, styleActiveLine: true,
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
indentUnit: 4, indentUnit: 4,
...props.options, ...props.options
} });
);
// //
editor.on("change", (e: any) => { editor.on("change", (e: any) => {
@ -105,9 +97,9 @@ export default defineComponent({
}); });
return { return {
editorRef, editorRef
}; };
}, }
}); });
</script> </script>

View File

@ -1,19 +1,18 @@
<template> <template>
<div class="cl-dept-check" v-loading="loading"> <div v-loading="loading" class="cl-dept-check">
<p v-if="title">{{ title }}</p> <p v-if="title">{{ title }}</p>
<div class="cl-dept-check__search"> <div class="cl-dept-check__search">
<el-input placeholder="输入关键字进行过滤" v-model="keyword" size="small"> </el-input> <el-input v-model="keyword" placeholder="输入关键字进行过滤" size="small" />
<el-switch <el-switch
v-model="form.relevance"
:active-value="1" :active-value="1"
:inactive-value="0" :inactive-value="0"
v-model="form.relevance"
@change="onCheckStrictlyChange" @change="onCheckStrictlyChange"
></el-switch />
>是否关联上下级
</div> </div>
<div class="cl-dept-check__tree" v-if="visible"> <div v-if="visible" class="cl-dept-check__tree">
<el-tree <el-tree
ref="treeRef" ref="treeRef"
highlight-current highlight-current
@ -28,8 +27,7 @@
:filter-node-method="filterNode" :filter-node-method="filterNode"
:check-strictly="!form.relevance" :check-strictly="!form.relevance"
@check-change="onCheckChange" @check-change="onCheckChange"
> />
</el-tree>
</div> </div>
</div> </div>
</template> </template>

View File

@ -12,50 +12,41 @@
<li v-if="drag && !isMini"> <li v-if="drag && !isMini">
<el-tooltip content="拖动排序"> <el-tooltip content="拖动排序">
<i <i class="el-icon-s-operation" @click="isDrag = true"></i>
class="el-icon-s-operation"
@click="isDrag = true"
></i>
</el-tooltip> </el-tooltip>
</li> </li>
<li class="no" v-show="isDrag"> <li v-show="isDrag" class="no">
<el-button type="text" size="mini" @click="treeOrder(true)" <el-button type="text" size="mini" @click="treeOrder(true)">保存</el-button>
>保存</el-button <el-button type="text" size="mini" @click="treeOrder(false)">取消</el-button>
>
<el-button type="text" size="mini" @click="treeOrder(false)"
>取消</el-button
>
</li> </li>
</ul> </ul>
</div> </div>
<div class="cl-dept-tree__container" @contextmenu.prevent="openCM"> <div class="cl-dept-tree__container" @contextmenu.prevent="openCM">
<el-tree <el-tree
v-loading="loading"
node-key="id" node-key="id"
highlight-current highlight-current
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"
:allow-drop="allowDrop" :allow-drop="allowDrop"
:expand-on-click-node="false" :expand-on-click-node="false"
v-loading="loading"
@node-contextmenu="openCM" @node-contextmenu="openCM"
> >
<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)">{{
node.label
}}</span>
<span <span
class="cl-dept-tree__node-label"
@click="rowClick(data)"
>{{ node.label }}</span
>
<span
class="cl-dept-tree__node-icon"
v-if="isMini" v-if="isMini"
class="cl-dept-tree__node-icon"
@click="openCM($event, data, node)" @click="openCM($event, data, node)"
> >
<i class="el-icon-more"></i> <i class="el-icon-more"></i>
@ -65,7 +56,7 @@
</el-tree> </el-tree>
</div> </div>
<cl-form :ref="setRefs('form')"></cl-form> <cl-form :ref="setRefs('form')" />
</div> </div>
</template> </template>
@ -82,14 +73,16 @@ 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
}, }
}, },
emits: ["list-change", "row-click", "user-add"],
setup(props, { emit }) { setup(props, { emit }) {
const { refs, setRefs } = useRefs(); const { refs, setRefs } = useRefs();
@ -134,9 +127,7 @@ export default defineComponent({
// ids // ids
function rowClick(e: any) { function rowClick(e: any) {
ContextMenu.close(); ContextMenu.close();
const ids = e.children const ids = e.children ? revDeepTree(e.children).map((e) => e.id) : [];
? 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 });
} }
@ -149,7 +140,7 @@ export default defineComponent({
title: "编辑部门", title: "编辑部门",
width: "550px", width: "550px",
props: { props: {
labelWidth: "100px", labelWidth: "100px"
}, },
items: [ items: [
{ {
@ -159,13 +150,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: "上级部门",
@ -174,9 +165,9 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
disabled: true, disabled: true
}, }
}, }
}, },
{ {
label: "排序", label: "排序",
@ -187,10 +178,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) => {
@ -198,7 +189,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}成功`);
@ -209,8 +200,8 @@ export default defineComponent({
ElMessage.error(err); ElMessage.error(err);
done(); done();
}); });
}, }
}, }
}); });
} }
@ -220,7 +211,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) {
@ -237,16 +228,12 @@ export default defineComponent({
}); });
}; };
ElMessageBox.confirm( ElMessageBox.confirm(`该操作会删除 “${e.name}” 部门的所有用户,是否确认?`, "提示", {
`该操作会删除 “${e.name}” 部门的所有用户,是否确认?`,
"提示",
{
type: "warning", type: "warning",
confirmButtonText: "直接删除", confirmButtonText: "直接删除",
cancelButtonText: "保留用户", cancelButtonText: "保留用户",
distinguishCancelAndClose: true, distinguishCancelAndClose: true
} })
)
.then(() => { .then(() => {
del(true); del(true);
}) })
@ -261,7 +248,7 @@ 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[] = [];
@ -285,7 +272,7 @@ export default defineComponent({
return { return {
id: e.id, id: e.id,
parentId: e.parentId, parentId: e.parentId,
orderNum: i, orderNum: i
}; };
}) })
) )
@ -322,10 +309,10 @@ export default defineComponent({
rowEdit({ rowEdit({
name: "", name: "",
parentName: d.name, parentName: d.name,
parentId: d.id, parentId: d.id
}); });
done(); done();
}, }
}, },
{ {
label: "编辑", label: "编辑",
@ -333,7 +320,7 @@ export default defineComponent({
callback: (_: any, done: Function) => { callback: (_: any, done: Function) => {
rowEdit(d); rowEdit(d);
done(); done();
}, }
}, },
{ {
label: "删除", label: "删除",
@ -342,7 +329,7 @@ export default defineComponent({
callback: (_: any, done: Function) => { callback: (_: any, done: Function) => {
rowDel(d); rowDel(d);
done(); done();
}, }
}, },
{ {
label: "新增成员", label: "新增成员",
@ -350,9 +337,9 @@ export default defineComponent({
callback: (_: any, done: Function) => { callback: (_: any, done: Function) => {
emit("user-add", d); emit("user-add", d);
done(); done();
}, }
}, }
], ]
}); });
} }
@ -374,9 +361,9 @@ export default defineComponent({
rowClick, rowClick,
rowEdit, rowEdit,
rowDel, rowDel,
treeOrder, treeOrder
}; };
}, }
}); });
</script> </script>

View File

@ -7,8 +7,7 @@
detail-data detail-data
:show-button="false" :show-button="false"
@confirm="onUploadSpaceConfirm" @confirm="onUploadSpaceConfirm"
> />
</cl-upload-space>
</div> </div>
</template> </template>
@ -26,7 +25,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,12 +59,7 @@ export default defineComponent({
files.forEach((file, i) => { files.forEach((file, i) => {
const [type] = file.type.split("/"); const [type] = file.type.split("/");
quill.insertEmbed( quill.insertEmbed(cursorIndex.value + i, type, file.url, Quill.sources.USER);
cursorIndex.value + i,
type,
file.url,
Quill.sources.USER
);
}); });
// //
@ -80,16 +74,12 @@ export default defineComponent({
// //
const style = computed<any>(() => { const style = computed<any>(() => {
const height = isNumber(props.height) const height = isNumber(props.height) ? props.height + "px" : props.height;
? props.height + "px" const width = isNumber(props.width) ? props.width + "px" : props.width;
: props.height;
const width = isNumber(props.width)
? props.width + "px"
: props.width;
return { return {
height, height,
width, width
}; };
}); });
@ -127,10 +117,10 @@ export default defineComponent({
[{ font: [] }], [{ font: [] }],
[{ align: [] }], [{ align: [] }],
["clean"], ["clean"],
["link", "image"], ["link", "image"]
], ]
}, },
...props.options, ...props.options
}); });
// //
@ -157,9 +147,9 @@ export default defineComponent({
style, style,
setRefs, setRefs,
setContent, setContent,
onUploadSpaceConfirm, onUploadSpaceConfirm
}; };
}, }
}); });
</script> </script>
@ -259,12 +249,8 @@ export default defineComponent({
content: "衬线字体"; content: "衬线字体";
} }
.ql-snow .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-picker.ql-font .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
.ql-picker-label[data-value="monospace"]::before,
.ql-snow
.ql-picker.ql-font
.ql-picker-item[data-value="monospace"]::before {
content: "等宽字体"; content: "等宽字体";
} }
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<svg :class="svgClass" :style="style" aria-hidden="true"> <svg :class="svgClass" :style="style" aria-hidden="true">
<use :xlink:href="iconName"></use> <use :xlink:href="iconName" />
</svg> </svg>
</template> </template>
@ -13,36 +13,32 @@ export default defineComponent({
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>(() => `#icon-${props.name}`); const iconName = computed<string>(() => `#icon-${props.name}`);
const svgClass = computed<Array<string>>(() => { const svgClass = computed<Array<string>>(() => {
return [ return ["icon-svg", `icon-svg__${props.name}`, String(props.className || "")];
"icon-svg",
`icon-svg__${props.name}`,
String(props.className || ""),
];
}); });
return { return {
style, style,
iconName, iconName,
svgClass, svgClass
}; };
}, }
}); });
</script> </script>

View File

@ -1,19 +1,12 @@
<template> <template>
<div class="cl-menu-file"> <div class="cl-menu-file">
<el-select <el-select v-model="path" allow-create filterable clearable placeholder="请选择">
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"
:label="item.value" :label="item.value"
:value="item.value" :value="item.value"
> />
</el-option>
</el-select> </el-select>
</div> </div>
</template> </template>
@ -29,7 +22,7 @@ function findFiles() {
for (const i in files) { for (const i in files) {
if (!i.includes("components")) { if (!i.includes("components")) {
list.push({ list.push({
value: i.substr(5), value: i.substr(5)
}); });
} }
} }
@ -43,8 +36,8 @@ export default defineComponent({
props: { props: {
modelValue: { modelValue: {
type: String, type: String,
default: "", default: ""
}, }
}, },
emits: ["update:modelValue"], emits: ["update:modelValue"],
@ -69,9 +62,9 @@ export default defineComponent({
return { return {
path, path,
list, list
}; };
}, }
}); });
</script> </script>

View File

@ -8,13 +8,13 @@
popper-class="popper-menu-icon" popper-class="popper-menu-icon"
> >
<el-row :gutter="10" class="list scroller1"> <el-row :gutter="10" class="list scroller1">
<el-col :span="3" :xs="4" v-for="(item, index) in list" :key="index"> <el-col v-for="(item, index) in list" :key="index" :span="3" :xs="4">
<el-button <el-button
size="mini" size="mini"
:class="{ 'is-active': item === name }" :class="{ 'is-active': item === name }"
@click="onChange(item)" @click="onChange(item)"
> >
<icon-svg :name="item"></icon-svg> <icon-svg :name="item" />
</el-button> </el-button>
</el-col> </el-col>
</el-row> </el-row>
@ -26,7 +26,7 @@
clearable clearable
@click="open" @click="open"
@input="onChange" @input="onChange"
></el-input> />
</template> </template>
</el-popover> </el-popover>
</div> </div>
@ -60,7 +60,7 @@ export default defineComponent({
watch( watch(
() => props.modelValue, () => props.modelValue,
val => { (val) => {
name.value = val; name.value = val;
} }
); );

View File

@ -8,7 +8,7 @@
:options="options" :options="options"
:props="{ multiple: true }" :props="{ multiple: true }"
@change="onChange" @change="onChange"
></el-cascader> />
</div> </div>
</template> </template>
@ -21,8 +21,8 @@ export default defineComponent({
props: { props: {
modelValue: { modelValue: {
type: String, type: String,
default: "", default: ""
}, }
}, },
emits: ["update:modelValue"], emits: ["update:modelValue"],
@ -38,10 +38,7 @@ export default defineComponent({
// //
function onChange(row: any) { function onChange(row: any) {
emit( emit("update:modelValue", row.map((e: any) => e.join(":")).join(","));
"update:modelValue",
row.map((e: any) => e.join(":")).join(",")
);
} }
// //
@ -80,7 +77,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) {
@ -99,21 +96,19 @@ export default defineComponent({
watch( watch(
() => props.modelValue, () => props.modelValue,
(val: string) => { (val: string) => {
value.value = val value.value = val ? val.split(",").map((e: string) => e.split(":")) : [];
? val.split(",").map((e: string) => e.split(":"))
: [];
}, },
{ {
immediate: true, immediate: true
} }
); );
return { return {
value, value,
options, options,
onChange, onChange
}; };
}, }
}); });
</script> </script>

View File

@ -6,16 +6,8 @@
background-color="transparent" background-color="transparent"
@select="onSelect" @select="onSelect"
> >
<el-menu-item <el-menu-item v-for="(item, index) in list" :key="index" :index="`${index}`">
v-for="(item, index) in list" <icon-svg v-if="item.icon" :name="item.icon" :size="18" />
: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>
@ -45,9 +37,7 @@ export default defineComponent({
const index = ref<string>("0"); const index = ref<string>("0");
// //
const list = computed(() => const list = computed(() => store.getters.menuGroup.filter((e: any) => e.isShow));
store.getters.menuGroup.filter((e: any) => e.isShow)
);
// //
function onSelect(index: number) { function onSelect(index: number) {
@ -87,9 +77,9 @@ export default defineComponent({
return { return {
index, index,
list, list,
onSelect, onSelect
}; };
}, }
}); });
</script> </script>

View File

@ -6,7 +6,7 @@
width="500px" width="500px"
popper-class="popper-menu-tree" popper-class="popper-menu-tree"
> >
<el-input size="small" v-model="keyword"> <el-input v-model="keyword" size="small">
<template #prefix> <template #prefix>
<i class="el-input__icon el-icon-search"></i> <i class="el-input__icon el-icon-search"></i>
</template> </template>
@ -25,11 +25,10 @@
:default-expanded-keys="expandedKeys" :default-expanded-keys="expandedKeys"
:filter-node-method="filterNode" :filter-node-method="filterNode"
@current-change="onCurrentChange" @current-change="onCurrentChange"
> />
</el-tree>
<template #reference> <template #reference>
<el-input v-model="name" readonly placeholder="请选择"></el-input> <el-input v-model="name" readonly placeholder="请选择" />
</template> </template>
</el-popover> </el-popover>
</div> </div>
@ -91,7 +90,7 @@ export default defineComponent({
// //
const name = computed(() => { const name = computed(() => {
const item = list.value.find(e => e.id == props.modelValue); const item = list.value.find((e) => e.id == props.modelValue);
return item ? item.name : "一级菜单"; return item ? item.name : "一级菜单";
}); });

View File

@ -4,19 +4,19 @@
<i class="el-icon-arrow-left"></i> <i class="el-icon-arrow-left"></i>
</div> </div>
<div class="app-process__scroller" :ref="setRefs('scroller')"> <div :ref="setRefs('scroller')" class="app-process__scroller">
<div <div
class="app-process__item"
v-for="(item, index) in list" v-for="(item, index) in list"
:key="index" :key="index"
:ref="setRefs(`item-${index}`)" :ref="setRefs(`item-${index}`)"
class="app-process__item"
:class="{ active: item.active }" :class="{ active: item.active }"
:data-index="index" :data-index="index"
@click="onTap(item)" @click="onTap(item)"
@contextmenu.stop.prevent="openCM($event, item)" @contextmenu.stop.prevent="openCM($event, item)"
> >
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
<i class="el-icon-close" v-if="index > 0" @mousedown.stop="onDel(index)"></i> <i v-if="index > 0" class="el-icon-close" @mousedown.stop="onDel(index)"></i>
</div> </div>
</div> </div>

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="cl-role-perms" v-loading="loading"> <div v-loading="loading" class="cl-role-perms">
<p v-if="title">{{ title }}</p> <p v-if="title">{{ title }}</p>
<el-input placeholder="输入关键字进行过滤" v-model="keyword" size="small"> </el-input> <el-input v-model="keyword" placeholder="输入关键字进行过滤" size="small" />
<div class="scroller"> <div class="scroller">
<el-tree <el-tree
@ -18,8 +18,7 @@
:default-checked-keys="checked" :default-checked-keys="checked"
:filter-node-method="filterNode" :filter-node-method="filterNode"
@check-change="save" @check-change="save"
> />
</el-tree>
</div> </div>
</div> </div>
</template> </template>
@ -40,6 +39,8 @@ export default defineComponent({
title: String title: String
}, },
emits: ["update:modelValue"],
setup(props, { emit }) { setup(props, { emit }) {
const $service = inject<any>("service"); const $service = inject<any>("service");
@ -68,7 +69,7 @@ export default defineComponent({
// //
const fn = (list: any[]) => { const fn = (list: any[]) => {
list.forEach(e => { list.forEach((e) => {
if (e.children) { if (e.children) {
fn(e.children); fn(e.children);
} else { } else {
@ -79,7 +80,7 @@ export default defineComponent({
fn(list.value); fn(list.value);
checked.value = ids.filter(id => (val || []).includes(id)); checked.value = ids.filter((id) => (val || []).includes(id));
} }
// //

View File

@ -1,11 +1,6 @@
<template> <template>
<el-select v-model="value" v-bind="props" multiple @change="onChange"> <el-select v-model="value" v-bind="props" multiple @change="onChange">
<el-option <el-option v-for="(item, index) in list" :key="index" :value="item.id" :label="item.name" />
v-for="(item, index) in list"
:value="item.id"
:label="item.name"
:key="index"
></el-option>
</el-select> </el-select>
</template> </template>

View File

@ -1,21 +1,15 @@
<template> <template>
<div class="cl-route-nav"> <div class="cl-route-nav">
<p class="title" v-if="browser.isMini"> <p v-if="browser.isMini" class="title">
{{ lastName }} {{ lastName }}
</p> </p>
<template v-else> <template v-else>
<el-breadcrumb> <el-breadcrumb>
<el-breadcrumb-item :to="{ path: '/' }" <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
>首页</el-breadcrumb-item <el-breadcrumb-item v-for="(item, index) in list" :key="index">{{
>
<el-breadcrumb-item
v-for="(item, index) in list"
:key="index"
>{{
(item.meta && item.meta.label) || item.name (item.meta && item.meta.label) || item.name
}}</el-breadcrumb-item }}</el-breadcrumb-item>
>
</el-breadcrumb> </el-breadcrumb>
</template> </template>
</div> </div>
@ -75,7 +69,7 @@ export default defineComponent({
} }
}, },
{ {
immediate: true, immediate: true
} }
); );
@ -87,9 +81,9 @@ export default defineComponent({
return { return {
list, list,
lastName, lastName,
browser, browser
}; };
}, }
}); });
</script> </script>

View File

@ -1,5 +1,5 @@
<template> <template>
<error-page :code="404" desc="找不到您要查找的页面"></error-page> <error-page :code="404" desc="找不到您要查找的页面" />
</template> </template>
<script> <script>

View File

@ -1,5 +1,5 @@
<template> <template>
<error-page :code="500" desc="糟糕,出了点问题"></error-page> <error-page :code="500" desc="糟糕,出了点问题" />
</template> </template>
<script> <script>

View File

@ -1,5 +1,5 @@
<template> <template>
<error-page :code="502" desc="马上回来"></error-page> <error-page :code="502" desc="马上回来" />
</template> </template>
<script> <script>

View File

@ -5,7 +5,7 @@
<template v-if="token || isLogout"> <template v-if="token || isLogout">
<div class="router"> <div class="router">
<el-select size="medium" filterable prefix-icon="el-icon-search" v-model="url"> <el-select v-model="url" size="medium" filterable prefix-icon="el-icon-search">
<el-option v-for="(item, index) in routes" :key="index" :value="item.path"> <el-option v-for="(item, index) in routes" :key="index" :value="item.path">
<span style="float: left">{{ item.name }}</span> <span style="float: left">{{ item.name }}</span>
<span style="float: right">{{ item.path }}</span> <span style="float: right">{{ item.path }}</span>

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="page-iframe" v-loading="loading" element-loading-text="拼命加载中"> <div v-loading="loading" class="page-iframe" element-loading-text="拼命加载中">
<iframe :src="url" frameborder="0"></iframe> <iframe :src="url" frameborder="0"></iframe>
</div> </div>
</template> </template>

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="login-captcha" @click="refresh"> <div class="login-captcha" @click="refresh">
<div class="svg" v-html="svg" v-if="svg"></div> <div v-if="svg" class="svg" v-html="svg"></div>
<img class="base64" :src="base64" alt="" v-else /> <img v-else class="base64" :src="base64" alt="" />
</div> </div>
</template> </template>

View File

@ -7,51 +7,46 @@
<el-form class="form" size="medium" :disabled="saving"> <el-form class="form" size="medium" :disabled="saving">
<el-form-item label="用户名"> <el-form-item label="用户名">
<el-input <el-input
placeholder="请输入用户名"
v-model="form.username" v-model="form.username"
placeholder="请输入用户名"
maxlength="20" maxlength="20"
auto-complete="off" auto-complete="off"
></el-input> />
</el-form-item> </el-form-item>
<el-form-item label="密码"> <el-form-item label="密码">
<el-input <el-input
v-model="form.password"
type="password" type="password"
placeholder="请输入密码" placeholder="请输入密码"
v-model="form.password"
maxlength="20" maxlength="20"
auto-complete="off" auto-complete="off"
></el-input> />
</el-form-item> </el-form-item>
<el-form-item label="验证码" class="captcha"> <el-form-item label="验证码" class="captcha">
<el-input <el-input
v-model="form.verifyCode"
placeholder="请输入图片验证码" placeholder="请输入图片验证码"
maxlength="4" maxlength="4"
v-model="form.verifyCode"
auto-complete="off" auto-complete="off"
@keyup.enter="toLogin" @keyup.enter="toLogin"
></el-input> />
<captcha <captcha
:ref="setRefs('captcha')" :ref="setRefs('captcha')"
class="value"
v-model="form.captchaId" v-model="form.captchaId"
class="value"
@change=" @change="
() => { () => {
form.verifyCode = ''; form.verifyCode = '';
} }
" "
></captcha> />
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-button <el-button round size="mini" class="submit-btn" :loading="saving" @click="toLogin"
round
size="mini"
class="submit-btn"
@click="toLogin"
:loading="saving"
>登录</el-button >登录</el-button
> >
</div> </div>
@ -68,13 +63,13 @@ import { useRefs } from "/@/core";
export default defineComponent({ export default defineComponent({
components: { components: {
Captcha, Captcha
}, },
setup() { setup() {
const router = useRouter(); const router = useRouter();
const store = useStore(); const store = useStore();
const { refs, setRefs } = useRefs(); const { refs, setRefs }: any = useRefs();
const saving = ref<boolean>(false); const saving = ref<boolean>(false);
@ -83,7 +78,7 @@ export default defineComponent({
username: "admin", username: "admin",
password: "123456", password: "123456",
captchaId: "", captchaId: "",
verifyCode: "", verifyCode: ""
}); });
// //
@ -130,9 +125,9 @@ export default defineComponent({
form, form,
saving, saving,
toLogin, toLogin,
setRefs, setRefs
}; };
}, }
}); });
</script> </script>

View File

@ -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

@ -25,7 +25,7 @@ const actions = {
// 用户退出 // 用户退出
userLogout({ dispatch }: any): Promise<any> { userLogout({ dispatch }: any): Promise<any> {
return new Promise(resolve => { return new Promise((resolve) => {
store.$service.common.userLogout().done(() => { store.$service.common.userLogout().done(() => {
dispatch("userRemove").then(() => { dispatch("userRemove").then(() => {
resolve(null); resolve(null);

View File

@ -39,8 +39,5 @@ export function createLink(url: string, id?: string) {
link.id = id; link.id = id;
} }
document document.getElementsByTagName("head")?.item(0)?.appendChild(link);
.getElementsByTagName("head")
?.item(0)
?.appendChild(link);
} }

View File

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

View File

@ -1,7 +1,7 @@
<template> <template>
<cl-crud :ref="setRefs('crud')" @load="onLoad"> <cl-crud :ref="setRefs('crud')" @load="onLoad">
<el-row type="flex"> <el-row type="flex">
<cl-refresh-btn></cl-refresh-btn> <cl-refresh-btn />
<el-button <el-button
v-permission="$service.system.log.permission.clear" v-permission="$service.system.log.permission.clear"
@ -14,26 +14,26 @@
<cl-filter label="日志保存天数"> <cl-filter label="日志保存天数">
<el-input-number <el-input-number
v-model="day"
controls-position="right" controls-position="right"
size="mini" size="mini"
:max="10000" :max="10000"
:min="1" :min="1"
v-model="day"
@blur="saveDay" @blur="saveDay"
></el-input-number> />
</cl-filter> </cl-filter>
<cl-flex1 /> <cl-flex1 />
<cl-search-key placeholder="请输入请求地址, 参数ip地址"></cl-search-key> <cl-search-key placeholder="请输入请求地址, 参数ip地址" />
</el-row> </el-row>
<el-row> <el-row>
<cl-table v-bind="table"></cl-table> <cl-table v-bind="table" />
</el-row> </el-row>
<el-row type="flex"> <el-row type="flex">
<cl-flex1></cl-flex1> <cl-flex1 />
<cl-pagination></cl-pagination> <cl-pagination />
</el-row> </el-row>
</cl-crud> </cl-crud>
</template> </template>

View File

@ -11,10 +11,10 @@
<template #column-name="{ scope }"> <template #column-name="{ scope }">
<span>{{ scope.row.name }}</span> <span>{{ scope.row.name }}</span>
<el-tag <el-tag
v-if="!scope.row.isShow"
size="mini" size="mini"
effect="dark" effect="dark"
type="danger" type="danger"
v-if="!scope.row.isShow"
style="margin-left: 10px" style="margin-left: 10px"
>隐藏</el-tag >隐藏</el-tag
> >
@ -22,7 +22,7 @@
<!-- 图标 --> <!-- 图标 -->
<template #column-icon="{ scope }"> <template #column-icon="{ scope }">
<icon-svg :name="scope.row.icon" size="16px" style="margin-top: 5px"></icon-svg> <icon-svg :name="scope.row.icon" size="16px" style="margin-top: 5px" />
</template> </template>
<!-- 权限 --> <!-- 权限 -->
@ -39,7 +39,7 @@
<!-- 路由 --> <!-- 路由 -->
<template #column-router="{ scope }"> <template #column-router="{ scope }">
<el-link type="primary" :href="scope.row.router" v-if="scope.row.type == 1">{{ <el-link v-if="scope.row.type == 1" type="primary" :href="scope.row.router">{{
scope.row.router scope.row.router
}}</el-link> }}</el-link>
<span v-else>{{ scope.row.router }}</span> <span v-else>{{ scope.row.router }}</span>
@ -48,18 +48,18 @@
<!-- 路由缓存 --> <!-- 路由缓存 -->
<template #column-keepAlive="{ scope }"> <template #column-keepAlive="{ scope }">
<template v-if="scope.row.type == 1"> <template v-if="scope.row.type == 1">
<i class="el-icon-check" v-if="scope.row.keepAlive"></i> <i v-if="scope.row.keepAlive" class="el-icon-check"></i>
<i class="el-icon-close" v-else></i> <i v-else class="el-icon-close"></i>
</template> </template>
</template> </template>
<!-- 行新增 --> <!-- 行新增 -->
<template #slot-add="{ scope }"> <template #slot-add="{ scope }">
<el-button <el-button
v-if="scope.row.type != 2"
type="text" type="text"
size="mini" size="mini"
@click="upsertAppend(scope.row)" @click="upsertAppend(scope.row)"
v-if="scope.row.type != 2"
>新增</el-button >新增</el-button
> >
</template> </template>
@ -67,12 +67,12 @@
</el-row> </el-row>
<el-row type="flex"> <el-row type="flex">
<cl-flex1></cl-flex1> <cl-flex1 />
<cl-pagination :props="{ layout: 'total' }"></cl-pagination> <cl-pagination :props="{ layout: 'total' }" />
</el-row> </el-row>
<!-- 编辑 --> <!-- 编辑 -->
<cl-upsert v-bind="upsert"></cl-upsert> <cl-upsert v-bind="upsert" />
</cl-crud> </cl-crud>
</template> </template>
@ -100,7 +100,7 @@ export default defineComponent({
// //
function onRefresh(_: any, { render }: RefreshOp) { function onRefresh(_: any, { render }: RefreshOp) {
$service.system.menu.list().then((list: any[]) => { $service.system.menu.list().then((list: any[]) => {
list.map(e => { list.map((e) => {
e.permList = e.perms ? e.perms.split(",") : []; e.permList = e.perms ? e.perms.split(",") : [];
}); });

View File

@ -1,35 +1,31 @@
<template> <template>
<cl-crud @load="onLoad"> <cl-crud @load="onLoad">
<el-row type="flex"> <el-row type="flex">
<cl-refresh-btn></cl-refresh-btn> <cl-refresh-btn />
<cl-add-btn></cl-add-btn> <cl-add-btn />
<cl-multi-delete-btn></cl-multi-delete-btn> <cl-multi-delete-btn />
<cl-flex1></cl-flex1> <cl-flex1 />
<cl-search-key></cl-search-key> <cl-search-key />
</el-row> </el-row>
<el-row> <el-row>
<cl-table v-bind="table"></cl-table> <cl-table v-bind="table" />
</el-row> </el-row>
<el-row type="flex"> <el-row type="flex">
<cl-flex1></cl-flex1> <cl-flex1 />
<cl-pagination></cl-pagination> <cl-pagination />
</el-row> </el-row>
<cl-upsert :ref="setRefs('upsert')" v-bind="upsert" @open="onUpsertOpen"> <cl-upsert :ref="setRefs('upsert')" v-bind="upsert" @open="onUpsertOpen">
<template #slot-content="{ scope }"> <template #slot-content="{ scope }">
<div class="editor" v-for="(item, index) in tab.list" :key="index"> <div v-for="(item, index) in tab.list" :key="index" class="editor">
<template v-if="tab.index == index"> <template v-if="tab.index == index">
<el-button class="change-btn" size="mini" @click="changeTab(item.to)">{{ <el-button class="change-btn" size="mini" @click="changeTab(item.to)">{{
item.label item.label
}}</el-button> }}</el-button>
<component <component :is="item.component" v-model="scope.data" height="300px" />
:is="item.component"
height="300px"
v-model="scope.data"
></component>
</template> </template>
</div> </div>
</template> </template>

View File

@ -18,15 +18,15 @@
size="mini" size="mini"
:disabled="!perms.enable" :disabled="!perms.enable"
@change="onEnableChange($event, scope.row)" @change="onEnableChange($event, scope.row)"
></el-switch> />
</template> </template>
<!-- 配置按钮 --> <!-- 配置按钮 -->
<template #slot-conf="{ scope }"> <template #slot-conf="{ scope }">
<el-button <el-button
v-if="scope.row.view && perms.edit"
type="text" type="text"
size="mini" size="mini"
v-if="scope.row.view && perms.edit"
@click="openConf(scope.row)" @click="openConf(scope.row)"
>配置</el-button >配置</el-button
> >
@ -42,7 +42,7 @@
</cl-crud> </cl-crud>
<!-- 表单 --> <!-- 表单 -->
<cl-form :ref="setRefs('form')"></cl-form> <cl-form :ref="setRefs('form')" />
</div> </div>
</template> </template>
@ -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

@ -9,7 +9,7 @@
</el-row> </el-row>
<el-row> <el-row>
<cl-table v-bind="table"> </cl-table> <cl-table v-bind="table" />
</el-row> </el-row>
<el-row type="flex"> <el-row type="flex">
@ -17,7 +17,7 @@
<cl-pagination /> <cl-pagination />
</el-row> </el-row>
<cl-upsert v-model="form" v-bind="upsert"></cl-upsert> <cl-upsert v-model="form" v-bind="upsert" />
</cl-crud> </cl-crud>
</template> </template>

View File

@ -7,7 +7,7 @@
@row-click="onDeptRowClick" @row-click="onDeptRowClick"
@user-add="onDeptUserAdd" @user-add="onDeptUserAdd"
@list-change="onDeptListChange" @list-change="onDeptListChange"
></cl-dept-tree> />
</div> </div>
<!-- 成员列表 --> <!-- 成员列表 -->
@ -22,27 +22,21 @@
</div> </div>
<div class="container"> <div class="container">
<cl-crud <cl-crud :ref="setRefs('crud')" :on-refresh="onRefresh" @load="onLoad">
: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-add-btn></cl-add-btn> <cl-add-btn />
<cl-multi-delete-btn></cl-multi-delete-btn> <cl-multi-delete-btn />
<el-button <el-button
v-permission=" v-permission="$service.system.user.permission.move"
$service.system.user.permission.move
"
size="mini" size="mini"
type="success" type="success"
:disabled="selects.ids.length == 0" :disabled="selects.ids.length == 0"
@click="toMove()" @click="toMove()"
>转移</el-button >转移</el-button
> >
<cl-flex1></cl-flex1> <cl-flex1 />
<cl-search-key></cl-search-key> <cl-search-key />
</el-row> </el-row>
<el-row> <el-row>
@ -58,15 +52,13 @@
size="medium" size="medium"
:src="scope.row.headImg" :src="scope.row.headImg"
:style="{ margin: 'auto' }" :style="{ margin: 'auto' }"
> />
</cl-avatar>
</template> </template>
<!-- 权限 --> <!-- 权限 -->
<template #column-roleName="{ scope }"> <template #column-roleName="{ scope }">
<el-tag <el-tag
v-for="(item, index) in scope.row v-for="(item, index) in scope.row.roleNameList"
.roleNameList"
:key="index" :key="index"
disable-transitions disable-transitions
size="small" size="small"
@ -79,9 +71,7 @@
<!-- 单个转移 --> <!-- 单个转移 -->
<template #slot-move-btn="{ scope }"> <template #slot-move-btn="{ scope }">
<el-button <el-button
v-permission=" v-permission="$service.system.user.permission.move"
$service.system.user.permission.move
"
type="text" type="text"
size="mini" size="mini"
@click="toMove(scope.row)" @click="toMove(scope.row)"
@ -92,8 +82,8 @@
</el-row> </el-row>
<el-row type="flex"> <el-row type="flex">
<cl-flex1></cl-flex1> <cl-flex1 />
<cl-pagination></cl-pagination> <cl-pagination />
</el-row> </el-row>
<cl-upsert <cl-upsert
@ -104,9 +94,7 @@
<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" <span style="margin-left: 6px">新增用户默认密码为123456</span>
>新增用户默认密码为123456</span
>
</div> </div>
</template> </template>
</cl-upsert> </cl-upsert>
@ -116,10 +104,7 @@
</div> </div>
<!-- 部门移动 --> <!-- 部门移动 -->
<cl-dept-move <cl-dept-move :ref="setRefs('dept-move')" @success="refresh({ page: 1 })" />
:ref="setRefs('dept-move')"
@success="refresh({ page: 1 })"
></cl-dept-move>
</div> </div>
</template> </template>
@ -143,7 +128,7 @@ export default defineComponent({
// //
const selects = reactive<any>({ const selects = reactive<any>({
dept: {}, dept: {},
ids: [], ids: []
}); });
// //
@ -154,53 +139,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",
@ -210,27 +195,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
}, }
], ]
}); });
// //
@ -244,9 +229,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",
@ -255,13 +240,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",
@ -270,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: "username", prop: "username",
@ -285,15 +270,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",
@ -304,16 +289,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",
@ -324,14 +309,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",
@ -340,9 +325,9 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
placeholder: "请填写手机号码", placeholder: "请填写手机号码"
}, }
}, }
}, },
{ {
prop: "email", prop: "email",
@ -351,9 +336,9 @@ export default defineComponent({
component: { component: {
name: "el-input", name: "el-input",
props: { props: {
placeholder: "请填写邮箱", placeholder: "请填写邮箱"
}, }
}, }
}, },
{ {
prop: "remark", prop: "remark",
@ -364,9 +349,9 @@ export default defineComponent({
props: { props: {
placeholder: "请填写备注", placeholder: "请填写备注",
type: "textarea", type: "textarea",
rows: 4, rows: 4
}, }
}, }
}, },
{ {
prop: "status", prop: "status",
@ -377,23 +362,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"
}, }
}, }
], ]
}); });
// //
@ -406,7 +391,7 @@ export default defineComponent({
isExpand.value = !val; isExpand.value = !val;
}, },
{ {
immediate: true, immediate: true
} }
); );
@ -450,7 +435,7 @@ export default defineComponent({
next({ next({
...data, ...data,
departmentId, departmentId
}); });
} }
@ -465,7 +450,7 @@ export default defineComponent({
refresh({ refresh({
page: 1, page: 1,
departmentIds: ids, departmentIds: ids
}); });
// //
@ -477,7 +462,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
}); });
} }
@ -522,9 +507,9 @@ export default defineComponent({
onDeptUserAdd, onDeptUserAdd,
onDeptListChange, onDeptListChange,
deptExpand, deptExpand,
toMove, toMove
}; };
}, }
}); });
</script> </script>

View File

@ -31,8 +31,8 @@
<template #slot-session> <template #slot-session>
<button v-if="session"> <button v-if="session">
<i class="el-icon-notebook-2" v-if="sessionVisible" @click="closeSession()"></i> <i v-if="sessionVisible" class="el-icon-notebook-2" @click="closeSession()"></i>
<i class="el-icon-arrow-left" v-else @click="openSession()"></i> <i v-else class="el-icon-arrow-left" @click="openSession()"></i>
</button> </button>
</template> </template>
</cl-dialog> </cl-dialog>
@ -40,8 +40,8 @@
<!-- MP3 --> <!-- MP3 -->
<div class="mp3"> <div class="mp3">
<audio <audio
style="display: none"
:ref="setRefs('sound')" :ref="setRefs('sound')"
style="display: none"
src="../static/notify.mp3" src="../static/notify.mp3"
controls controls
></audio> ></audio>
@ -82,6 +82,8 @@ export default defineComponent({
} }
}, },
emits: ["message"],
setup(_, { emit }) { setup(_, { emit }) {
const store = useStore(); const store = useStore();
const { refs, setRefs } = useRefs(); const { refs, setRefs } = useRefs();

View File

@ -10,9 +10,9 @@
<div class="tool-emoji"> <div class="tool-emoji">
<div class="tool-emoji__scroller scroller1"> <div class="tool-emoji__scroller scroller1">
<div <div
class="tool-emoji__item"
v-for="(item, index) in list" v-for="(item, index) in list"
:key="index" :key="index"
class="tool-emoji__item"
@click="select(item)" @click="select(item)"
> >
<img :src="item" /> <img :src="item" />
@ -127,6 +127,8 @@ const emoji = {
}; };
export default defineComponent({ export default defineComponent({
emits: ["select"],
setup(_, { emit }) { setup(_, { emit }) {
const store = useStore(); const store = useStore();
@ -134,7 +136,7 @@ export default defineComponent({
const visible = ref<boolean>(false); const visible = ref<boolean>(false);
// //
const list = ref<any[]>(emoji.list.map(e => emoji.url + e)); const list = ref<any[]>(emoji.list.map((e) => emoji.url + e));
// //
const popoverWidth = computed(() => { const popoverWidth = computed(() => {

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="icon-voice"> <div class="icon-voice">
<icon-svg :name="`voice${index}`"></icon-svg> <icon-svg :name="`voice${index}`" />
</div> </div>
</template> </template>

View File

@ -59,13 +59,9 @@
resize="none" resize="none"
:rows="5" :rows="5"
@keyup.enter="onTextSend" @keyup.enter="onTextSend"
></el-input> />
<el-button <el-button type="primary" size="mini" :disabled="!text" @click="onTextSend"
type="primary"
size="mini"
:disabled="!text"
@click="onTextSend"
>发送</el-button >发送</el-button
> >
</div> </div>
@ -79,7 +75,7 @@ import Emoji from "./emoji.vue";
export default defineComponent({ export default defineComponent({
components: { components: {
Emoji, Emoji
}, },
setup() { setup() {
@ -92,7 +88,7 @@ export default defineComponent({
// //
const emoji = reactive<any>({ const emoji = reactive<any>({
visible: false, visible: false
}); });
// //
@ -116,7 +112,7 @@ export default defineComponent({
contentType: data.contentType, contentType: data.contentType,
type: 0, type: 0,
content: data.content, content: data.content,
sessionId: id, sessionId: id
}); });
} }
@ -131,14 +127,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);
@ -163,12 +159,12 @@ export default defineComponent({
next({ next({
content: { content: {
imageUrl, imageUrl
}, },
style: { style: {
height: height + "px", height: height + "px",
width: width + "px", width: width + "px"
}, }
}); });
}; };
@ -186,8 +182,8 @@ export default defineComponent({
store.commit("UPDATE_MESSAGE", { store.commit("UPDATE_MESSAGE", {
file, file,
data: { data: {
progress: e.percent + "%", progress: e.percent + "%"
}, }
}); });
} }
@ -198,10 +194,10 @@ export default defineComponent({
data: { data: {
loading: false, loading: false,
content: { content: {
[`${key}Url`]: res.data, [`${key}Url`]: res.data
}
}, },
}, callback: send
callback: send,
}); });
} }
@ -213,8 +209,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);
@ -231,10 +227,10 @@ export default defineComponent({
send( send(
{ {
content: { content: {
imageUrl: res.data, imageUrl: res.data
}, },
type: 0, type: 0,
contentType: 1, contentType: 1
}, },
true true
); );
@ -246,10 +242,10 @@ export default defineComponent({
send( send(
{ {
content: { content: {
imageUrl: url, imageUrl: url
}, },
type: 0, type: 0,
contentType: 2, contentType: 2
}, },
true true
); );
@ -260,10 +256,10 @@ export default defineComponent({
send( send(
{ {
content: { content: {
videoUrl: url, videoUrl: url
}, },
type: 0, type: 0,
contentType: 4, contentType: 4
}, },
true true
); );
@ -279,9 +275,9 @@ export default defineComponent({
onTextSend, onTextSend,
onImageSelect, onImageSelect,
onEmojiSelect, onEmojiSelect,
onVideoSelect, onVideoSelect
}; };
}, }
}); });
</script> </script>

View File

@ -1,23 +1,15 @@
<template> <template>
<div v-loading="!visible && loading" class="cl-chat-message" element-loading-text="消息加载中">
<div <div
class="cl-chat-message"
v-loading="!visible && loading"
element-loading-text="消息加载中"
>
<div
class="cl-chat-message__scroller scroller1"
:ref="setRefs('scroller')" :ref="setRefs('scroller')"
class="cl-chat-message__scroller scroller1"
:style="{ :style="{
opacity: visible ? 1 : 0, opacity: visible ? 1 : 0
}" }"
> >
<!-- 加载更多 --> <!-- 加载更多 -->
<div class="cl-chat-message__more" v-show="list.length > 0"> <div v-show="list.length > 0" class="cl-chat-message__more">
<el-button <el-button round size="mini" :loading="loading" @click="onLoadmore"
round
size="mini"
:loading="loading"
@click="onLoadmore"
>加载更多</el-button >加载更多</el-button
> >
</div> </div>
@ -25,16 +17,13 @@
<!-- 消息列表 --> <!-- 消息列表 -->
<div class="cl-chat-message__list"> <div class="cl-chat-message__list">
<div <div
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="[ class="cl-chat-message__item"
item.type == 0 ? `is-right` : `is-left`, :class="[item.type == 0 ? `is-right` : `is-left`, `is-${item.mode}`]"
`is-${item.mode}`,
]"
> >
<!-- 日期 --> <!-- 日期 -->
<div class="date" v-if="item._date"> <div v-if="item._date" class="date">
<span>{{ item._date }}</span> <span>{{ item._date }}</span>
</div> </div>
@ -50,8 +39,8 @@
<span class="name">{{ item.nickName }}</span> <span class="name">{{ item.nickName }}</span>
<div <div
class="content"
v-loading="item.loading" v-loading="item.loading"
class="content"
:element-loading-text="item.progress" :element-loading-text="item.progress"
@click="onTap(item)" @click="onTap(item)"
> >
@ -65,9 +54,7 @@
<el-image <el-image
:key="item.uid" :key="item.uid"
:src="item.content.imageUrl" :src="item.content.imageUrl"
:preview-src-list="[ :preview-src-list="[item.content.imageUrl]"
item.content.imageUrl,
]"
:z-index="3000" :z-index="3000"
:style="item.style" :style="item.style"
> >
@ -88,12 +75,8 @@
<!-- 语音 --> <!-- 语音 -->
<template v-else-if="item.mode === 'voice'"> <template v-else-if="item.mode === 'voice'">
<icon-voice <icon-voice :play="item.isPlay" />
:play="item.isPlay" <span class="duration">{{ item.content.duration }}"</span>
></icon-voice>
<span class="duration"
>{{ item.content.duration }}"</span
>
</template> </template>
<!-- 视频 --> <!-- 视频 -->
@ -119,12 +102,7 @@
<!-- 音频 --> <!-- 音频 -->
<div class="voice"> <div class="voice">
<audio <audio ref="voice" style="display: none" :src="voice.url" controls></audio>
style="display: none"
ref="voice"
:src="voice.url"
controls
></audio>
</div> </div>
</div> </div>
</div> </div>
@ -132,15 +110,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { import { computed, defineComponent, inject, nextTick, onUnmounted, reactive, ref } from "vue";
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";
@ -152,7 +122,7 @@ import AvatarUrl from "../static/images/custom-avatar.png";
export default defineComponent({ export default defineComponent({
components: { components: {
IconVoice, IconVoice
}, },
setup() { setup() {
@ -175,13 +145,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
}); });
// //
@ -210,19 +180,14 @@ export default defineComponent({
} }
// //
const content = isString(e.content) const content = isString(e.content) ? JSON.parse(e.content) : e.content;
? JSON.parse(e.content)
: e.content;
// //
const nickName = const nickName = e.type == 0 ? userInfo.nickName : session.value.nickname;
e.type == 0 ? userInfo.nickName : session.value.nickname;
// //
const avatarUrl = const avatarUrl =
e.type == 0 e.type == 0 ? userInfo.avatarUrl || AvatarUrl : session.value.headimgurl;
? userInfo.avatarUrl || AvatarUrl
: session.value.headimgurl;
return { return {
...e, ...e,
@ -230,7 +195,7 @@ export default defineComponent({
content, content,
avatarUrl, avatarUrl,
nickName, nickName,
mode: chat.modes[e.contentType], mode: chat.modes[e.contentType]
}; };
}); });
}); });
@ -270,7 +235,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"
}); });
} }
}); });
@ -287,7 +252,7 @@ export default defineComponent({
...params, ...params,
sessionId: session.value.id, sessionId: session.value.id,
order: "createTime", order: "createTime",
sort: "desc", sort: "desc"
}; };
// //
@ -371,9 +336,9 @@ export default defineComponent({
onTap, onTap,
refresh, refresh,
onLoadmore, onLoadmore,
scrollToBottom, scrollToBottom
}; };
}, }
}); });
</script> </script>

View File

@ -5,7 +5,7 @@
</el-badge> </el-badge>
<!-- 聊天盒子 --> <!-- 聊天盒子 -->
<cl-chat ref="chat" @message="updateNum"></cl-chat> <cl-chat ref="chat" @message="updateNum" />
</div> </div>
</template> </template>
@ -16,7 +16,7 @@ export default {
data() { data() {
return { return {
visible: false, visible: false,
number: 0, number: 0
}; };
}, },
@ -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

@ -16,15 +16,15 @@
clearable clearable
@clear="onSearch" @clear="onSearch"
@keyup.enter="onSearch" @keyup.enter="onSearch"
></el-input> />
</div> </div>
<!-- 会话列表 --> <!-- 会话列表 -->
<ul class="cl-chat-session__list scroller1" v-loading="loading"> <ul v-loading="loading" class="cl-chat-session__list scroller1">
<li <li
class="cl-chat-session__item"
v-for="(item, index) in list" v-for="(item, index) in list"
:key="index" :key="index"
class="cl-chat-session__item"
:class="{ :class="{
'is-active': session ? item.id == session.id : false 'is-active': session ? item.id == session.id : false
}" }"

View File

@ -4,12 +4,12 @@ import Clipboard from "clipboard";
function copyboard() { function copyboard() {
const clipboard = new Clipboard("._copy-btn"); const clipboard = new Clipboard("._copy-btn");
clipboard.on("success", e => { clipboard.on("success", (e) => {
ElMessage.success("复制成功"); ElMessage.success("复制成功");
e.clearSelection(); e.clearSelection();
}); });
clipboard.on("error", err => { clipboard.on("error", (err) => {
console.error(err); console.error(err);
ElMessage.success("复制失败"); ElMessage.success("复制失败");
}); });

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="demo-adv-search"> <div class="demo-adv-search">
<cl-adv-btn></cl-adv-btn> <cl-adv-btn />
<cl-adv-search :items="items" :op-list="opList"></cl-adv-search> <cl-adv-search :items="items" :op-list="opList" />
</div> </div>
</template> </template>
@ -10,8 +10,6 @@ import { AdvSearchItem } from "/@/crud/types";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({
name: "demo-adv-search",
setup() { setup() {
const items = ref<AdvSearchItem[]>([ const items = ref<AdvSearchItem[]>([
{ {

View File

@ -10,8 +10,6 @@ import { ElMessage } from "element-plus";
import { defineComponent } from "vue"; import { defineComponent } from "vue";
export default defineComponent({ export default defineComponent({
name: "demo__context-menu",
setup() { setup() {
function open(event: any) { function open(event: any) {
ContextMenu.open(event, { ContextMenu.open(event, {

View File

@ -9,7 +9,7 @@
@opened="onOpened" @opened="onOpened"
@closed="onClosed" @closed="onClosed"
> >
<el-alert type="success" title="行云又被风吹散,见了依前是梦中"> </el-alert> <el-alert type="success" title="行云又被风吹散,见了依前是梦中" />
</cl-dialog> </cl-dialog>
</div> </div>
</template> </template>
@ -18,8 +18,6 @@
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({
name: "demo__dialog",
setup() { setup() {
const visible = ref<boolean>(false); const visible = ref<boolean>(false);

View File

@ -27,7 +27,7 @@
prop: 'createTime' prop: 'createTime'
} }
]" ]"
></cl-table> />
</cl-crud> </cl-crud>
</template> </template>
@ -39,7 +39,7 @@
:prop="'vads.' + index + '.val'" :prop="'vads.' + index + '.val'"
:rules="{ required: true, message: '请输入' }" :rules="{ required: true, message: '请输入' }"
> >
<el-input v-model="item.val"></el-input> <el-input v-model="item.val" />
</el-form-item> </el-form-item>
<el-button @click="addVad(scope.vads)">添加行</el-button> <el-button @click="addVad(scope.vads)">添加行</el-button>
@ -55,8 +55,6 @@ 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",
setup() { setup() {
const formRef = ref<FormRef>(); const formRef = ref<FormRef>();

View File

@ -1,5 +1,5 @@
<template> <template>
<cl-query field="status" :list="list"></cl-query> <cl-query field="status" :list="list" />
</template> </template>
<script lang="ts"> <script lang="ts">
@ -7,8 +7,6 @@ import { QueryList } from "/@/crud/types";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({
name: "demo__query",
setup() { setup() {
const list = ref<QueryList[]>([ const list = ref<QueryList[]>([
{ {

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="demo-table"> <div class="demo-table">
<cl-table :columns="columns"></cl-table> <cl-table :columns="columns" />
</div> </div>
</template> </template>
@ -9,8 +9,6 @@ import { TableColumn } from "/@/crud/types";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({
name: "demo-table",
setup() { setup() {
const columns = ref<TableColumn[]>([ const columns = ref<TableColumn[]>([
{ {

View File

@ -6,8 +6,6 @@
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({
name: "render-test",
setup() { setup() {
const value = ref<string>("Value" + Math.random()); const value = ref<string>("Value" + Math.random());

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="demo-upsert"> <div class="demo-upsert">
<cl-upsert ref="upsertRef" :items="items"></cl-upsert> <cl-upsert ref="upsertRef" :items="items" />
</div> </div>
</template> </template>
@ -9,8 +9,6 @@ import { UpsertItem, UpsertRef } from "/@/crud/types";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
export default defineComponent({ export default defineComponent({
name: "demo-upsert",
setup() { setup() {
const upsertRef = ref<UpsertRef>(); const upsertRef = ref<UpsertRef>();

View File

@ -5,8 +5,8 @@
svg图片库 svg图片库
</div> </div>
<div class="c _svg"> <div class="c _svg">
<el-tooltip content="icon-like" v-for="(item, index) in list" :key="index"> <el-tooltip v-for="(item, index) in list" :key="index" content="icon-like">
<icon-svg :size="18" :name="`icon-${item}`"></icon-svg> <icon-svg :size="18" :name="`icon-${item}`" />
</el-tooltip> </el-tooltip>
</div> </div>
<div class="f"> <div class="f">

View File

@ -6,7 +6,7 @@
</div> </div>
<div class="c"> <div class="c">
<el-button size="small" v-copy="'https://www.cool-admin.com/'"> <el-button v-copy="'https://www.cool-admin.com/'" size="small">
https://www.cool-admin.com https://www.cool-admin.com
</el-button> </el-button>
</div> </div>

View File

@ -75,8 +75,8 @@ export const TestService = {
}, },
info: (d: any) => { info: (d: any) => {
console.log("GET[info]", d); console.log("GET[info]", d);
return new Promise(resolve => { return new Promise((resolve) => {
resolve(UserList.find(e => e.id == d.id)); resolve(UserList.find((e) => e.id == d.id));
}); });
}, },
add: (d: any) => { add: (d: any) => {
@ -92,14 +92,14 @@ export const TestService = {
console.log("POST[delete]", d); console.log("POST[delete]", d);
const ids = d.ids.split(","); const ids = d.ids.split(",");
ids.forEach((id: any) => { ids.forEach((id: any) => {
const index = UserList.findIndex(e => e.id == id); const index = UserList.findIndex((e) => e.id == id);
UserList.splice(index, 1); UserList.splice(index, 1);
}); });
return Promise.resolve(); return Promise.resolve();
}, },
update: (d: any) => { update: (d: any) => {
console.log("POST[update]", d); console.log("POST[update]", d);
const item = UserList.find(e => e.id == d.id); const item = UserList.find((e) => e.id == d.id);
Object.assign(item, d); Object.assign(item, d);
return Promise.resolve(); return Promise.resolve();
} }

View File

@ -2,28 +2,28 @@
<div class="demo"> <div class="demo">
<cl-crud @load="onLoad"> <cl-crud @load="onLoad">
<el-row> <el-row>
<cl-refresh-btn></cl-refresh-btn> <cl-refresh-btn />
<cl-add-btn></cl-add-btn> <cl-add-btn />
<cl-multi-delete-btn></cl-multi-delete-btn> <cl-multi-delete-btn />
<demo-dialog></demo-dialog> <demo-dialog />
<demo-context-menu></demo-context-menu> <demo-context-menu />
<demo-form></demo-form> <demo-form />
<demo-query></demo-query> <demo-query />
<cl-flex1></cl-flex1> <cl-flex1 />
<cl-search-key field="name"></cl-search-key> <cl-search-key field="name" />
<demo-adv-search></demo-adv-search> <demo-adv-search />
</el-row> </el-row>
<el-row> <el-row>
<demo-table></demo-table> <demo-table />
</el-row> </el-row>
<el-row> <el-row>
<cl-flex1></cl-flex1> <cl-flex1 />
<cl-pagination></cl-pagination> <cl-pagination />
</el-row> </el-row>
<demo-upsert></demo-upsert> <demo-upsert />
</cl-crud> </cl-crud>
</div> </div>
</template> </template>
@ -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,15 +1,8 @@
<template> <template>
<div class="demo scroller1"> <div class="demo scroller1">
<el-row :gutter="10"> <el-row :gutter="10">
<el-col <el-col v-for="(item, index) in list" :key="index" :xs="24" :sm="12" :md="8" :lg="6">
v-for="(item, index) in list" <component :is="item" />
:key="index"
:xs="24"
:sm="12"
:md="8"
:lg="6"
>
<component :is="item"></component>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
@ -34,7 +27,7 @@ export default {
BClCrud, BClCrud,
BClContextMenu, BClContextMenu,
BErrorPage, BErrorPage,
BClEditorQuill, BClEditorQuill
}, },
setup() { setup() {
@ -46,10 +39,10 @@ export default {
"b-v-copy", "b-v-copy",
"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

@ -1,6 +1,6 @@
<template> <template>
<div class="page-editor-quill"> <div class="page-editor-quill">
<cl-editor-quill v-model="content" :height="400"></cl-editor-quill> <cl-editor-quill v-model="content" :height="400" />
</div> </div>
</template> </template>

View File

@ -2,7 +2,7 @@
<div class="demo-upload scroller1"> <div class="demo-upload scroller1">
<div class="demo-upload__item"> <div class="demo-upload__item">
<p>文件空间</p> <p>文件空间</p>
<cl-upload-space v-model="urls"></cl-upload-space> <cl-upload-space v-model="urls" />
<p style="margin-top: 10px">选择的文件</p> <p style="margin-top: 10px">选择的文件</p>
@ -11,33 +11,33 @@
:key="index" :key="index"
:src="item" :src="item"
:style="{ width: '100px', marginRight: '10px' }" :style="{ width: '100px', marginRight: '10px' }"
></el-image> />
</div> </div>
<div class="demo-upload__item"> <div class="demo-upload__item">
<p>普通上传</p> <p>普通上传</p>
<cl-upload></cl-upload> <cl-upload />
</div> </div>
<div class="demo-upload__item"> <div class="demo-upload__item">
<p>指定类型上传 accept=.jpg,.png</p> <p>指定类型上传 accept=.jpg,.png</p>
<cl-upload accept=".jpg,.png"></cl-upload> <cl-upload accept=".jpg,.png" />
</div> </div>
<div class="demo-upload__item"> <div class="demo-upload__item">
<p>多图上传 picture-card</p> <p>多图上传 picture-card</p>
<cl-upload multiple :limit="3" listType="picture-card"></cl-upload> <cl-upload multiple :limit="3" list-type="picture-card" />
</div> </div>
<div class="demo-upload__item"> <div class="demo-upload__item">
<p>文件上传 text</p> <p>文件上传 text</p>
<cl-upload v-model="urls" multiple :limit="5" accept="*" list-type="text"></cl-upload> <cl-upload v-model="urls" multiple :limit="5" accept="*" list-type="text" />
</div> </div>
<div class="demo-upload__item"> <div class="demo-upload__item">
<p>自定义</p> <p>自定义</p>
<cl-upload icon="el-icon-picture" text="选择图片" :size="[120, 200]"></cl-upload> <cl-upload icon="el-icon-picture" text="选择图片" :size="[120, 200]" />
</div> </div>
<div class="demo-upload__item"> <div class="demo-upload__item">

View File

@ -34,7 +34,7 @@ export default {
nearestWeekday: ["最近的工作日(周一至周五)至本月", "日"], nearestWeekday: ["最近的工作日(周一至周五)至本月", "日"],
someWeekday: ["在这个月的第", "个"] someWeekday: ["在这个月的第", "个"]
}, },
Week: ["天", "一", "二", "三", "四", "五", "六"].map(val => "星期" + val), Week: ["天", "一", "二", "三", "四", "五", "六"].map((val) => "星期" + val),
Month: { Month: {
name: "月", name: "月",
every: "每一月", every: "每一月",

View File

@ -2,9 +2,7 @@
<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> <template #label> <i class="el-icon-date"></i> {{ text.Seconds.name }} </template>
<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">{{
@ -15,38 +13,28 @@
<el-radio v-model="second.cronEvery" label="2" <el-radio v-model="second.cronEvery" label="2"
>{{ text.Seconds.interval[0] }} >{{ text.Seconds.interval[0] }}
<el-input-number <el-input-number
size="small"
v-model="second.incrementIncrement" v-model="second.incrementIncrement"
size="small"
:min="1" :min="1"
:max="60" :max="60"
></el-input-number> />
{{ text.Seconds.interval[1] || "" }} {{ text.Seconds.interval[1] || "" }}
<el-input-number <el-input-number
size="small"
v-model="second.incrementStart" v-model="second.incrementStart"
size="small"
:min="0" :min="0"
:max="59" :max="59"
></el-input-number> />
{{ text.Seconds.interval[2] || "" }} {{ text.Seconds.interval[2] || "" }}
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio <el-radio v-model="second.cronEvery" class="long" label="3"
class="long"
v-model="second.cronEvery"
label="3"
>{{ text.Seconds.specific }} >{{ text.Seconds.specific }}
<el-select <el-select v-model="second.specificSpecific" size="small" multiple>
size="small" <el-option v-for="val in 60" :key="val" :value="val - 1">{{
multiple val - 1
v-model="second.specificSpecific" }}</el-option>
>
<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>
@ -54,18 +42,18 @@
<el-radio v-model="second.cronEvery" label="4" <el-radio v-model="second.cronEvery" label="4"
>{{ text.Seconds.cycle[0] }} >{{ text.Seconds.cycle[0] }}
<el-input-number <el-input-number
size="small"
v-model="second.rangeStart" v-model="second.rangeStart"
size="small"
:min="1" :min="1"
:max="60" :max="60"
></el-input-number> />
{{ text.Seconds.cycle[1] || "" }} {{ text.Seconds.cycle[1] || "" }}
<el-input-number <el-input-number
size="small"
v-model="second.rangeEnd" v-model="second.rangeEnd"
size="small"
:min="0" :min="0"
:max="59" :max="59"
></el-input-number> />
{{ text.Seconds.cycle[2] || "" }} {{ text.Seconds.cycle[2] || "" }}
</el-radio> </el-radio>
</el-row> </el-row>
@ -86,38 +74,28 @@
<el-radio v-model="minute.cronEvery" label="2" <el-radio v-model="minute.cronEvery" label="2"
>{{ text.Minutes.interval[0] }} >{{ text.Minutes.interval[0] }}
<el-input-number <el-input-number
size="small"
v-model="minute.incrementIncrement" v-model="minute.incrementIncrement"
size="small"
:min="1" :min="1"
:max="60" :max="60"
></el-input-number> />
{{ text.Minutes.interval[1] }} {{ text.Minutes.interval[1] }}
<el-input-number <el-input-number
size="small"
v-model="minute.incrementStart" v-model="minute.incrementStart"
size="small"
:min="0" :min="0"
:max="59" :max="59"
></el-input-number> />
{{ text.Minutes.interval[2] || "" }} {{ text.Minutes.interval[2] || "" }}
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio <el-radio v-model="minute.cronEvery" class="long" label="3"
class="long"
v-model="minute.cronEvery"
label="3"
>{{ text.Minutes.specific }} >{{ text.Minutes.specific }}
<el-select <el-select v-model="minute.specificSpecific" size="small" multiple>
size="small" <el-option v-for="val in 60" :key="val" :value="val - 1">{{
multiple val - 1
v-model="minute.specificSpecific" }}</el-option>
>
<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>
@ -125,27 +103,25 @@
<el-radio v-model="minute.cronEvery" label="4" <el-radio v-model="minute.cronEvery" label="4"
>{{ text.Minutes.cycle[0] }} >{{ text.Minutes.cycle[0] }}
<el-input-number <el-input-number
size="small"
v-model="minute.rangeStart" v-model="minute.rangeStart"
size="small"
:min="1" :min="1"
:max="60" :max="60"
></el-input-number> />
{{ text.Minutes.cycle[1] }} {{ text.Minutes.cycle[1] }}
<el-input-number <el-input-number
size="small"
v-model="minute.rangeEnd" v-model="minute.rangeEnd"
size="small"
:min="0" :min="0"
:max="59" :max="59"
></el-input-number> />
{{ text.Minutes.cycle[2] }} {{ text.Minutes.cycle[2] }}
</el-radio> </el-radio>
</el-row> </el-row>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane> <el-tab-pane>
<template #label> <template #label> <i class="el-icon-date"></i> {{ text.Hours.name }} </template>
<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">{{
@ -156,38 +132,28 @@
<el-radio v-model="hour.cronEvery" label="2" <el-radio v-model="hour.cronEvery" label="2"
>{{ text.Hours.interval[0] }} >{{ text.Hours.interval[0] }}
<el-input-number <el-input-number
size="small"
v-model="hour.incrementIncrement" v-model="hour.incrementIncrement"
size="small"
:min="0" :min="0"
:max="23" :max="23"
></el-input-number> />
{{ text.Hours.interval[1] }} {{ text.Hours.interval[1] }}
<el-input-number <el-input-number
size="small"
v-model="hour.incrementStart" v-model="hour.incrementStart"
size="small"
:min="0" :min="0"
:max="23" :max="23"
></el-input-number> />
{{ text.Hours.interval[2] }} {{ text.Hours.interval[2] }}
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio <el-radio v-model="hour.cronEvery" class="long" label="3"
class="long"
v-model="hour.cronEvery"
label="3"
>{{ text.Hours.specific }} >{{ text.Hours.specific }}
<el-select <el-select v-model="hour.specificSpecific" size="small" multiple>
size="small" <el-option v-for="val in 24" :key="val" :value="val - 1">{{
multiple val - 1
v-model="hour.specificSpecific" }}</el-option>
>
<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>
@ -195,53 +161,46 @@
<el-radio v-model="hour.cronEvery" label="4" <el-radio v-model="hour.cronEvery" label="4"
>{{ text.Hours.cycle[0] }} >{{ text.Hours.cycle[0] }}
<el-input-number <el-input-number
size="small"
v-model="hour.rangeStart" v-model="hour.rangeStart"
size="small"
:min="0" :min="0"
:max="23" :max="23"
></el-input-number> />
{{ text.Hours.cycle[1] }} {{ text.Hours.cycle[1] }}
<el-input-number <el-input-number
size="small"
v-model="hour.rangeEnd" v-model="hour.rangeEnd"
size="small"
:min="0" :min="0"
:max="23" :max="23"
></el-input-number> />
{{ text.Hours.cycle[2] }} {{ text.Hours.cycle[2] }}
</el-radio> </el-radio>
</el-row> </el-row>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane> <el-tab-pane>
<template #label> <template #label> <i class="el-icon-date"></i> {{ text.Day.name }} </template>
<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">{{ <el-radio v-model="day.cronEvery" label="1">{{ text.Day.every }}</el-radio>
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"
>{{ text.Day.intervalWeek[0] }} >{{ text.Day.intervalWeek[0] }}
<el-input-number <el-input-number
size="small"
v-model="week.incrementIncrement" v-model="week.incrementIncrement"
size="small"
:min="1" :min="1"
:max="7" :max="7"
></el-input-number> />
{{ text.Day.intervalWeek[1] }} {{ text.Day.intervalWeek[1] }}
<el-select <el-select v-model="week.incrementStart" size="small">
size="small"
v-model="week.incrementStart"
>
<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="val" :value="val"
></el-option> />
</el-select> </el-select>
{{ text.Day.intervalWeek[2] }} {{ text.Day.intervalWeek[2] }}
</el-radio> </el-radio>
@ -250,62 +209,43 @@
<el-radio v-model="day.cronEvery" label="3" <el-radio v-model="day.cronEvery" label="3"
>{{ text.Day.intervalDay[0] }} >{{ text.Day.intervalDay[0] }}
<el-input-number <el-input-number
size="small"
v-model="day.incrementIncrement" v-model="day.incrementIncrement"
size="small"
:min="1" :min="1"
:max="31" :max="31"
></el-input-number> />
{{ text.Day.intervalDay[1] }} {{ text.Day.intervalDay[1] }}
<el-input-number <el-input-number
size="small"
v-model="day.incrementStart" v-model="day.incrementStart"
size="small"
:min="1" :min="1"
:max="31" :max="31"
></el-input-number> />
{{ text.Day.intervalDay[2] }} {{ text.Day.intervalDay[2] }}
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio class="long" v-model="day.cronEvery" label="4" <el-radio v-model="day.cronEvery" class="long" label="4"
>{{ text.Day.specificWeek }} >{{ text.Day.specificWeek }}
<el-select <el-select v-model="week.specificSpecific" size="small" multiple>
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-select> </el-select>
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio class="long" v-model="day.cronEvery" label="5" <el-radio v-model="day.cronEvery" class="long" label="5"
>{{ text.Day.specificDay }} >{{ text.Day.specificDay }}
<el-select <el-select v-model="day.specificSpecific" size="small" multiple>
size="small" <el-option v-for="val in 31" :key="val" :value="val">{{
multiple val
v-model="day.specificSpecific" }}</el-option>
>
<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>
@ -322,16 +262,13 @@
<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 <el-select v-model="day.cronLastSpecificDomDay" size="small">
size="small"
v-model="day.cronLastSpecificDomDay"
>
<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="val" :value="val"
></el-option> />
</el-select> </el-select>
{{ text.Day.lastWeek[1] || "" }} {{ text.Day.lastWeek[1] || "" }}
</el-radio> </el-radio>
@ -339,11 +276,11 @@
<el-row> <el-row>
<el-radio v-model="day.cronEvery" label="9"> <el-radio v-model="day.cronEvery" label="9">
<el-input-number <el-input-number
size="small"
v-model="day.cronDaysBeforeEomMinus" v-model="day.cronDaysBeforeEomMinus"
size="small"
:min="1" :min="1"
:max="31" :max="31"
></el-input-number> />
{{ text.Day.beforeEndMonth[0] }} {{ text.Day.beforeEndMonth[0] }}
</el-radio> </el-radio>
</el-row> </el-row>
@ -351,11 +288,11 @@
<el-radio v-model="day.cronEvery" label="10" <el-radio v-model="day.cronEvery" label="10"
>{{ text.Day.nearestWeekday[0] }} >{{ text.Day.nearestWeekday[0] }}
<el-input-number <el-input-number
size="small"
v-model="day.cronDaysNearestWeekday" v-model="day.cronDaysNearestWeekday"
size="small"
:min="1" :min="1"
:max="31" :max="31"
></el-input-number> />
{{ text.Day.nearestWeekday[1] }} {{ text.Day.nearestWeekday[1] }}
</el-radio> </el-radio>
</el-row> </el-row>
@ -363,14 +300,14 @@
<el-radio v-model="day.cronEvery" label="11" <el-radio v-model="day.cronEvery" label="11"
>{{ text.Day.someWeekday[0] }} >{{ text.Day.someWeekday[0] }}
<el-input-number <el-input-number
size="small"
v-model="week.cronNthDayNth" v-model="week.cronNthDayNth"
size="small"
:min="1" :min="1"
:max="5" :max="5"
></el-input-number> />
<el-select <el-select
size="small"
v-model="week.cronNthDayDay" v-model="week.cronNthDayDay"
size="small"
style="margin-left: 5px" style="margin-left: 5px"
> >
<el-option <el-option
@ -378,7 +315,7 @@
:key="val" :key="val"
:label="text.Week[val - 1]" :label="text.Week[val - 1]"
:value="val" :value="val"
></el-option> />
</el-select> </el-select>
{{ text.Day.someWeekday[1] }} {{ text.Day.someWeekday[1] }}
</el-radio> </el-radio>
@ -400,37 +337,25 @@
<el-radio v-model="month.cronEvery" label="2" <el-radio v-model="month.cronEvery" label="2"
>{{ text.Month.interval[0] }} >{{ text.Month.interval[0] }}
<el-input-number <el-input-number
size="small"
v-model="month.incrementIncrement" v-model="month.incrementIncrement"
size="small"
:min="0" :min="0"
:max="12" :max="12"
></el-input-number> />
{{ text.Month.interval[1] }} {{ text.Month.interval[1] }}
<el-input-number <el-input-number
size="small"
v-model="month.incrementStart" v-model="month.incrementStart"
size="small"
:min="0" :min="0"
:max="12" :max="12"
></el-input-number> />
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio <el-radio v-model="month.cronEvery" class="long" label="3"
class="long"
v-model="month.cronEvery"
label="3"
>{{ text.Month.specific }} >{{ text.Month.specific }}
<el-select <el-select v-model="month.specificSpecific" size="small" multiple>
size="small" <el-option v-for="val in 12" :key="val" :label="val" :value="val" />
multiple
v-model="month.specificSpecific"
>
<el-option
v-for="val in 12"
:key="val"
:label="val"
:value="val"
></el-option>
</el-select> </el-select>
</el-radio> </el-radio>
</el-row> </el-row>
@ -438,26 +363,24 @@
<el-radio v-model="month.cronEvery" label="4" <el-radio v-model="month.cronEvery" label="4"
>{{ text.Month.cycle[0] }} >{{ text.Month.cycle[0] }}
<el-input-number <el-input-number
size="small"
v-model="month.rangeStart" v-model="month.rangeStart"
size="small"
:min="1" :min="1"
:max="12" :max="12"
></el-input-number> />
{{ text.Month.cycle[1] }} {{ text.Month.cycle[1] }}
<el-input-number <el-input-number
size="small"
v-model="month.rangeEnd" v-model="month.rangeEnd"
size="small"
:min="1" :min="1"
:max="12" :max="12"
></el-input-number> />
</el-radio> </el-radio>
</el-row> </el-row>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane v-if="showYear || false"> <el-tab-pane v-if="showYear || false">
<template #label> <template #label> <i class="el-icon-date"></i> {{ text.Year.name }} </template>
<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">{{
@ -468,38 +391,35 @@
<el-radio v-model="year.cronEvery" label="2" <el-radio v-model="year.cronEvery" label="2"
>{{ text.Year.interval[0] }} >{{ text.Year.interval[0] }}
<el-input-number <el-input-number
size="small"
v-model="year.incrementIncrement" v-model="year.incrementIncrement"
size="small"
:min="1" :min="1"
:max="99" :max="99"
></el-input-number> />
{{ text.Year.interval[1] }} {{ text.Year.interval[1] }}
<el-input-number <el-input-number
size="small"
v-model="year.incrementStart" v-model="year.incrementStart"
size="small"
:min="2018" :min="2018"
:max="2118" :max="2118"
></el-input-number> />
</el-radio> </el-radio>
</el-row> </el-row>
<el-row> <el-row>
<el-radio <el-radio v-model="year.cronEvery" class="long" label="3"
class="long"
v-model="year.cronEvery"
label="3"
>{{ text.Year.specific }} >{{ text.Year.specific }}
<el-select <el-select
v-model="year.specificSpecific"
size="small" size="small"
filterable filterable
multiple multiple
v-model="year.specificSpecific"
> >
<el-option <el-option
v-for="val in 100" v-for="val in 100"
:key="val" :key="val"
:label="2017 + val" :label="2017 + val"
:value="2017 + val" :value="2017 + val"
></el-option> />
</el-select> </el-select>
</el-radio> </el-radio>
</el-row> </el-row>
@ -507,18 +427,18 @@
<el-radio v-model="year.cronEvery" label="4" <el-radio v-model="year.cronEvery" label="4"
>{{ text.Year.cycle[0] }} >{{ text.Year.cycle[0] }}
<el-input-number <el-input-number
size="small"
v-model="year.rangeStart" v-model="year.rangeStart"
size="small"
:min="2018" :min="2018"
:max="2118" :max="2118"
></el-input-number> />
{{ text.Year.cycle[1] }} {{ text.Year.cycle[1] }}
<el-input-number <el-input-number
size="small"
v-model="year.rangeEnd" v-model="year.rangeEnd"
size="small"
:min="2018" :min="2018"
:max="2118" :max="2118"
></el-input-number> />
</el-radio> </el-radio>
</el-row> </el-row>
</div> </div>
@ -541,9 +461,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"],
@ -556,7 +476,7 @@ export default {
incrementIncrement: 5, incrementIncrement: 5,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [], specificSpecific: []
}, },
minute: { minute: {
cronEvery: "", cronEvery: "",
@ -564,7 +484,7 @@ export default {
incrementIncrement: 5, incrementIncrement: 5,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [], specificSpecific: []
}, },
hour: { hour: {
cronEvery: "", cronEvery: "",
@ -572,7 +492,7 @@ export default {
incrementIncrement: 5, incrementIncrement: 5,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [], specificSpecific: []
}, },
day: { day: {
cronEvery: "", cronEvery: "",
@ -583,7 +503,7 @@ export default {
specificSpecific: [], specificSpecific: [],
cronLastSpecificDomDay: 1, cronLastSpecificDomDay: 1,
cronDaysBeforeEomMinus: "", cronDaysBeforeEomMinus: "",
cronDaysNearestWeekday: "", cronDaysNearestWeekday: ""
}, },
week: { week: {
cronEvery: "", cronEvery: "",
@ -591,7 +511,7 @@ export default {
incrementIncrement: 1, incrementIncrement: 1,
specificSpecific: [], specificSpecific: [],
cronNthDayDay: 1, cronNthDayDay: 1,
cronNthDayNth: 1, cronNthDayNth: 1
}, },
month: { month: {
cronEvery: "", cronEvery: "",
@ -599,7 +519,7 @@ export default {
incrementIncrement: 5, incrementIncrement: 5,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [], specificSpecific: []
}, },
year: { year: {
cronEvery: "", cronEvery: "",
@ -607,7 +527,7 @@ export default {
incrementIncrement: 1, incrementIncrement: 1,
rangeStart: "", rangeStart: "",
rangeEnd: "", rangeEnd: "",
specificSpecific: [], specificSpecific: []
}, },
output: { output: {
second: "", second: "",
@ -616,17 +536,11 @@ export default {
day: "", day: "",
month: "", month: "",
Week: "", Week: "",
year: "", year: ""
}, }
}; };
}, },
watch: {
data() {
this.rest(this.$data);
},
},
computed: { computed: {
text() { text() {
return Language; return Language;
@ -639,10 +553,7 @@ export default {
seconds = "*"; seconds = "*";
break; break;
case "2": case "2":
seconds = seconds = this.second.incrementStart + "/" + this.second.incrementIncrement;
this.second.incrementStart +
"/" +
this.second.incrementIncrement;
break; break;
case "3": case "3":
this.second.specificSpecific.forEach((val) => { this.second.specificSpecific.forEach((val) => {
@ -651,8 +562,7 @@ export default {
seconds = seconds.slice(0, -1); seconds = seconds.slice(0, -1);
break; break;
case "4": case "4":
seconds = seconds = this.second.rangeStart + "-" + this.second.rangeEnd;
this.second.rangeStart + "-" + this.second.rangeEnd;
break; break;
} }
return seconds; return seconds;
@ -665,10 +575,7 @@ export default {
minutes = "*"; minutes = "*";
break; break;
case "2": case "2":
minutes = minutes = this.minute.incrementStart + "/" + this.minute.incrementIncrement;
this.minute.incrementStart +
"/" +
this.minute.incrementIncrement;
break; break;
case "3": case "3":
this.minute.specificSpecific.forEach((val) => { this.minute.specificSpecific.forEach((val) => {
@ -677,8 +584,7 @@ export default {
minutes = minutes.slice(0, -1); minutes = minutes.slice(0, -1);
break; break;
case "4": case "4":
minutes = minutes = this.minute.rangeStart + "-" + this.minute.rangeEnd;
this.minute.rangeStart + "-" + this.minute.rangeEnd;
break; break;
} }
return minutes; return minutes;
@ -691,10 +597,7 @@ export default {
hours = "*"; hours = "*";
break; break;
case "2": case "2":
hours = hours = this.hour.incrementStart + "/" + this.hour.incrementIncrement;
this.hour.incrementStart +
"/" +
this.hour.incrementIncrement;
break; break;
case "3": case "3":
this.hour.specificSpecific.forEach((val) => { this.hour.specificSpecific.forEach((val) => {
@ -720,10 +623,7 @@ export default {
days = "?"; days = "?";
break; break;
case "3": case "3":
days = days = this.day.incrementStart + "/" + this.day.incrementIncrement;
this.day.incrementStart +
"/" +
this.day.incrementIncrement;
break; break;
case "5": case "5":
this.day.specificSpecific.forEach((val) => { this.day.specificSpecific.forEach((val) => {
@ -759,10 +659,7 @@ export default {
weeks = "?"; weeks = "?";
break; break;
case "2": case "2":
weeks = weeks = this.week.incrementStart + "/" + this.week.incrementIncrement;
this.week.incrementStart +
"/" +
this.week.incrementIncrement;
break; break;
case "4": case "4":
this.week.specificSpecific.forEach((val) => { this.week.specificSpecific.forEach((val) => {
@ -778,8 +675,7 @@ export default {
weeks = "?"; weeks = "?";
break; break;
case "11": case "11":
weeks = weeks = this.week.cronNthDayDay + "#" + this.week.cronNthDayNth;
this.week.cronNthDayDay + "#" + this.week.cronNthDayNth;
break; break;
} }
return weeks; return weeks;
@ -792,10 +688,7 @@ export default {
months = "*"; months = "*";
break; break;
case "2": case "2":
months = months = this.month.incrementStart + "/" + this.month.incrementIncrement;
this.month.incrementStart +
"/" +
this.month.incrementIncrement;
break; break;
case "3": case "3":
this.month.specificSpecific.forEach((val) => { this.month.specificSpecific.forEach((val) => {
@ -817,10 +710,7 @@ export default {
years = "*"; years = "*";
break; break;
case "2": case "2":
years = years = this.year.incrementStart + "/" + this.year.incrementIncrement;
this.year.incrementStart +
"/" +
this.year.incrementIncrement;
break; break;
case "3": case "3":
this.year.specificSpecific.forEach((val) => { this.year.specificSpecific.forEach((val) => {
@ -837,10 +727,16 @@ export default {
cron() { cron() {
return `${this.secondsText || "*"} ${this.minutesText || "*"} ${ return `${this.secondsText || "*"} ${this.minutesText || "*"} ${
this.hoursText || "*" this.hoursText || "*"
} ${this.daysText || "*"} ${this.monthsText || "*"} ${ } ${this.daysText || "*"} ${this.monthsText || "*"} ${this.weeksText || "?"} ${
this.weeksText || "?" this.showYear ? this.yearsText || "*" : ""
} ${this.showYear ? this.yearsText || "*" : ""}`; }`;
}
}, },
watch: {
data() {
this.rest(this.$data);
}
}, },
methods: { methods: {
@ -869,8 +765,8 @@ export default {
} }
} }
} }
}, }
}, }
}; };
</script> </script>

View File

@ -2,7 +2,7 @@
<div class="system-task"> <div class="system-task">
<div class="box scroller1"> <div class="box scroller1">
<!-- 系统用户自定义已停止 --> <!-- 系统用户自定义已停止 -->
<div class="block" :class="[`_${item.key}`]" v-for="(item, index) in list" :key="index"> <div v-for="(item, index) in list" :key="index" class="block" :class="[`_${item.key}`]">
<div class="header"> <div class="header">
<!-- 图标 --> <!-- 图标 -->
<i class="icon" :class="item.icon"></i> <i class="icon" :class="item.icon"></i>
@ -19,22 +19,22 @@
<li <li
v-else v-else
@click="refreshTask({ page: 1 })"
class="refresh-btn"
v-permission="perm.delete" v-permission="perm.delete"
class="refresh-btn"
@click="refreshTask({ page: 1 })"
> >
<i class="el-icon-refresh"></i> <i class="el-icon-refresh"></i>
<span>刷新</span> <span>刷新</span>
</li> </li>
<li @click="edit(item.params)" class="add-btn" v-permission="perm.add"> <li v-permission="perm.add" class="add-btn" @click="edit(item.params)">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<span>添加</span> <span>添加</span>
</li> </li>
</ul> </ul>
</div> </div>
<div class="container scroller1" :ref="setRefs(`${item.key}-scroller`)"> <div :ref="setRefs(`${item.key}-scroller`)" class="container scroller1">
<draggable <draggable
v-model="list[index].list" v-model="list[index].list"
v-bind="drag.options" v-bind="drag.options"
@ -42,17 +42,17 @@
item-key="id" item-key="id"
:data-type="item.params.type" :data-type="item.params.type"
:data-status="item.params.status" :data-status="item.params.status"
@end="e => onDragEnd(e, item)" @end="(e) => onDragEnd(e, item)"
> >
<template #item="{ element }"> <template #item="{ element }">
<li <li
:key="element.id" :key="element.id"
:data-id="element.id" :data-id="element.id"
@contextmenu.stop.prevent="openCM($event, element)"
class="_drag" class="_drag"
@contextmenu.stop.prevent="openCM($event, element)"
> >
<div class="h"> <div class="h">
<span class="type _warning" v-show="element.status === 0"> <span v-show="element.status === 0" class="type _warning">
{{ element.type === 0 ? "系统" : "用户" }} {{ element.type === 0 ? "系统" : "用户" }}
</span> </span>
<span class="name">{{ element.name }}</span> <span class="name">{{ element.name }}</span>
@ -74,8 +74,8 @@
<div class="op"> <div class="op">
<div <div
class="op-item"
v-if="element.status === 0" v-if="element.status === 0"
class="op-item"
@click="start(element)" @click="start(element)"
> >
<i class="el-icon-video-play"></i> <i class="el-icon-video-play"></i>
@ -83,30 +83,30 @@
</div> </div>
<div <div
class="op-item"
v-else v-else
@click="stop(element)"
v-permission="perm.stop" v-permission="perm.stop"
class="op-item"
@click="stop(element)"
> >
<i class="el-icon-video-pause"></i> <i class="el-icon-video-pause"></i>
<span>暂停</span> <span>暂停</span>
</div> </div>
<div <div
class="op-item"
@click="edit(element)"
v-permission="{ v-permission="{
and: [perm.update, perm.info] and: [perm.update, perm.info]
}" }"
class="op-item"
@click="edit(element)"
> >
<i class="el-icon-edit"></i> <i class="el-icon-edit"></i>
<span>编辑</span> <span>编辑</span>
</div> </div>
<div <div
v-permission="perm.log"
class="op-item" class="op-item"
@click="findLog(element)" @click="findLog(element)"
v-permission="perm.log"
> >
<i class="el-icon-tickets"></i> <i class="el-icon-tickets"></i>
<span>查看日志</span> <span>查看日志</span>
@ -116,31 +116,29 @@
</template> </template>
<template #header> <template #header>
<div class="empty" v-if="list[index].list.length == 0"> <div v-if="list[index].list.length == 0" class="empty">暂无数据</div>
暂无数据
</div>
</template> </template>
</draggable> </draggable>
<el-button <el-button
v-if="item.pagination.total >= item.pagination.size"
class="more" class="more"
type="text" type="text"
size="mini" size="mini"
@click="moreTask(index, item)" @click="moreTask(index, item)"
v-if="item.pagination.total >= item.pagination.size"
>查看更多</el-button >查看更多</el-button
> >
</div> </div>
<div class="footer"> <div class="footer">
<button class="btn-add" @click="edit(item.params)" v-permission="perm.add"> <button v-permission="perm.add" class="btn-add" @click="edit(item.params)">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
</button> </button>
</div> </div>
</div> </div>
<!-- 日志 --> <!-- 日志 -->
<div class="block _log" v-permission="perm.log"> <div v-permission="perm.log" class="block _log">
<div class="header"> <div class="header">
<!-- 标题 --> <!-- 标题 -->
<span class="label">日志</span> <span class="label">日志</span>
@ -150,8 +148,8 @@
<!-- 是否异常 --> <!-- 是否异常 -->
<el-checkbox-group <el-checkbox-group
class="status"
v-model="logs.filters.status" v-model="logs.filters.status"
class="status"
@change="filterLog" @change="filterLog"
> >
<el-checkbox :label="0">异常</el-checkbox> <el-checkbox :label="0">异常</el-checkbox>
@ -171,11 +169,11 @@
</ul> </ul>
</div> </div>
<div class="container" v-loading="logs.loading" element-loading-text="拼命加载中"> <div v-loading="logs.loading" class="container" element-loading-text="拼命加载中">
<ul <ul
class="scroller1"
:ref="setRefs('log-scroller')" :ref="setRefs('log-scroller')"
v-infinite-scroll="moreLog" v-infinite-scroll="moreLog"
class="scroller1"
> >
<li <li
v-for="(item, index) in logs.list" v-for="(item, index) in logs.list"
@ -343,7 +341,7 @@ export default defineComponent({
const { index, more } = options || {}; const { index, more } = options || {};
const arr = index === undefined || index === null ? list.map((e, i) => i) : [index]; const arr = index === undefined || index === null ? list.map((e, i) => i) : [index];
arr.forEach(async k => { arr.forEach(async (k) => {
const item = list[k]; const item = list[k];
Object.assign(item.params, { Object.assign(item.params, {
@ -759,9 +757,9 @@ export default defineComponent({
} }
ContextMenu.open(e, { ContextMenu.open(e, {
list: menus.filter(e => { list: menus.filter((e) => {
return checkPerm({ return checkPerm({
and: e.perm.map(a => perm.value[a]) and: e.perm.map((a) => perm.value[a])
}); });
}) })
}); });

View File

@ -1,11 +1,11 @@
<template> <template>
<div class="cl-theme"> <div class="cl-theme">
<li @click="open"> <li @click="open">
<icon-svg :size="18" name="icon-theme"></icon-svg> <icon-svg :size="18" name="icon-theme" />
</li> </li>
<!-- 系统设置 --> <!-- 系统设置 -->
<el-drawer title="系统设置" v-model="drawer.visible" size="300px"> <el-drawer v-model="drawer.visible" title="系统设置" size="300px">
<div class="cl-theme__container"> <div class="cl-theme__container">
<div class="cl-theme__color is-card"> <div class="cl-theme__color is-card">
<p>主题</p> <p>主题</p>
@ -19,13 +19,13 @@
> >
<li <li
:style="{ :style="{
backgroundColor: item.color, backgroundColor: item.color
}" }"
@click="setTheme(item)" @click="setTheme(item)"
> >
<i <i
class="el-icon-check"
v-show="item.color == form.theme.color" v-show="item.color == form.theme.color"
class="el-icon-check"
></i> ></i>
</li> </li>
</el-tooltip> </el-tooltip>
@ -38,24 +38,15 @@
<ul> <ul>
<li v-if="!browser.isMini"> <li v-if="!browser.isMini">
<span>显示一级菜单栏</span> <span>显示一级菜单栏</span>
<el-switch <el-switch v-model="form.conf.showAMenu" size="mini" />
size="mini"
v-model="form.conf.showAMenu"
></el-switch>
</li> </li>
<li> <li>
<span>显示路由导航栏</span> <span>显示路由导航栏</span>
<el-switch <el-switch v-model="form.conf.showRouteNav" size="mini" />
size="mini"
v-model="form.conf.showRouteNav"
></el-switch>
</li> </li>
<li> <li>
<span>显示页面进程栏</span> <span>显示页面进程栏</span>
<el-switch <el-switch v-model="form.conf.showProcess" size="mini" />
size="mini"
v-model="form.conf.showProcess"
></el-switch>
</li> </li>
</ul> </ul>
</div> </div>
@ -70,7 +61,7 @@
:closable="false" :closable="false"
show-icon show-icon
title="手动修改配置文件可设置为默认主题、布局。" title="手动修改配置文件可设置为默认主题、布局。"
></el-alert> />
<el-button <el-button
round round
@ -91,18 +82,18 @@
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">
<li> <li>
<p class="cl-theme__desc-label">修改主题色</p> <p class="cl-theme__desc-label">修改主题色</p>
<cl-codemirror v-model="desc.color"></cl-codemirror> <cl-codemirror v-model="desc.color" />
</li> </li>
<li> <li>
<p class="cl-theme__desc-label">修改应用配置</p> <p class="cl-theme__desc-label">修改应用配置</p>
<cl-codemirror v-model="desc.conf"></cl-codemirror> <cl-codemirror v-model="desc.conf" />
</li> </li>
</ul> </ul>
</cl-dialog> </cl-dialog>
@ -118,43 +109,43 @@ 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: {}
}; };
}, },
@ -163,7 +154,7 @@ export default {
themeList() { themeList() {
return isArray(this.list) ? this.list : this.themes; return isArray(this.list) ? this.list : this.themes;
}, }
}, },
watch: { watch: {
@ -172,15 +163,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: {
@ -203,19 +194,14 @@ 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 = `${ style.href = `${this.modules.theme.options.sourceUrl || "/theme/"}${name}.css`;
this.modules.theme.options.sourceUrl || "/theme/"
}${name}.css`;
if (!theme) { if (!theme) {
style.type = "text/css"; style.type = "text/css";
style.rel = "stylesheet"; style.rel = "stylesheet";
style.id = "theme-style"; style.id = "theme-style";
document document.getElementsByTagName("head").item(0).appendChild(style);
.getElementsByTagName("head")
.item(0)
.appendChild(style);
} }
// //
@ -223,9 +209,7 @@ export default {
this.form.theme.url = style.href; this.form.theme.url = style.href;
// css // css
document document.getElementsByTagName("body")[0].style.setProperty("--color-primary", color);
.getElementsByTagName("body")[0]
.style.setProperty("--color-primary", color);
}, },
// //
@ -246,8 +230,8 @@ export default {
} }
} }
`; `;
}, }
}, }
}; };
</script> </script>

View File

@ -6,11 +6,11 @@
`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-upload <el-upload
:action="action" :action="action"
@ -25,9 +25,10 @@
:show-file-list="_showFileList" :show-file-list="_showFileList"
:auto-upload="autoUpload" :auto-upload="autoUpload"
:disabled="disabled" :disabled="disabled"
v-loading="_loading"
:headers="{ :headers="{
Authorization: token, Authorization: token,
...headers, ...headers
}" }"
:http-request="action ? undefined : httpRequest" :http-request="action ? undefined : httpRequest"
:on-remove="_onRemove" :on-remove="_onRemove"
@ -38,15 +39,12 @@
:before-upload="_beforeUpload" :before-upload="_beforeUpload"
:before-remove="beforeRemove" :before-remove="beforeRemove"
:style="_style" :style="_style"
v-loading="_loading"
> >
<slot> <slot>
<!-- 多图上传 --> <!-- 多图上传 -->
<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">{{ <span v-if="_text" class="cl-upload__text">{{ _text }}</span>
_text
}}</span>
</template> </template>
<!-- 文件上传 --> <!-- 文件上传 -->
@ -61,10 +59,7 @@
<template v-if="_file"> <template v-if="_file">
<div class="cl-upload__cover"> <div class="cl-upload__cover">
<!-- 图片 --> <!-- 图片 -->
<img <img v-if="_file.type == 'image'" :src="_file.url" />
v-if="_file.type == 'image'"
:src="_file.url"
/>
<!-- 文件名 --> <!-- 文件名 -->
<span v-else>{{ _file.name }}</span> <span v-else>{{ _file.name }}</span>
@ -73,8 +68,8 @@
<!-- 功能按钮 --> <!-- 功能按钮 -->
<div class="cl-upload__actions"> <div class="cl-upload__actions">
<span <span
class="cl-upload__actions-preview"
v-if="_file.type == 'image'" v-if="_file.type == 'image'"
class="cl-upload__actions-preview"
@click.stop="_onPreview(_file)" @click.stop="_onPreview(_file)"
> >
<i class="el-icon-zoom-in"></i> <i class="el-icon-zoom-in"></i>
@ -92,9 +87,7 @@
<!-- 空态 --> <!-- 空态 -->
<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">{{ <span v-if="_text" class="cl-upload__text">{{ _text }}</span>
_text
}}</span>
</template> </template>
</template> </template>
</slot> </slot>
@ -102,10 +95,10 @@
</div> </div>
<cl-dialog <cl-dialog
title="图片预览"
v-model="preview.visible" v-model="preview.visible"
title="图片预览"
:props="{ :props="{
width: previewWidth, width: previewWidth
}" }"
> >
<img style="width: 100%" :src="preview.url" alt="" /> <img style="width: 100%" :src="preview.url" alt="" />
@ -133,19 +126,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,
@ -160,7 +153,7 @@ export default {
// //
showFileList: { showFileList: {
type: Boolean, type: Boolean,
default: undefined, default: undefined
}, },
// //
drag: Boolean, drag: Boolean,
@ -169,12 +162,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,
@ -197,7 +190,7 @@ export default {
// //
beforeUpload: Function, beforeUpload: Function,
// //
beforeRemove: Function, beforeRemove: Function
}, },
emits: ["update:modelValue", "change"], emits: ["update:modelValue", "change"],
@ -209,8 +202,8 @@ export default {
loading: false, loading: false,
preview: { preview: {
visible: false, visible: false,
url: null, url: null
}, }
}; };
}, },
@ -278,7 +271,7 @@ 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
@ -304,26 +297,24 @@ export default {
arr = [this._size, this._size]; arr = [this._size, this._size];
} }
const [height, width] = arr.map((e) => const [height, width] = arr.map((e) => (isNumber(e) ? `${e}px` : 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: {
@ -353,7 +344,7 @@ export default {
return { return {
url, url,
name: basename(url), name: basename(url),
uid: url, uid: url
}; };
}); });
@ -423,9 +414,7 @@ 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.$message.error(`上传文件大小不能超过 ${this._limitSize}MB!`);
`上传文件大小不能超过 ${this._limitSize}MB!`
);
this.done(); this.done();
return false; return false;
} }
@ -433,7 +422,7 @@ export default {
if (this.beforeUpload) { if (this.beforeUpload) {
return this.beforeUpload(file, { return this.beforeUpload(file, {
done: this.done, done: this.done
}); });
} }
@ -447,7 +436,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
}); });
// //
@ -476,10 +465,7 @@ export default {
// uuid // uuid
if (this._rename) { if (this._rename) {
fileName = fileName = uuidv4() + "." + last((file.name || "").split("."));
uuidv4() +
"." +
last((file.name || "").split("."));
} }
data.append("key", `app/${fileName}`); data.append("key", `app/${fileName}`);
@ -491,17 +477,15 @@ 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.percent = parseInt((e.loaded / e.total) * 100);
(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") {
@ -517,7 +501,7 @@ export default {
if (mode == "local") { if (mode == "local") {
next({ next({
host: "/upload", host: "/upload"
}); });
} else { } else {
this.$service.common this.$service.common
@ -553,8 +537,8 @@ 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

@ -9,7 +9,7 @@
<div class="cl-upload-space-category__search"> <div class="cl-upload-space-category__search">
<el-button type="primary" size="mini" @click="edit()">添加分类</el-button> <el-button type="primary" size="mini" @click="edit()">添加分类</el-button>
<el-input v-model="keyword" placeholder="输入关键字过滤" size="mini"></el-input> <el-input v-model="keyword" placeholder="输入关键字过滤" size="mini" />
</div> </div>
<div class="cl-upload-space-category__list"> <div class="cl-upload-space-category__list">
@ -28,7 +28,7 @@
</ul> </ul>
</div> </div>
<cl-form ref="form"></cl-form> <cl-form ref="form" />
</div> </div>
</template> </template>
@ -39,11 +39,13 @@ import { isEmpty } from "/@/core/utils";
export default { export default {
name: "cl-upload-space-category", name: "cl-upload-space-category",
inject: ["space"],
props: { props: {
modelValue: [Number] modelValue: [Number]
}, },
inject: ["space"], emits: ["update:modelValue", "change"],
data() { data() {
return { return {
@ -57,7 +59,7 @@ export default {
...mapGetters(["browser"]), ...mapGetters(["browser"]),
flist() { flist() {
return this.list.filter(e => e.name.includes(this.keyword)); return this.list.filter((e) => e.name.includes(this.keyword));
} }
}, },
@ -77,7 +79,7 @@ export default {
methods: { methods: {
// //
refresh() { refresh() {
return this.$service.space.type.list().then(res => { return this.$service.space.type.list().then((res) => {
res.unshift({ res.unshift({
name: "全部文件", name: "全部文件",
id: null id: null
@ -131,7 +133,7 @@ export default {
next.then(() => { next.then(() => {
this.refresh(); this.refresh();
close(); close();
}).catch(err => { }).catch((err) => {
this.$message.error(err); this.$message.error(err);
done(); done();
}); });
@ -195,7 +197,7 @@ export default {
this.refresh(); this.refresh();
}) })
.catch(err => { .catch((err) => {
this.$message.error(err); this.$message.error(err);
}); });
}) })

View File

@ -14,7 +14,7 @@
<template v-else> <template v-else>
<!-- 图片 --> <!-- 图片 -->
<template v-if="type === 'image'"> <template v-if="type === 'image'">
<el-image fit="cover" :src="value.url" lazy></el-image> <el-image fit="cover" :src="value.url" lazy />
</template> </template>
<!-- 视频 --> <!-- 视频 -->
@ -39,7 +39,7 @@
<div class="cl-upload-space-item__size"></div> <div class="cl-upload-space-item__size"></div>
<!-- 遮罩层 --> <!-- 遮罩层 -->
<div class="cl-upload-space-item__mask" v-if="isSelected"> <div v-if="isSelected" class="cl-upload-space-item__mask">
<span>{{ index + 1 }}</span> <span>{{ index + 1 }}</span>
</div> </div>
</div> </div>
@ -49,15 +49,17 @@
export default { export default {
name: "cl-upload-space-item", name: "cl-upload-space-item",
inject: ["space"],
props: { props: {
value: Object value: Object
}, },
inject: ["space"], emits: ["select", "remove"],
computed: { computed: {
index() { index() {
return this.space.selection.findIndex(e => e.id === this.value.id); return this.space.selection.findIndex((e) => e.id === this.value.id);
}, },
isSelected() { isSelected() {

View File

@ -1,22 +1,20 @@
<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 v-if="showButton" size="mini" @click="open">点击上传</el-button>
>点击上传</el-button
>
</slot> </slot>
<!-- 弹框 --> <!-- 弹框 -->
<cl-dialog <cl-dialog
v-model="visible"
title="文件空间" title="文件空间"
height="630px" height="630px"
width="1000px" width="1000px"
keep-alive keep-alive
v-model="visible"
: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']"
> >
@ -28,9 +26,7 @@
<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 size="mini" @click="refresh()">刷新</el-button>
>刷新</el-button
>
<cl-upload <cl-upload
style="margin: 0 10px" style="margin: 0 10px"
@ -48,9 +44,7 @@
:on-progress="onProgress" :on-progress="onProgress"
:before-upload="beforeUpload" :before-upload="beforeUpload"
> >
<el-button size="mini" type="primary" <el-button size="mini" type="primary">点击上传</el-button>
>点击上传</el-button
>
</cl-upload> </cl-upload>
<el-button <el-button
@ -72,8 +66,8 @@
<!-- 文件区域 --> <!-- 文件区域 -->
<div <div
class="cl-upload-space__file scroller1"
v-loading="loading" v-loading="loading"
class="cl-upload-space__file scroller1"
element-loading-text="拼命加载中" element-loading-text="拼命加载中"
> >
<!-- 文件列表 --> <!-- 文件列表 -->
@ -82,17 +76,17 @@
<file-item <file-item
v-for="item in list" v-for="item in list"
:key="item.id" :key="item.id"
v-loading="item.loading"
:value="item" :value="item"
:element-loading-text="item.progress" :element-loading-text="item.progress"
v-loading="item.loading"
@select="select" @select="select"
@remove="remove" @remove="remove"
></file-item> />
</div> </div>
</template> </template>
<!-- 空态 --> <!-- 空态 -->
<div class="cl-upload-space__file-empty" v-else> <div v-else class="cl-upload-space__file-empty">
<cl-upload <cl-upload
drag drag
:action="action" :action="action"
@ -127,7 +121,7 @@
refresh({ page }); refresh({ page });
} }
" "
></el-pagination> />
</div> </div>
</div> </div>
</div> </div>
@ -136,15 +130,11 @@
<template #slot-expand> <template #slot-expand>
<button> <button>
<i <i
class="el-icon-notebook-2"
v-if="category.visible" v-if="category.visible"
class="el-icon-notebook-2"
@click="category.visible = false" @click="category.visible = false"
></i> ></i>
<i <i v-else class="el-icon-arrow-left" @click="category.visible = true"></i>
class="el-icon-arrow-left"
v-else
@click="category.visible = true"
></i>
</button> </button>
</template> </template>
</cl-dialog> </cl-dialog>
@ -160,18 +150,29 @@ import { mapGetters } from "vuex";
export default { export default {
name: "cl-upload-space", name: "cl-upload-space",
components: {
Category,
FileItem
},
provide() {
return {
space: this
};
},
props: { props: {
// //
action: String, action: String,
// //
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,
@ -188,20 +189,11 @@ export default {
// //
showButton: { showButton: {
type: Boolean, type: Boolean,
default: true, default: true
}, }
}, },
components: { emits: ["update:modelValue", "confirm"],
Category,
FileItem,
},
provide() {
return {
space: this,
};
},
data() { data() {
return { return {
@ -209,15 +201,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
}, }
}; };
}, },
@ -230,7 +222,7 @@ export default {
isSelected() { isSelected() {
return !isEmpty(this.selection); return !isEmpty(this.selection);
}, }
}, },
watch: { watch: {
@ -238,8 +230,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: {
@ -267,7 +259,7 @@ 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;
@ -297,7 +289,7 @@ export default {
uid, uid,
classifyId: this.category.id, classifyId: this.category.id,
loading: true, loading: true,
progress: "0%", progress: "0%"
}); });
}, },
@ -322,7 +314,7 @@ 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;
@ -370,7 +362,7 @@ export default {
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("删除成功");
@ -386,15 +378,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>

View File

@ -66,19 +66,14 @@ export function cloneDeep(obj: any) {
} }
export function clone(obj: any) { export function clone(obj: any) {
return Object.create( return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
);
} }
export function deepMerge(a: any, b: any) { export function deepMerge(a: any, b: any) {
let k; let k;
for (k in b) { for (k in b) {
a[k] = a[k] =
a[k] && a[k].toString() === "[object Object]" a[k] && a[k].toString() === "[object Object]" ? deepMerge(a[k], b[k]) : (a[k] = b[k]);
? deepMerge(a[k], b[k])
: (a[k] = b[k]);
} }
return a; return a;
} }
@ -97,14 +92,7 @@ export function getUrlParam(name: string) {
export function isPc() { export function isPc() {
const userAgentInfo = navigator.userAgent; const userAgentInfo = navigator.userAgent;
const Agents = [ const Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
"Android",
"iPhone",
"SymbianOS",
"Windows Phone",
"iPad",
"iPod",
];
let flag = true; let flag = true;
for (let v = 0; v < Agents.length; v++) { for (let v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) { if (userAgentInfo.indexOf(Agents[v]) > 0) {
@ -132,9 +120,7 @@ export function getBrowser() {
let tag = ""; let tag = "";
const isTocuh = const isTocuh =
"ontouchstart" in window || "ontouchstart" in window || ua.indexOf("touch") !== -1 || ua.indexOf("mobile") !== -1;
ua.indexOf("touch") !== -1 ||
ua.indexOf("mobile") !== -1;
if (isTocuh) { if (isTocuh) {
if (ua.indexOf("ipad") !== -1) { if (ua.indexOf("ipad") !== -1) {
tag = "pad"; tag = "pad";
@ -173,10 +159,7 @@ export function getBrowser() {
} }
// 操作平台 // 操作平台
const plat = const plat = ua.indexOf("android") > 0 ? "android" : navigator.platform.toLowerCase();
ua.indexOf("android") > 0
? "android"
: navigator.platform.toLowerCase();
// 屏幕信息 // 屏幕信息
let screen = "full"; let screen = "full";
@ -220,7 +203,7 @@ export function getBrowser() {
isIOS, isIOS,
isPC, isPC,
isMini, isMini,
screen, screen
}; };
} }
@ -234,7 +217,7 @@ export function href(path: string, newWindow?: boolean) {
let url = ""; let url = "";
if (routerMode == "history") { if (routerMode == "history") {
url = origin + path; url = origin + import.meta.env.BASE_URL + path.substr(1);
} else { } else {
url = origin + search + "#" + path; url = origin + search + "#" + path;
} }
@ -254,9 +237,9 @@ export function deepTree(list: Array<any>) {
const newList: Array<any> = []; const newList: Array<any> = [];
const map: any = {}; const map: any = {};
list.forEach((e) => (map[e.id] = e)); list.forEach(e => (map[e.id] = e));
list.forEach((e) => { list.forEach(e => {
const parent = map[e.parentId]; const parent = map[e.parentId];
if (parent) { if (parent) {
@ -267,7 +250,7 @@ export function deepTree(list: Array<any>) {
}); });
const fn = (list: Array<any>) => { const fn = (list: Array<any>) => {
list.map((e) => { list.map(e => {
if (e.children instanceof Array) { if (e.children instanceof Array) {
e.children = orderBy(e.children, "orderNum"); e.children = orderBy(e.children, "orderNum");
@ -286,7 +269,7 @@ export function revDeepTree(list: Array<any> = []) {
let id = 0; let id = 0;
const deep = (list: Array<any>, parentId: any) => { const deep = (list: Array<any>, parentId: any) => {
list.forEach((e) => { list.forEach(e => {
if (!e.id) { if (!e.id) {
e.id = id++; e.id = id++;
} }

View File

@ -345,8 +345,7 @@
position: absolute; position: absolute;
bottom: -1px; bottom: -1px;
left: 0; left: 0;
transition: transform 0.3s ease-in-out, transition: transform 0.3s ease-in-out, width 0.2s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
width 0.2s 0.1s cubic-bezier(0.645, 0.045, 0.355, 1);
} }
} }

View File

@ -128,7 +128,7 @@ export default defineComponent({
// 添加到 body 下 // 添加到 body 下
document.body.appendChild(refs.value["context-menu"]); document.body.appendChild(refs.value["context-menu"]);
// 关闭事件 // 关闭事件
(document.documentElement || document.body).addEventListener("mousedown", e => { (document.documentElement || document.body).addEventListener("mousedown", (e) => {
const el = refs.value["context-menu"]; const el = refs.value["context-menu"];
if (!contains(el, e.target) && el != e.target) { if (!contains(el, e.target) && el != e.target) {
close(); close();
@ -156,7 +156,7 @@ export default defineComponent({
return ( return (
<div class={["cl-context-menu__box", level > 1 && "is-append"]}> <div class={["cl-context-menu__box", level > 1 && "is-append"]}>
{list {list
.filter(e => !e.hidden) .filter((e) => !e.hidden)
.map((e, i) => { .map((e, i) => {
const id = `${pId}-${i}`; const id = `${pId}-${i}`;

View File

@ -40,7 +40,7 @@ export default defineComponent({
function update(val: string | number) { function update(val: string | number) {
nextTick(() => { nextTick(() => {
const index = list.value.findIndex(e => e.value === val); const index = list.value.findIndex((e) => e.value === val);
const item = refs.value[`tab-${index}`]; const item = refs.value[`tab-${index}`];
// 下划线位置 // 下划线位置

View File

@ -341,7 +341,7 @@ export default defineComponent({
{/* Form item */} {/* Form item */}
<div class="cl-form-item"> <div class="cl-form-item">
{["prepend", "component", "append"].map( {["prepend", "component", "append"].map(
name => { (name) => {
return ( return (
e[name] && ( e[name] && (
<div <div

View File

@ -42,7 +42,7 @@ export default {
// 默认选择 // 默认选择
list.value = (props.list || []).map((e: any) => { list.value = (props.list || []).map((e: any) => {
e.active = arr.some(v => v === e.value); e.active = arr.some((v) => v === e.value);
return e; return e;
}); });
}; };
@ -105,7 +105,7 @@ export default {
<button <button
class={{ "is-active": item.active }} class={{ "is-active": item.active }}
key={index} key={index}
onClick={event => { onClick={(event) => {
ctx.selectItem(event, item); ctx.selectItem(event, item);
}}> }}>
<span>{item.label}</span> <span>{item.label}</span>

View File

@ -200,7 +200,7 @@ export default defineComponent({
} }
} }
}) })
.filter(e => Boolean(e) && !e.hidden); .filter((e) => Boolean(e) && !e.hidden);
// 打开菜单 // 打开菜单
if (list.length > 0) { if (list.length > 0) {

View File

@ -16,7 +16,7 @@ export function useFormApi({ refs }: any) {
"clearValidate", "clearValidate",
"validateField", "validateField",
"validate" "validate"
].forEach(e => { ].forEach((e) => {
apis[e] = (...args: any[]) => { apis[e] = (...args: any[]) => {
return refs.value.form[e](...args); return refs.value.form[e](...args);
}; };

View File

@ -118,7 +118,7 @@ export default defineComponent({
// 打开表单 // 打开表单
function open() { function open() {
return new Promise(resolve => { return new Promise((resolve) => {
if (!refs.value.form) { if (!refs.value.form) {
return false; return false;
} }

View File

@ -16,11 +16,7 @@ const parseNode = (vnode: any, options: any) => {
if (rn) { if (rn) {
return rn({ scope }); return rn({ scope });
} else { } else {
return ( return <cl-error-message title={`组件渲染失败,未找到插槽:${vnode.name}`} />;
<cl-error-message
title={`组件渲染失败,未找到插槽:${vnode.name}`}
/>
);
} }
} }
@ -41,7 +37,7 @@ const parseNode = (vnode: any, options: any) => {
const props = { const props = {
...vnode, ...vnode,
...vnode.attrs, ...vnode.attrs,
...vnode.props, ...vnode.props
}; };
delete props._children; delete props._children;
@ -50,7 +46,7 @@ const parseNode = (vnode: any, options: any) => {
return h(resolveComponent(vnode.name), props, { return h(resolveComponent(vnode.name), props, {
default: () => { default: () => {
return vnode._children; return vnode._children;
}, }
}); });
}; };
@ -107,37 +103,21 @@ export function renderNode(vnode: any, { prop, scope, slots }: any) {
} }
return ( return (
<el-option <el-option key={i} label={label} value={value} {...e.props} />
key={i}
label={label}
value={value}
{...e.props}
/>
); );
} }
// 单选框组 // 单选框组
else if (vnode.name == "el-radio-group") { else if (vnode.name == "el-radio-group") {
return h( return h(<el-radio key={i} label={e.value}></el-radio>, e.props, {
<el-radio
key={i}
label={e.value}
></el-radio>,
e.props,
{
default() { default() {
return <span>{e.label}</span>; return <span>{e.label}</span>;
},
} }
); });
} }
// 多选框组 // 多选框组
else if (vnode.name == "el-checkbox-group") { else if (vnode.name == "el-checkbox-group") {
return ( return (
<el-checkbox <el-checkbox key={i} label={e.value} {...e.props}>
key={i}
label={e.value}
{...e.props}
>
{e.label} {e.label}
</el-checkbox> </el-checkbox>
); );
@ -153,9 +133,7 @@ export function renderNode(vnode: any, { prop, scope, slots }: any) {
return parseNode(vnode, { prop, scope, slots }); return parseNode(vnode, { prop, scope, slots });
} }
} else { } else {
return ( return <cl-error-message title={`组件渲染失败,组件 name 不能为空`} />;
<cl-error-message title={`组件渲染失败,组件 name 不能为空`} />
);
} }
} }
} }

View File

@ -3,15 +3,15 @@
<div class="page-layout__mask" @click="collapseMenu(true)"></div> <div class="page-layout__mask" @click="collapseMenu(true)"></div>
<div class="page-layout__left"> <div class="page-layout__left">
<slider></slider> <slider />
</div> </div>
<div class="page-layout__right"> <div class="page-layout__right">
<div class="page-layout__topbar"> <div class="page-layout__topbar">
<topbar></topbar> <topbar />
</div> </div>
<div class="page-layout__process" v-if="app.conf.showProcess"> <div v-if="app.conf.showProcess" class="page-layout__process">
<cl-process /> <cl-process />
</div> </div>

View File

@ -6,7 +6,7 @@
</div> </div>
<div class="app-slider__menu"> <div class="app-slider__menu">
<cl-menu-slider></cl-menu-slider> <cl-menu-slider />
</div> </div>
</div> </div>
</template> </template>

View File

@ -1,18 +1,16 @@
<template> <template>
<div class="app-topbar"> <div class="app-topbar">
<div class="app-topbar__collapse" @click="collapse"> <div class="app-topbar__collapse" @click="collapse">
<i <i :class="[menuCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold']"></i>
:class="[menuCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold']"
></i>
</div> </div>
<!-- 一级菜单 --> <!-- 一级菜单 -->
<div class="app-topbar__menu" v-if="app.conf.showAMenu"> <div v-if="app.conf.showAMenu" class="app-topbar__menu">
<cl-menu-topbar /> <cl-menu-topbar />
</div> </div>
<!-- 路由导航 --> <!-- 路由导航 -->
<div class="app-topbar__route-nav" v-if="app.conf.showRouteNav"> <div v-if="app.conf.showRouteNav" class="app-topbar__route-nav">
<cl-route-nav /> <cl-route-nav />
</div> </div>
@ -33,21 +31,15 @@
<!-- 用户信息 --> <!-- 用户信息 -->
<div class="app-topbar__user"> <div class="app-topbar__user">
<el-dropdown <el-dropdown trigger="click" :hide-on-click="false" @command="onCommand">
trigger="click" <span v-if="userInfo" class="el-dropdown-link">
:hide-on-click="false"
@command="onCommand"
>
<span class="el-dropdown-link" v-if="userInfo">
<span class="name">{{ userInfo.nickName }}</span> <span class="name">{{ userInfo.nickName }}</span>
<img class="avatar" :src="userInfo.headImg" alt /> <img class="avatar" :src="userInfo.headImg" alt />
</span> </span>
<template #dropdown> <template #dropdown>
<el-dropdown-menu class="dropdown-menu__user"> <el-dropdown-menu class="dropdown-menu__user">
<el-dropdown-item command="my" <el-dropdown-item command="my">个人中心</el-dropdown-item>
>个人中心</el-dropdown-item
>
<el-dropdown-item command="exit">退出</el-dropdown-item> <el-dropdown-item command="exit">退出</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
@ -104,9 +96,9 @@ export default defineComponent({
modules, modules,
app, app,
onCommand, onCommand,
collapse, collapse
}; };
}, }
}); });
</script> </script>

View File

@ -2,7 +2,7 @@ import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
// 忽略规则 // 忽略规则
const ignore: any = { const ignore: any = {
token: ["/login", "/403", "/404", "/500", "/502"], token: ["/login", "/403", "/404", "/500", "/502"]
}; };
const routes: Array<RouteRecordRaw> = [ const routes: Array<RouteRecordRaw> = [
@ -14,20 +14,20 @@ const routes: Array<RouteRecordRaw> = [
{ {
path: "/", path: "/",
name: "数据统计", name: "数据统计",
component: () => import("/@/views/home/index.vue"), component: () => import("/@/views/home/index.vue")
}, }
], ]
}, },
{ {
path: "/:catchAll(.*)", path: "/:catchAll(.*)",
name: "404", name: "404",
redirect: "/404", redirect: "/404"
}, }
]; ];
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
routes, routes
}); });
export default router; export default router;

View File

@ -32,11 +32,11 @@ axios.interceptors.request.use(
const token = store.getters.token || ""; const token = store.getters.token || "";
if (config.url) { if (config.url) {
if (!ignore.token.some(e => config.url.includes(e))) { if (!ignore.token.some((e) => config.url.includes(e))) {
config.headers["Authorization"] = token; config.headers["Authorization"] = token;
} }
if (!ignore.NProgress.some(e => config.url.includes(e))) { if (!ignore.NProgress.some((e) => config.url.includes(e))) {
NProgress.start(); NProgress.start();
} }
} }
@ -68,13 +68,13 @@ axios.interceptors.request.use(
isRefreshing = true; isRefreshing = true;
store.dispatch("refreshToken").then((token: string) => { store.dispatch("refreshToken").then((token: string) => {
requests.forEach(cb => cb(token)); requests.forEach((cb) => cb(token));
requests = []; requests = [];
isRefreshing = false; isRefreshing = false;
}); });
} }
return new Promise(resolve => { return new Promise((resolve) => {
// 继续请求 // 继续请求
requests.push((token: string) => { requests.push((token: string) => {
// 重新设置 token // 重新设置 token
@ -87,14 +87,14 @@ axios.interceptors.request.use(
return config; return config;
}, },
error => { (error) => {
return Promise.reject(error); return Promise.reject(error);
} }
); );
// Response // Response
axios.interceptors.response.use( axios.interceptors.response.use(
res => { (res) => {
NProgress.done(); NProgress.done();
const { code, data, message } = res.data; const { code, data, message } = res.data;
@ -109,7 +109,7 @@ axios.interceptors.response.use(
return Promise.reject(message); return Promise.reject(message);
} }
}, },
async error => { async (error) => {
NProgress.done(); NProgress.done();
if (error.response) { if (error.response) {

View File

@ -5,7 +5,7 @@
</div> </div>
<div class="category-ratio__container"> <div class="category-ratio__container">
<v-chart :option="chartOption" autoresize></v-chart> <v-chart :option="chartOption" autoresize />
</div> </div>
</div> </div>
</template> </template>

View File

@ -7,7 +7,7 @@
</div> </div>
<div class="card__container"> <div class="card__container">
<el-progress :percentage="50" :stroke-width="8"></el-progress> <el-progress :percentage="50" :stroke-width="8" />
</div> </div>
<div class="card__footer"> <div class="card__footer">

View File

@ -7,7 +7,7 @@
</div> </div>
<div class="card__container"> <div class="card__container">
<v-chart :option="chartOption" autoresize></v-chart> <v-chart :option="chartOption" autoresize />
</div> </div>
<div class="card__footer"> <div class="card__footer">

View File

@ -7,7 +7,7 @@
</div> </div>
<div class="card__container"> <div class="card__container">
<v-chart :option="chartOption" autoresize></v-chart> <v-chart :option="chartOption" autoresize />
</div> </div>
<div class="card__footer"> <div class="card__footer">

View File

@ -19,7 +19,7 @@
</div> </div>
</div> </div>
<v-chart :option="chartOption" autoresize></v-chart> <v-chart :option="chartOption" autoresize />
</div> </div>
</el-col> </el-col>
@ -36,7 +36,7 @@
</div> </div>
</div> </div>
<v-chart :option="chartOption" autoresize></v-chart> <v-chart :option="chartOption" autoresize />
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -50,34 +50,34 @@
border: false, border: false,
'default-sort': { 'default-sort': {
prop: 'ud', prop: 'ud',
order: 'descending', order: 'descending'
}, }
}" }"
:context-menu="false" :context-menu="false"
:columns="[ :columns="[
{ {
label: '排名', label: '排名',
prop: 'index', prop: 'index',
width: 60, width: 60
}, },
{ {
label: '搜索关键词', label: '搜索关键词',
prop: 'keyWord', prop: 'keyWord',
'min-width': 100, 'min-width': 100
}, },
{ {
label: '用户数', label: '用户数',
prop: 'users', prop: 'users',
'min-width': 100, 'min-width': 100
}, },
{ {
label: '周涨幅', label: '周涨幅',
prop: 'ud', prop: 'ud',
sortable: 'custom', sortable: 'custom',
'min-width': 100, 'min-width': 100
}, }
]" ]"
></cl-table> />
</el-row> </el-row>
</cl-crud> </cl-crud>
</div> </div>
@ -96,7 +96,7 @@ export default defineComponent({
left: 0, left: 0,
top: 0, top: 0,
right: 0, right: 0,
bottom: 0, bottom: 0
}, },
xAxis: { xAxis: {
type: "category", type: "category",
@ -112,24 +112,24 @@ export default defineComponent({
"16:00", "16:00",
"18:00", "18:00",
"20:00", "20:00",
"22:00", "22:00"
], ],
boundaryGap: false, boundaryGap: false
}, },
yAxis: { yAxis: {
type: "value", type: "value",
splitLine: { splitLine: {
show: false, show: false
}, },
axisTick: { axisTick: {
show: false, show: false
}, },
axisLine: { axisLine: {
show: false, show: false
}, },
axisLabel: { axisLabel: {
show: false, show: false
}, }
}, },
series: [ series: [
{ {
@ -151,7 +151,7 @@ export default defineComponent({
"1100", "1100",
"1000", "1000",
"1118", "1118",
"1322", "1322"
], ],
areaStyle: { areaStyle: {
normal: { normal: {
@ -163,29 +163,29 @@ export default defineComponent({
[ [
{ {
offset: 0, offset: 0,
color: "#D1E5FF", color: "#D1E5FF"
}, },
{ {
offset: 1, offset: 1,
color: "#FFFFFF", color: "#FFFFFF"
}, }
], ],
false false
), )
}, }
}, },
itemStyle: { itemStyle: {
normal: { normal: {
color: "#4165d7", color: "#4165d7"
}, }
}, },
lineStyle: { lineStyle: {
normal: { normal: {
width: 2, width: 2
}, }
}, }
}, }
], ]
}); });
function onLoad({ ctx, app }: any) { function onLoad({ ctx, app }: any) {
@ -197,41 +197,41 @@ export default defineComponent({
index: 1, index: 1,
keyWord: "无线耳机", keyWord: "无线耳机",
users: 983, users: 983,
ud: 5, ud: 5
}, },
{ {
index: 1, index: 1,
keyWord: "运动耳机", keyWord: "运动耳机",
users: 763, users: 763,
ud: -3, ud: -3
}, },
{ {
index: 1, index: 1,
keyWord: "蓝牙音箱", keyWord: "蓝牙音箱",
users: 328, users: 328,
ud: 7, ud: 7
}, },
{ {
index: 1, index: 1,
keyWord: "4k显示屏", keyWord: "4k显示屏",
users: 144, users: 144,
ud: 4, ud: 4
}, },
{ {
index: 1, index: 1,
keyWord: "罗技 G530", keyWord: "罗技 G530",
users: 121, users: 121,
ud: -1, ud: -1
}, }
], ]
}); });
}, }
}).done(); }).done();
app.refresh(); app.refresh();
} }
return { chartOption, onLoad }; return { chartOption, onLoad };
}, }
}); });
</script> </script>

View File

@ -27,8 +27,7 @@
range-separator="至" range-separator="至"
start-placeholder="开始日期" start-placeholder="开始日期"
end-placeholder="结束日期" end-placeholder="结束日期"
> />
</el-date-picker>
</div> </div>
<ul class="sales-rank__list"> <ul class="sales-rank__list">

View File

@ -10,7 +10,7 @@
</div> </div>
<div class="tab-chart__container"> <div class="tab-chart__container">
<v-chart :option="chartOption" autoresize></v-chart> <v-chart :option="chartOption" autoresize />
</div> </div>
</div> </div>
</template> </template>
@ -20,9 +20,6 @@ import { defineComponent, reactive } from "vue";
import { isPc } from "/@/core/utils"; import { isPc } from "/@/core/utils";
export default defineComponent({ export default defineComponent({
data() {
return {};
},
setup() { setup() {
const barWidth = isPc() ? 25 : 15; const barWidth = isPc() ? 25 : 15;
const chartOption = reactive<any>({ const chartOption = reactive<any>({
@ -111,6 +108,9 @@ export default defineComponent({
return { return {
chartOption chartOption
}; };
},
data() {
return {};
} }
}); });
</script> </script>

View File

@ -3,22 +3,22 @@
<el-row :gutter="15"> <el-row :gutter="15">
<el-col :lg="6" :md="12" :xs="24"> <el-col :lg="6" :md="12" :xs="24">
<div class="card"> <div class="card">
<count-sales></count-sales> <count-sales />
</div> </div>
</el-col> </el-col>
<el-col :lg="6" :md="12" :xs="24"> <el-col :lg="6" :md="12" :xs="24">
<div class="card"> <div class="card">
<count-views></count-views> <count-views />
</div> </div>
</el-col> </el-col>
<el-col :lg="6" :md="12" :xs="24"> <el-col :lg="6" :md="12" :xs="24">
<div class="card"> <div class="card">
<count-paid></count-paid> <count-paid />
</div> </div>
</el-col> </el-col>
<el-col :lg="6" :md="12" :xs="24"> <el-col :lg="6" :md="12" :xs="24">
<div class="card"> <div class="card">
<count-effect></count-effect> <count-effect />
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -26,12 +26,12 @@
<el-row :gutter="15"> <el-row :gutter="15">
<el-col :lg="14" :xs="24"> <el-col :lg="14" :xs="24">
<div class="card"> <div class="card">
<tab-chart></tab-chart> <tab-chart />
</div> </div>
</el-col> </el-col>
<el-col :lg="10" :xs="24"> <el-col :lg="10" :xs="24">
<div class="card"> <div class="card">
<sales-rank></sales-rank> <sales-rank />
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -39,12 +39,12 @@
<el-row :gutter="15"> <el-row :gutter="15">
<el-col :lg="14" :sm="24"> <el-col :lg="14" :sm="24">
<div class="card card--last"> <div class="card card--last">
<hot-search></hot-search> <hot-search />
</div> </div>
</el-col> </el-col>
<el-col :lg="10" :sm="24"> <el-col :lg="10" :sm="24">
<div class="card card--last"> <div class="card card--last">
<category-ratio></category-ratio> <category-ratio />
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -71,8 +71,8 @@ export default defineComponent({
CountEffect, CountEffect,
TabChart, TabChart,
SalesRank, SalesRank,
HotSearch, HotSearch
}, }
}); });
</script> </script>

View File

@ -9,7 +9,11 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"esModuleInterop": true, "esModuleInterop": true,
"lib": ["esnext", "dom"], "lib": ["esnext", "dom"],
"types": ["vite/client", "vite-svg-loader"] "types": ["vite/client", "vite-svg-loader"],
"paths": {
"/@/*": ["./src/*"],
"/#/*": ["./types/*"]
}
}, },
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
} }

View File

@ -1,6 +1,6 @@
// @ts-nocheck // @ts-nocheck
import path from "path"; import path from "path";
import { defineConfig } from "vite"; import type { UserConfig, ConfigEnv } from 'vite';
import vue from "@vitejs/plugin-vue"; import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx"; import vueJsx from "@vitejs/plugin-vue-jsx";
import { svgBuilder } from "./src/core/utils/svg"; import { svgBuilder } from "./src/core/utils/svg";
@ -11,35 +11,47 @@ function resolve(dir: string) {
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default ({ command, mode }: ConfigEnv): UserConfig => {
return {
base: "/",
plugins: [vue(), vueJsx(), svgBuilder("./src/icons/svg/")], plugins: [vue(), vueJsx(), svgBuilder("./src/icons/svg/")],
resolve: { resolve: {
alias: { alias: {
"/@": resolve("src"), "/@": resolve("src"),
"/#": resolve("types"), "/#": resolve("types")
}, }
}, },
css: { css: {
preprocessorOptions: { preprocessorOptions: {
scss: { scss: {
additionalData: "@import './src/assets/css/common.scss';", additionalData: "@import './src/assets/css/common.scss';"
}, }
}, }
}, },
server: { server: {
port: 9000, port: 9000,
hmr: {
overlay: true,
},
proxy: { proxy: {
"/dev": { "/dev": {
target: "http://127.0.0.1:8001", target: "http://127.0.0.1:8001",
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/dev/, ""), rewrite: path => path.replace(/^\/dev/, "")
}, },
"/pro": { "/pro": {
target: "https://show.cool-admin.com", target: "https://show.cool-admin.com",
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/pro/, "/api"), rewrite: path => path.replace(/^\/pro/, "/api")
}
}
}, },
optimizeDeps: {
include: [
],
exclude: ['vue-demi'],
}, },
}, };
}); };

File diff suppressed because it is too large Load Diff

853
yarn.lock

File diff suppressed because it is too large Load Diff