diff --git a/package.json b/package.json
index e2d53a8..6a5e368 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "quasar-vue3-admin-template",
- "version": "0.0.1",
+ "version": "2.3.5",
"description": "A Quasar Project with Vue3 and have class API",
"productName": "Quasar Project",
"author": "dirk.he ",
@@ -19,7 +19,7 @@
"@fullcalendar/interaction": "^5.11.3",
"@fullcalendar/vue3": "^5.11.3",
"@quasar/extras": "^1.0.0",
- "axios": "^1.1.3",
+ "axios": "1.6.0",
"chart.js": "^4.0.1",
"codemirror": "^5.56.0",
"core-js": "^3.6.5",
@@ -29,11 +29,11 @@
"js-cookie": "^3.0.1",
"jsencrypt": "^3.2.1",
"json-editor-vue": "^0.9.2",
- "marked": "^2.0.0",
+ "marked": "4.0.10",
"path-browserify": "^1.0.1",
"path-to-regexp": "^6.2.1",
"prismjs": "^1.29.0",
- "quasar": "^2.6.0",
+ "quasar": "^2.14.2",
"sass.js": "^0.11.1",
"sha256": "^0.2.0",
"shepherd.js": "^11.0.1",
@@ -41,7 +41,7 @@
"uuid": "^9.0.0",
"vanilla-jsoneditor": "^0.9.2",
"vue": "^3.2.29",
- "vue-facing-decorator": "^2.1.12",
+ "vue-facing-decorator": "^3.0.3",
"vue-i18n": "^9.3.0-beta.6",
"vue-router": "^4.1.6",
"vue-shepherd": "^2.0.1",
@@ -74,7 +74,9 @@
"html-webpack-plugin": "^5.5.0",
"prettier": "^2.5.1",
"typescript": "^4.5.4",
- "vuex-module-decorators": "^2.0.0"
+ "vuex-module-decorators": "^2.0.0",
+ "sass": "1.69.7",
+ "sass-loader": "^12.3.0"
},
"browserslist": [
"last 10 Chrome versions",
diff --git a/src/App.vue b/src/App.vue
index bd54dc1..78afd2b 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -22,6 +22,10 @@ export default class myComponentApp extends Vue {
this.$q.dark.set(false);
document.querySelector('html')?.classList.remove('dark');
}
+ this.$globalMessage.show({
+ type: 'success',
+ content: '欢迎使用本系统',
+ });
const iconPath = path;
this.$q.iconMapFn = (iconName) => {
const icon = myIcons[iconName];
diff --git a/src/boot/main.ts b/src/boot/main.ts
index 5966276..1532004 100644
--- a/src/boot/main.ts
+++ b/src/boot/main.ts
@@ -1,57 +1,57 @@
-import * as directives from 'src/directives/index';
-import { boot } from 'quasar/wrappers';
-import { type Directive } from 'vue';
-import ElementPlus from 'element-plus';
-import 'src/router/permission';
-import 'element-plus/dist/index.css';
-import 'element-plus/theme-chalk/dark/css-vars.css';
-import vue3PhotoPreview from 'vue3-photo-preview';
-import 'vue3-photo-preview/dist/index.css';
-import globalMessage from 'src/utils/notify';
-import globalConfirm from 'src/utils/dialogConfirm';
-import 'src/utils/types';
-import VueSidePanel from 'vue3-side-panel';
-import 'vue3-side-panel/dist/vue3-side-panel.css';
-import { defaultFill } from 'src/utils/tools';
-import { date } from 'quasar';
-
-import { Platform } from 'quasar';
-export default boot(({ app }) => {
- // We globally register our directive with Vue;
- // Rememeber that all directives in Vue will start with 'v-'
- // but that should not be part of your directive name
- // https://vuejs.org/v2/guide/custom-directive.html
- // 'my-directive' will be used as 'v-my-directive'
- Object.keys(directives).forEach((key) => {
- app.directive(key, (directives as { [key: string]: Directive })[key]);
- });
- app.use(vue3PhotoPreview);
- app.use(VueSidePanel);
- app.use(ElementPlus);
- app.config.globalProperties.$globalMessage = globalMessage;
- app.config.globalProperties.$window = window;
- app.config.globalProperties.$globalConfirm = globalConfirm;
- app.config.globalProperties.defaultFill = defaultFill;
- app.config.globalProperties.parseTime = (time: number | string | null | undefined) => {
- let timeStamp = '';
- if (!time || String(time).length < 10) return '--';
- if (!/^\d+$/g.test(time.toString())) {
- if (String(time).indexOf('T') !== -1 && !Number.isNaN(new Date(time).getTimezoneOffset())) {
- const formattedString = date.formatDate(+new Date(time), 'YYYY-MM-DD HH:mm:ss');
- return formattedString;
- } else {
- if (/\d/.test(String(time))) {
- return String(time);
- } else {
- return '--';
- }
- }
- } else {
- if (String(time).length === 10) timeStamp = time += '000';
- else timeStamp = String(time);
- const formattedString = date.formatDate(Number(timeStamp), 'YYYY-MM-DD HH:mm:ss');
- return formattedString;
- }
- };
- document.querySelector('body')?.classList.add(Platform.is.platform);
-});
+import * as directives from 'src/directives/index';
+import { boot } from 'quasar/wrappers';
+import { type Directive } from 'vue';
+import ElementPlus from 'element-plus';
+import 'src/router/permission';
+import 'element-plus/dist/index.css';
+import 'element-plus/theme-chalk/dark/css-vars.css';
+import vue3PhotoPreview from 'vue3-photo-preview';
+import 'vue3-photo-preview/dist/index.css';
+import globalMessage from 'src/utils/notify';
+import globalConfirm from 'src/utils/dialogConfirm';
+import 'src/utils/types';
+import VueSidePanel from 'vue3-side-panel';
+import 'vue3-side-panel/dist/vue3-side-panel.css';
+import { defaultFill } from 'src/utils/tools';
+import { date } from 'quasar';
+
+import { Platform } from 'quasar';
+export default boot(({ app }) => {
+ // We globally register our directive with Vue;
+ // Rememeber that all directives in Vue will start with 'v-'
+ // but that should not be part of your directive name
+ // https://vuejs.org/v2/guide/custom-directive.html
+ // 'my-directive' will be used as 'v-my-directive'
+ Object.keys(directives).forEach((key) => {
+ app.directive(key, (directives as { [key: string]: Directive })[key]);
+ });
+ app.use(vue3PhotoPreview);
+ app.use(VueSidePanel);
+ app.use(ElementPlus);
+ app.config.globalProperties.$globalMessage = globalMessage;
+ app.config.globalProperties.$window = window;
+ app.config.globalProperties.$globalConfirm = globalConfirm;
+ app.config.globalProperties.defaultFill = defaultFill;
+ app.config.globalProperties.parseTime = (time: number | string | null | undefined) => {
+ let timeStamp = '';
+ if (!time || String(time).length < 10) return '--';
+ if (!/^\d+$/g.test(time.toString())) {
+ if (String(time).indexOf('T') !== -1 && !Number.isNaN(new Date(time).getTimezoneOffset())) {
+ const formattedString = date.formatDate(+new Date(time), 'YYYY-MM-DD HH:mm:ss');
+ return formattedString;
+ } else {
+ if (/\d/.test(String(time))) {
+ return String(time);
+ } else {
+ return '--';
+ }
+ }
+ } else {
+ if (String(time).length === 10) timeStamp = time += '000';
+ else timeStamp = String(time);
+ const formattedString = date.formatDate(Number(timeStamp), 'YYYY-MM-DD HH:mm:ss');
+ return formattedString;
+ }
+ };
+ document.querySelector('body')?.classList.add(Platform.is.platform);
+});
diff --git a/src/boot/register-component.ts b/src/boot/register-component.ts
index b89b80c..8879086 100644
--- a/src/boot/register-component.ts
+++ b/src/boot/register-component.ts
@@ -1,36 +1,36 @@
-// 文件: /src/boot/register-component.js
-import { boot } from 'quasar/wrappers';
-import MyBanner from 'src/components/myBanner/index.vue';
-import RightPanel from 'src/components/rightPanel/index.vue';
-import TextToInput from 'src/components/textToInput/index.vue';
-import MyTooltip from 'src/components/myTooltip/index.vue';
-import MyPagination from 'src/components/myPagination/index.vue';
-import MyDialog from 'src/components/myDialog/index.vue';
-import MyFormInput from 'src/components/myForm/input.vue';
-import MyFormSelect from 'src/components/myForm/select.vue';
-import MyFormMultipleSelect from 'src/components/myForm/multipleSelect.vue';
-import MyFormDateRange from 'src/components/myForm/dateRange.vue';
-import MyFormDateRangeWithTime from 'src/components/myForm/dateRangeWithTime.vue';
-import MyFormSlider from 'src/components/myForm/slider.vue';
-import MyFormRadio from 'src/components/myForm/radio.vue';
-import MyMaskInput from 'src/components/myForm/maskInput.vue';
-import MyTreeSelect from 'src/components/myForm/treeSelect.vue';
-
-// 我们使用Vue全局注册了我们的组件
-export default boot(({ app }) => {
- app.component('MyBanner', MyBanner);
- app.component('RightPanel', RightPanel);
- app.component('TextToInput', TextToInput);
- app.component('MyPagination', MyPagination);
- app.component('MyTooltip', MyTooltip);
- app.component('MyDialog', MyDialog);
- app.component('MyFormInput', MyFormInput);
- app.component('MyMaskInput', MyMaskInput);
- app.component('MyFormSelect', MyFormSelect);
- app.component('MyFormMultipleSelect', MyFormMultipleSelect);
- app.component('MyFormDateRange', MyFormDateRange);
- app.component('MyFormDateRangeWithTime', MyFormDateRangeWithTime);
- app.component('MyFormSlider', MyFormSlider);
- app.component('MyFormRadio', MyFormRadio);
- app.component('MyTreeSelect', MyTreeSelect);
-});
+// 文件: /src/boot/register-component.js
+import { boot } from 'quasar/wrappers';
+import MyBanner from 'src/components/myBanner/index.vue';
+import RightPanel from 'src/components/rightPanel/index.vue';
+import TextToInput from 'src/components/textToInput/index.vue';
+import MyTooltip from 'src/components/myTooltip/index.vue';
+import MyPagination from 'src/components/myPagination/index.vue';
+import MyDialog from 'src/components/myDialog/index.vue';
+import MyFormInput from 'src/components/myForm/input.vue';
+import MyFormSelect from 'src/components/myForm/select.vue';
+import MyFormMultipleSelect from 'src/components/myForm/multipleSelect.vue';
+import MyFormDateRange from 'src/components/myForm/dateRange.vue';
+import MyFormDateRangeWithTime from 'src/components/myForm/dateRangeWithTime.vue';
+import MyFormSlider from 'src/components/myForm/slider.vue';
+import MyFormRadio from 'src/components/myForm/radio.vue';
+import MyMaskInput from 'src/components/myForm/maskInput.vue';
+import MyTreeSelect from 'src/components/myForm/treeSelect.vue';
+
+// 我们使用Vue全局注册了我们的组件
+export default boot(({ app }) => {
+ app.component('MyBanner', MyBanner);
+ app.component('RightPanel', RightPanel);
+ app.component('TextToInput', TextToInput);
+ app.component('MyPagination', MyPagination);
+ app.component('MyTooltip', MyTooltip);
+ app.component('MyDialog', MyDialog);
+ app.component('MyFormInput', MyFormInput);
+ app.component('MyMaskInput', MyMaskInput);
+ app.component('MyFormSelect', MyFormSelect);
+ app.component('MyFormMultipleSelect', MyFormMultipleSelect);
+ app.component('MyFormDateRange', MyFormDateRange);
+ app.component('MyFormDateRangeWithTime', MyFormDateRangeWithTime);
+ app.component('MyFormSlider', MyFormSlider);
+ app.component('MyFormRadio', MyFormRadio);
+ app.component('MyTreeSelect', MyTreeSelect);
+});
diff --git a/src/components/confirmDialog/index.vue b/src/components/confirmDialog/index.vue
index 71992a6..ebf5513 100644
--- a/src/components/confirmDialog/index.vue
+++ b/src/components/confirmDialog/index.vue
@@ -1,115 +1,114 @@
-
-
-
-
-
- {{ getJsx(content) }}
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ {{ getJsx(content) }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/myDialog/index.vue b/src/components/myDialog/index.vue
index 65a64e1..5c83c8f 100644
--- a/src/components/myDialog/index.vue
+++ b/src/components/myDialog/index.vue
@@ -1,210 +1,244 @@
-
-
-
-
-
- {{ myDialogParams.title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ {{ myDialogParams.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/myFixedPage/index.vue b/src/components/myFixedPage/index.vue
index 1a71f44..8b93e2e 100644
--- a/src/components/myFixedPage/index.vue
+++ b/src/components/myFixedPage/index.vue
@@ -1,95 +1,95 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/src/components/myForm/dateRange.vue b/src/components/myForm/dateRange.vue
index de31b4c..a1bc29a 100644
--- a/src/components/myForm/dateRange.vue
+++ b/src/components/myForm/dateRange.vue
@@ -1,99 +1,110 @@
-
-
-
- {{ myDateData.rules.length ? '*' : '' }} {{ myDateData.label }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ {{ dateParams.required ? '*' : '' }} {{ dateParams.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/myForm/dateRangeWithTime.vue b/src/components/myForm/dateRangeWithTime.vue
index d22e23d..6922887 100644
--- a/src/components/myForm/dateRangeWithTime.vue
+++ b/src/components/myForm/dateRangeWithTime.vue
@@ -1,140 +1,201 @@
-
-
-
- {{ dateParams.rules.length ? '*' : '' }} {{ dateParams.label }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ {{ dateParams.required ? '*' : '' }} {{ dateParams.label }}
+
+
+
+
+
Start:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
End:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/myForm/input.vue b/src/components/myForm/input.vue
index af07a38..1986045 100644
--- a/src/components/myForm/input.vue
+++ b/src/components/myForm/input.vue
@@ -1,103 +1,105 @@
-
-
-
- {{ rules.length ? '*' : '' }} {{ label }}
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ {{ rules.length ? '*' : '' }} {{ label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/myForm/select.vue b/src/components/myForm/select.vue
index ad377e5..c707e8c 100644
--- a/src/components/myForm/select.vue
+++ b/src/components/myForm/select.vue
@@ -1,178 +1,153 @@
-
-
-
- {{ rules.length ? '*' : '' }} {{ label }}
-
-
-
0"
- @popup-hide="userInput ? popHide() : () => 0"
- @filter="filterFn"
- @input-value="inputValue"
- :spellcheck="false"
- autocapitalize="off"
- autocomplete="new-password"
- autocorrect="off"
- dense
- dropdown-icon="app:topbar-arrow-bottom"
- no-error-icon
- options-dense
- outlined
- emit-value
- map-options
- clear-icon="app:clear"
- >
-
-
- {{ inputSelectOptionBak.find((data) => String(data.value) === String(model))?.label ?? model }}
-
-
-
- {{ inputPlaceholder }}
-
-
-
-
-
-
- {{ scope.opt.label }}
- {{ scope.opt.description }}
-
-
-
-
-
-
-
-
-
-
+
+
+
+ {{ rules.length ? '*' : '' }} {{ label }}
+
+
+
+
+
+ {{ inputSelectOptionBak.find((data) => String(data.value) === String(model))?.label ?? model }}
+
+
+
+
+
+ {{ scope.opt.label }}
+
+
+ {{ scope.opt.description }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/myForm/treeSelect.vue b/src/components/myForm/treeSelect.vue
index e1c6679..61e6fb6 100644
--- a/src/components/myForm/treeSelect.vue
+++ b/src/components/myForm/treeSelect.vue
@@ -6,7 +6,6 @@
-
+
@@ -68,40 +67,35 @@ import { Component, Prop, Vue, Watch } from 'vue-facing-decorator';
export default class MyTreeSelectComponent extends Vue {
declare $refs: any;
@Prop({ default: {} }) option!: any;
+
@Watch('option.disable', { deep: true })
onDisablechange(newVal: boolean) {
this.disable = newVal;
}
+
@Watch('option.model', { deep: true })
onModelchange(newVal: string) {
this.model = newVal;
+ this.inputModel = this.inputSelectOptionBak.find((one: any) => one.value === this.model)?.label || '';
}
+
@Watch('option.classes')
onClassesChange(newVal: string) {
this.classes = newVal;
}
+
@Watch('option.rules', { deep: true })
onRulesChange(newVal: any[]) {
this.rules = newVal;
}
+
@Watch('option.label', { deep: true })
onLabelChange(newVal: string) {
this.label = newVal;
}
- mounted() {
- this.model = this.option.model;
- this.inputPlaceholder = this.option.inputPlaceholder ?? 'Please select';
- this.classes = this.option?.classes || '';
- this.rules = this.option.rules;
- this.label = this.option.label || '';
- this.inputSelectOptionBak = this.option.inputSelectOption;
- this.hint = this.option.hint;
- this.inputId = this.option.inputId;
- this.disable = this.option.disable || false;
- }
+
private globals = getCurrentInstance()!.appContext.config.globalProperties;
private model = '';
- private type = '';
private inputPlaceholder = '';
private classes = '';
private rules: any[] = [];
@@ -114,6 +108,20 @@ export default class MyTreeSelectComponent extends Vue {
private userInput: boolean = false;
private showPlaceholder = true;
private inputModel = '';
+
+ mounted() {
+ this.model = this.option.model;
+ this.inputPlaceholder = this.option.inputPlaceholder ?? 'Please select';
+ this.classes = this.option?.classes || '';
+ this.rules = this.option.rules;
+ this.label = this.option.label || '';
+ this.inputSelectOptionBak = this.option.inputSelectOption;
+ this.hint = this.option.hint;
+ this.inputId = this.option.inputId;
+ this.disable = this.option.disable || false;
+ this.inputModel = this.inputSelectOptionBak.find((one: any) => one.value === this.model)?.label || '';
+ }
+
/* event */
private menuItemClick(item: any) {
if (!item.children.length) {
@@ -122,22 +130,27 @@ export default class MyTreeSelectComponent extends Vue {
this.$emit('input', item.value);
}
}
+
private documentClickEvent(event: any) {
// 检查点击事件是否发生在目标元素之外
if (this.$refs.inputRef && !this.$refs.inputRef.$el.contains(event.target)) {
this.$refs.menuRef.hide();
}
}
+
private menuShow() {
document.addEventListener('click', this.documentClickEvent);
}
+
private menuHide() {
document.removeEventListener('click', this.documentClickEvent);
}
+
private inputFocus() {
this.inputValue(this.inputModel);
this.$refs.menuRef.show();
}
+
private inputValue(value: any) {
const inputSelectOptionBak = cloneDeep(this.inputSelectOptionBak);
if (!value) {
@@ -146,15 +159,14 @@ export default class MyTreeSelectComponent extends Vue {
return;
}
value = value.toLowerCase();
- let arr = inputSelectOptionBak.filter((one: any) => {
+ this.inputSelectOption = inputSelectOptionBak.filter((one: any) => {
if (one.label.toLowerCase().includes(value)) return true;
else {
one.children = one.children.filter((two: any) => {
if (two.label.toLowerCase().includes(value)) return true;
else {
two.children = two.children.filter((three: any) => {
- if (three.label.toLowerCase().includes(value)) return true;
- else return false;
+ return three.label.toLowerCase().includes(value);
});
return two.children.length;
}
@@ -162,7 +174,6 @@ export default class MyTreeSelectComponent extends Vue {
return one.children.length;
}
});
- this.inputSelectOption = arr;
}
}
diff --git a/src/components/myPagination/index.vue b/src/components/myPagination/index.vue
index 086e951..f8280dd 100644
--- a/src/components/myPagination/index.vue
+++ b/src/components/myPagination/index.vue
@@ -1,93 +1,141 @@
-
-
-
-
{{ $t('table.total') }} {{ _paginationParams.rowsNumber }}
-
-
-
-
-
-
-
-
-
+
+
+
+
{{ $t('table.total') }} {{ _paginationParams.rowsNumber }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/css/lib/_utils.scss b/src/css/lib/_utils.scss
index 4fb302d..9e47e3f 100644
--- a/src/css/lib/_utils.scss
+++ b/src/css/lib/_utils.scss
@@ -181,7 +181,7 @@
color: #ffffff !important;
}
.q-message-success-style {
- background-color: $primary;
+ background-color: $blue;
color: #ffffff !important;
}
.my-label {
diff --git a/src/css/reset-quasar.scss b/src/css/reset-quasar.scss
index f676521..b3d5d8f 100644
--- a/src/css/reset-quasar.scss
+++ b/src/css/reset-quasar.scss
@@ -117,11 +117,11 @@
.q-date__content {
.q-btn {
height: 30px;
- width: 30px;
+ min-width: 30px;
line-height: 30px;
- padding: 0;
+ padding: 0 4px;
&.q-btn--rectangle {
- border-radius: 3 !important;
+ border-radius: 3px !important;
}
}
}
@@ -162,6 +162,20 @@
}
}
}
+.pagination-currentPage-input{
+ max-width: 68px !important;
+ margin-top: 3px;
+ .q-field__inner{
+ .q-field__control{
+ height: 32px !important;
+ &:before{
+ border-radius: 8px;
+ border: 1px solid var(--my-grey-6);
+ }
+ }
+ }
+
+}
.q-field--outlined .q-field__control {
border-radius: 8px;
}
diff --git a/src/directives/disableClick/index.ts b/src/directives/disableClick/index.ts
new file mode 100644
index 0000000..e81ed4d
--- /dev/null
+++ b/src/directives/disableClick/index.ts
@@ -0,0 +1,12 @@
+import { Directive } from 'vue';
+
+export const disableClick: Directive = {
+ mounted(el, binding) {
+ const { value } = binding;
+ el.addEventListener('click', (e: any) => {
+ if (value) {
+ e.stopPropagation();
+ }
+ });
+ },
+};
diff --git a/src/directives/index.ts b/src/directives/index.ts
index 42ba822..48f8049 100644
--- a/src/directives/index.ts
+++ b/src/directives/index.ts
@@ -1,3 +1,5 @@
-export * from './permission';
-export * from './defaultFill';
-export * from './tooltip';
+export * from './permission';
+export * from './defaultFill';
+export * from './tooltip';
+export * from './disableClick';
+export * from './response-class';
diff --git a/src/directives/permission/index.ts b/src/directives/permission/index.ts
index 20c2ba9..d8c987c 100644
--- a/src/directives/permission/index.ts
+++ b/src/directives/permission/index.ts
@@ -1,24 +1,25 @@
-import router from 'src/router';
-import { UserModule } from 'src/store/modules/user';
-import { type Directive } from 'vue';
-
-/** 权限指令 */
-export const permission: Directive = {
- mounted(el, binding) {
- const { value } = binding;
- },
-};
-export const permissionReplace: Directive = {
- mounted(el, binding) {
- const { value } = binding;
- // if (!UserModule.pagePermissionId.includes(value)) {
- // el.innerHTML = '--';
- // el.setAttribute(
- // 'style',
- // 'color:#var(--q-dark);pointer-events: none;border:none;box-shadow:none'
- // );
- // } else {
- // return 0;
- // }
- },
-};
+import router from 'src/router';
+import { UserModule } from 'src/store/modules/user';
+import { type Directive } from 'vue';
+
+/** 权限指令 */
+export const permission: Directive = {
+ mounted(el, binding) {
+ const { value } = binding;
+ console.log(value);
+ },
+};
+export const permissionReplace: Directive = {
+ mounted(el, binding) {
+ const { value } = binding;
+ // if (!UserModule.pagePermissionId.includes(value)) {
+ // el.innerHTML = '--';
+ // el.setAttribute(
+ // 'style',
+ // 'color:#var(--q-dark);pointer-events: none;border:none;box-shadow:none'
+ // );
+ // } else {
+ // return 0;
+ // }
+ },
+};
diff --git a/src/directives/response-class/index.ts b/src/directives/response-class/index.ts
new file mode 100644
index 0000000..875da99
--- /dev/null
+++ b/src/directives/response-class/index.ts
@@ -0,0 +1,33 @@
+import { Directive } from 'vue';
+
+export const responseClass: Directive = {
+ mounted(el, binding) {
+ const { value } = binding;
+ const documentWidth = document.body.clientWidth;
+ let sm = 600;
+ let md = 960;
+ let lg = 1280;
+ let xl = 1920;
+ let allClass = value.split(' ');
+ let classList: any = [];
+ allClass.forEach((item: any) => {
+ let classItem = item.split(':');
+ classList.push(classItem);
+ });
+ let classObj: any = {};
+ classList.forEach((item: any) => {
+ classObj[item[0]] = item[1];
+ });
+ if (documentWidth < sm) {
+ classObj['sm'] && el.classList.add(classObj['sm']);
+ } else if (documentWidth < md) {
+ classObj['md'] && el.classList.add(classObj['md']);
+ } else if (documentWidth < lg) {
+ classObj['lg'] && el.classList.add(classObj['lg']);
+ } else if (documentWidth < xl) {
+ classObj['xl'] && el.classList.add(classObj['xl']);
+ } else {
+ classObj['xl'] && el.classList.add(classObj['xl']);
+ }
+ },
+};
diff --git a/src/layouts/components/AppMain.vue b/src/layouts/components/AppMain.vue
index 44c367e..92d0200 100644
--- a/src/layouts/components/AppMain.vue
+++ b/src/layouts/components/AppMain.vue
@@ -51,8 +51,6 @@ export default class AppMainComponent extends Vue {
}
-
-
diff --git a/src/layouts/components/Sidebar/index.vue b/src/layouts/components/Sidebar/index.vue
index 0a84508..13c3a49 100644
--- a/src/layouts/components/Sidebar/index.vue
+++ b/src/layouts/components/Sidebar/index.vue
@@ -154,7 +154,7 @@ export default class SidebarLogoComponent extends Vue {
color: var(--el-text-color-primary);
font-size: 14px !important;
.record {
- font-size: 3px;
+ font-size: 14px;
width: 3px;
height: 3px;
}
diff --git a/src/pages/components/md.vue b/src/pages/components/md.vue
index 355ae0b..b9b728f 100644
--- a/src/pages/components/md.vue
+++ b/src/pages/components/md.vue
@@ -1,52 +1,56 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/pages/table/beta.vue b/src/pages/table/beta.vue
index 507a3fc..032b616 100644
--- a/src/pages/table/beta.vue
+++ b/src/pages/table/beta.vue
@@ -1,1051 +1,1058 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Expand
-
-
- {{ col.label.indexOf('$') !== -1 ? $t(`table.${col.label.replace('$', '')}`) : col.label }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ col.value }}
-
-
-
- {{ tableParams.data.indexOf(props.row) + 1 }}
-
-
-
- {{ props.row.name }}
-
-
-
- {{ $t(`action.update`) }}
- {{ $t(`action.delete`) }}
-
- {{ $t(`action.more`) }}
-
-
-
-
- 123123
-
-
- 123123
-
-
- 123123
-
-
-
-
-
-
-
-
-
-
-
- Name:{{ props.row.name }}
- this is expand detail , it maybe json string or other special text
-
-
-
-
-
-
-
-
-
-
-
-
-
-
(dialogAddUpdateParams.params[item.model] = data)"
- />
- (dialogAddUpdateParams.params[item.model] = data)"
- />
- (dialogAddUpdateParams.params[item.endModel] = data)"
- @startInput="(data) => (dialogAddUpdateParams.params[item.startModel] = data)"
- />
- (dialogAddUpdateParams.params[item.model] = data)"
- />
- (dialogAddUpdateParams.params[item.model] = data)"
- />
- (dialogAddUpdateParams.params[item.model] = data)"
- />
- (dialogAddUpdateParams.params[item.model] = data)"
- >
-
-
- {{ index + 1 }}. {{ item }}
-
-
-
-
-
-
- (dialogAddUpdateParams.params[item.model] = data)"
- >
-
-
- {{ index + 1 }}. {{ item }}
-
-
-
-
-
-
- (dialogAddUpdateParams.params[item.model] = data)"
- >
-
-
-
-
-
-
-
-
-
-
-
- {{ item.label }}:
- {{ item.value }}
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Expand
+
+
+ {{ col.label.indexOf('$') !== -1 ? $t(`table.${col.label.replace('$', '')}`) : col.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ col.value }}
+
+
+
{{ tableParams.data.indexOf(props.row) + 1 }}
+
{{ props.row.name }}
+
+ {{ $t('action.update') }}
+ {{ $t('action.delete') }}
+
+ {{ $t(`action.more`) }}
+
+
+
+
+ 123123
+
+
+ 123123
+
+
+ 123123
+
+
+
+
+
+
+
+
+
+
+
+ Name:{{ props.row.name }}
+ this is expand detail , it maybe json string or other special text
+
+
+
+
+
+
+
+
+
+
+
+
+
+
(dialogAddUpdateParams.params[item.model] = data)"
+ />
+ (dialogAddUpdateParams.params[item.model] = data)"
+ />
+ (dialogAddUpdateParams.params[item.model] = data)"
+ />
+ (dialogAddUpdateParams.params[item.model] = data)"
+ />
+ (dialogAddUpdateParams.params[item.model] = data)"
+ />
+ (dialogAddUpdateParams.params[item.model] = data)"
+ />
+ (dialogAddUpdateParams.params[item.model] = data)"
+ >
+
+
+ {{ index + 1 }}. {{ item }}
+
+
+
+
+
+
+ (dialogAddUpdateParams.params[item.model] = data)"
+ >
+
+
+ {{ index + 1 }}. {{ item }}
+
+
+
+
+
+
+ (dialogAddUpdateParams.params[item.model] = data)"
+ >
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.label }}:
+
+ {{ item.value }}
+
+
+ {{ item.value }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/setting.json b/src/setting.json
index a49a004..613deab 100644
--- a/src/setting.json
+++ b/src/setting.json
@@ -4,7 +4,7 @@
"policy": "//github.com/dirkhe1051931999/quasar-typescript-admin-template/",
"publicPath": "/v3-admin/",
"pro": "",
- "version": "V2.3.4",
+ "version": "V2.3.5",
"devServerPort": 9002,
"ip": "",
"adminName": ["admin"],
diff --git a/src/store/modules/tags.ts b/src/store/modules/tags.ts
index c8563ca..a431711 100644
--- a/src/store/modules/tags.ts
+++ b/src/store/modules/tags.ts
@@ -1,19 +1,17 @@
-import {
- VuexModule,
- Module,
- Mutation,
- Action,
- getModule,
-} from 'vuex-module-decorators';
+import { VuexModule, Module, Mutation, Action, getModule } from 'vuex-module-decorators';
import { RouteLocationNormalized } from 'vue-router';
import store from 'src/store';
+
export type ITagsView = Partial;
+
export interface ITagsViewState {
visitedViews: ITagsView[];
}
+
@Module({ dynamic: true, namespaced: true, store, name: 'TagsView' })
class TagsView extends VuexModule {
public visitedViews: ITagsView[] = [];
+
@Mutation
private ADD_VISITED_VIEW(view: ITagsView) {
if (
@@ -31,6 +29,7 @@ class TagsView extends VuexModule {
}
this.visitedViews.push(Object.assign({}, view));
}
+
@Mutation
private DEL_VISITED_VIEW(view: ITagsView) {
for (const [i, v] of this.visitedViews.entries()) {
@@ -40,12 +39,14 @@ class TagsView extends VuexModule {
}
}
}
+
@Mutation
private DEL_OTHER_VISITED_VIEWS(view: ITagsView) {
this.visitedViews = this.visitedViews.filter((v) => {
return v.meta?.affix || v.path === view.path;
});
}
+
@Mutation
private DEL_ALL_VISITED_VIEWS() {
// keep affix tags
@@ -57,17 +58,21 @@ class TagsView extends VuexModule {
public addView(view: ITagsView) {
this.ADD_VISITED_VIEW(view);
}
+
@Action
public delView(view: ITagsView) {
this.DEL_VISITED_VIEW(view);
}
+
@Action
public delOtherViews(view: ITagsView) {
this.DEL_OTHER_VISITED_VIEWS(view);
}
+
@Action
public delAllViews() {
this.DEL_ALL_VISITED_VIEWS();
}
}
+
export const TagsViewModule = getModule(TagsView);
diff --git a/src/utils/dialogConfirm.ts b/src/utils/dialogConfirm.ts
index d02d968..debc454 100644
--- a/src/utils/dialogConfirm.ts
+++ b/src/utils/dialogConfirm.ts
@@ -1,37 +1,41 @@
-// globalConfirm.ts
-import { Dialog, DialogChainObject } from 'quasar';
-import ConfirmDialogComponent from 'src/components/confirmDialog/index.vue';
-type showParams = {
- title: string;
- color: string;
- content: string;
- confirmButtonText: string;
-};
-export interface IGlobalConfirm {
- show: (params: showParams) => Promise;
-}
-class GlobalConfirm {
- constructor() {}
- public async show({ title, color, content, confirmButtonText }: showParams) {
- return new Promise((resolve, reject) => {
- Dialog.create({
- component: ConfirmDialogComponent,
- cancel: true,
- componentProps: {
- title,
- color,
- content,
- confirmButtonText,
- },
- })
- .onOk(() => {
- return resolve(true);
- })
- .onCancel(() => {
- return resolve(false);
- });
- });
- }
-}
-
-export default new GlobalConfirm();
+// globalConfirm.ts
+import { Dialog, DialogChainObject } from 'quasar';
+import ConfirmDialogComponent from 'src/components/confirmDialog/index.vue';
+
+type showParams = {
+ title: string;
+ color: string;
+ content: string;
+ confirmButtonText: string;
+};
+
+export interface IGlobalConfirm {
+ show: (params: showParams) => Promise;
+}
+
+class GlobalConfirm {
+ constructor() {}
+
+ public async show({ title, color, content, confirmButtonText }: showParams) {
+ return new Promise((resolve, reject) => {
+ Dialog.create({
+ component: ConfirmDialogComponent,
+ cancel: true,
+ componentProps: {
+ title,
+ color,
+ content,
+ confirmButtonText,
+ },
+ })
+ .onOk(() => {
+ return resolve(true);
+ })
+ .onCancel(() => {
+ return resolve(false);
+ });
+ });
+ }
+}
+
+export default new GlobalConfirm();
diff --git a/src/utils/notify.ts b/src/utils/notify.ts
index 5ad09e9..ec6aaed 100644
--- a/src/utils/notify.ts
+++ b/src/utils/notify.ts
@@ -1,47 +1,52 @@
-//globalMessage.ts
-import { Notify, QNotifyCreateOptions } from 'quasar';
-import { useQuasar } from 'quasar';
-import { AppModule } from 'src/store/modules/app';
-type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top' | 'bottom' | 'left' | 'right' | 'center' | undefined;
-type showParams = {
- type: string;
- content: string;
- position?: Position;
- isNotify?: boolean;
-};
-export interface IGlobalMessage {
- show: (params: showParams) => void;
-}
-const DEFAULT_PARAMS: QNotifyCreateOptions = {
- timeout: 3000,
- html: true,
- progress: true,
- iconSize: '20px',
-};
-class GlobalMessage {
- constructor() {}
- public show({ type, content, position, isNotify }: showParams) {
- const data = Object.assign(DEFAULT_PARAMS, {
- message: content,
- position: position ?? 'top',
- multiLine: isNotify ?? false,
- icon: type === 'error' ? 'o_highlight_off' : type === 'warn' ? 'o_error_outline' : 'o_check_circle', // error warn success
- actions: isNotify
- ? [
- {
- color: 'white',
- label: AppModule.language === 'en-US' ? 'Close' : '关闭',
- },
- ]
- : [],
- classes: type === 'success' ? `q-message-${type}-style min-h-36 m-t-55` : `q-message-${type}-style min-h-36`,
- });
- try {
- Notify.create(data);
- } catch (error) {
- alert(data.message);
- }
- }
-}
-
-export default new GlobalMessage();
+//globalMessage.ts
+import { Notify, QNotifyCreateOptions } from 'quasar';
+import { useQuasar } from 'quasar';
+import { AppModule } from 'src/store/modules/app';
+
+type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top' | 'bottom' | 'left' | 'right' | 'center' | undefined;
+type showParams = {
+ type: string;
+ content: string;
+ position?: Position;
+ isNotify?: boolean;
+};
+
+export interface IGlobalMessage {
+ show: (params: showParams) => void;
+}
+
+const DEFAULT_PARAMS: QNotifyCreateOptions = {
+ timeout: 3000,
+ html: true,
+ progress: true,
+ iconSize: '20px',
+};
+
+class GlobalMessage {
+ constructor() {}
+
+ public show({ type, content, position, isNotify }: showParams) {
+ const data = Object.assign(DEFAULT_PARAMS, {
+ message: content,
+ position: position ?? 'top',
+ multiLine: isNotify ?? false,
+ icon: type === 'error' ? 'o_highlight_off' : type === 'warn' ? 'o_error_outline' : 'o_check_circle', // error warn success
+ actions: isNotify
+ ? [
+ {
+ color: 'white',
+ label: AppModule.language === 'en-US' ? 'Close' : '关闭',
+ },
+ ]
+ : [],
+ classes: type === 'success' ? `q-message-${type}-style min-h-36 m-t-55` : `q-message-${type}-style min-h-36`,
+ });
+ try {
+ Notify.create(data);
+ } catch (error) {
+ alert(data.message);
+ }
+ }
+}
+
+export default new GlobalMessage();
diff --git a/yarn.lock b/yarn.lock
index 02987c0..395b9c0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2175,10 +2175,10 @@ autoprefixer@^10.4.2:
picocolors "^1.0.0"
postcss-value-parser "^4.2.0"
-axios@^1.1.3:
- version "1.2.2"
- resolved "https://registry.npmjs.org/axios/-/axios-1.2.2.tgz"
- integrity sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==
+axios@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102"
+ integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
@@ -4057,6 +4057,11 @@ ignore@^5.1.9, ignore@^5.2.0:
resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz"
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
+immutable@^4.0.0:
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f"
+ integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==
+
import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
@@ -4581,10 +4586,10 @@ make-dir@^3.0.2, make-dir@^3.1.0:
dependencies:
semver "^6.0.0"
-marked@^2.0.0:
- version "2.1.3"
- resolved "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz"
- integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==
+marked@4.0.10:
+ version "4.0.10"
+ resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.10.tgz#423e295385cc0c3a70fa495e0df68b007b879423"
+ integrity sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw==
mdn-data@2.0.14:
version "2.0.14"
@@ -5475,10 +5480,10 @@ qs@6.11.0:
dependencies:
side-channel "^1.0.4"
-quasar@^2.6.0:
- version "2.11.4"
- resolved "https://registry.npmjs.org/quasar/-/quasar-2.11.4.tgz"
- integrity sha512-psE6R5pAyzkjpp7symrtuFug9LRPcuKne6C2XUdIUbomEzi0BiWcdxGesIqS+SUn7qrLIEFWVsvnCTAYSmqbyw==
+quasar@^2.14.2:
+ version "2.14.2"
+ resolved "https://registry.yarnpkg.com/quasar/-/quasar-2.14.2.tgz#794d8434eb449549fc8455aaec9bc14b71a57c98"
+ integrity sha512-f5KliWtM5BEuFsDU4yvuP+dlVIWZNrGu5VpWFsxzjpoykcP4B2HIOUiCl3mx2NCqERHd4Ts0aeioRkt9TTeExA==
queue-microtask@^1.2.2:
version "1.2.3"
@@ -5730,6 +5735,14 @@ sass-loader@12.4.0:
klona "^2.0.4"
neo-async "^2.6.2"
+sass-loader@^12.3.0:
+ version "12.6.0"
+ resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb"
+ integrity sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==
+ dependencies:
+ klona "^2.0.4"
+ neo-async "^2.6.2"
+
sass.js@^0.11.1:
version "0.11.1"
resolved "https://registry.npmjs.org/sass.js/-/sass.js-0.11.1.tgz"
@@ -5742,6 +5755,15 @@ sass@1.32.12:
dependencies:
chokidar ">=3.0.0 <4.0.0"
+sass@1.69.7:
+ version "1.69.7"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.7.tgz#6e7e1c8f51e8162faec3e9619babc7da780af3b7"
+ integrity sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==
+ dependencies:
+ chokidar ">=3.0.0 <4.0.0"
+ immutable "^4.0.0"
+ source-map-js ">=0.6.2 <2.0.0"
+
sax@1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz"
@@ -6008,7 +6030,7 @@ source-list-map@^2.0.0:
resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz"
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
-source-map-js@^1.0.2:
+"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
@@ -6480,10 +6502,10 @@ vue-eslint-parser@^9.0.1:
lodash "^4.17.21"
semver "^7.3.6"
-vue-facing-decorator@^2.1.12:
- version "2.1.13"
- resolved "https://registry.npmjs.org/vue-facing-decorator/-/vue-facing-decorator-2.1.13.tgz"
- integrity sha512-MQ8zzd/0upCvObrluJ/3jl4YrT9PP/1mcWx8A87lfVu2+Miv2D7lx3EWicF6Fx5Bl2DKrxjcrO3I6Ud5GxzT8A==
+vue-facing-decorator@^3.0.3:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/vue-facing-decorator/-/vue-facing-decorator-3.0.4.tgz#e005a8371aa4e3b4241fc20e7d8e8706dda209f6"
+ integrity sha512-Lk90PevJllB6qRRdLvLFjATZrv00nof1Ob6afavKL7Pc7V3eEin3vhdvEDRORdWKVvNoXhJbHejngWVuT0Pt0g==
vue-global-config@latest:
version "0.4.0"