!25 部分优化以及新增功能
Merge pull request !25 from ahaos/tspr
| | |
| | | { |
| | | "globals": { |
| | | "ComponentInternalInstance": true, |
| | | "TransferKey": true, |
| | | "ElFormRules": true, |
| | | "CheckboxValueType": true, |
| | | "PropType": true, |
| | | "DateModelType": true, |
| | | "UploadFile": true, |
| | | "ElFormInstance": true, |
| | | "ElTableInstance": true, |
| | | "ElTreeInstance": true, |
| | | "ElTreeSelectInstance": true, |
| | | "ElSelectInstance": true, |
| | | "ElUploadInstance": true, |
| | | "ElCardInstance": true, |
| | | "ElDialogInstance": true, |
| | | "ElInputInstance": true, |
| | | "ElInputNumberInstance": true, |
| | | "ElRadioInstance": true, |
| | | "ElRadioGroupInstance": true, |
| | | "ElRadioButtonInstance": true, |
| | | "ElCheckboxInstance": true, |
| | | "ElCheckboxGroupInstance": true, |
| | | "ElSwitchInstance": true, |
| | | "ElDatePickerInstance": true, |
| | | "ElTimePickerInstance": true, |
| | | "ElTimeSelectInstance": true, |
| | | "ElScrollbarInstance": true, |
| | | "ElCascaderInstance": true, |
| | | "ElColorPickerInstance": true, |
| | | "ElRateInstance": true, |
| | | "ElSliderInstance": true, |
| | | "useRouter": true, |
| | | "useRoute": true, |
| | | "EffectScope": true, |
| | |
| | | // å
³éç©ºç±»åæ£æ¥ {} |
| | | extendDefaults: true, |
| | | types: { |
| | | '{}': false |
| | | '{}': false, |
| | | 'Function': false |
| | | } |
| | | } |
| | | ] |
| | |
| | | "path-to-regexp": "6.2.0", |
| | | "pinia": "2.0.22", |
| | | "screenfull": "6.0.0", |
| | | "vform3-builds": "3.0.8", |
| | | "vue": "3.2.45", |
| | | "vue-cropper": "1.0.3", |
| | | "vue-i18n": "9.2.2", |
| | | "vue-router": "4.1.4" |
| | | "vue-router": "4.1.4", |
| | | "vue-types": "^5.0.3" |
| | | }, |
| | | "devDependencies": { |
| | | "@iconify/json": "^2.2.40", |
| | |
| | | "unplugin-auto-import": "0.13.0", |
| | | "unplugin-icons": "0.15.1", |
| | | "unplugin-vue-components": "0.23.0", |
| | | "vite": "4.3.1", |
| | | "vite-plugin-compression": "0.5.1", |
| | | "vite-plugin-svg-icons": "2.0.1", |
| | | "vite-plugin-vue-setup-extend": "^0.4.0", |
| | | "vitest": "^0.29.7", |
| | | "vite": "4.3.1", |
| | | "vue-eslint-parser": "9.1.0", |
| | | "vue-tsc": "0.35.0" |
| | | } |
| | |
| | | * æ¥è¯¢ç¨æ·å表 |
| | | * @param query |
| | | */ |
| | | export function listUser(query: UserQuery): AxiosPromise<UserVO[]> { |
| | | export const listUser = (query: UserQuery): AxiosPromise<UserVO[]> => { |
| | | return request({ |
| | | url: '/system/user/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * è·åç¨æ·è¯¦æ
|
| | | * @param userId |
| | | */ |
| | | export function getUser(userId?: string | number): AxiosPromise<UserInfoVO> { |
| | | export const getUser = (userId?: string | number): AxiosPromise<UserInfoVO> => { |
| | | return request({ |
| | | url: '/system/user/' + parseStrEmpty(userId), |
| | | method: 'get' |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * æ°å¢ç¨æ· |
| | | */ |
| | | export function addUser(data: UserForm) { |
| | | export const addUser = (data: UserForm) => { |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¨æ· |
| | | */ |
| | | export function updateUser(data: UserForm) { |
| | | export const updateUser = (data: UserForm) => { |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * å é¤ç¨æ· |
| | | * @param userId ç¨æ·ID |
| | | */ |
| | | export function delUser(userId: Array<string | number> | string | number) { |
| | | export const delUser = (userId: Array<string | number> | string | number) => { |
| | | return request({ |
| | | url: '/system/user/' + userId, |
| | | method: 'delete' |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * ç¨æ·å¯ç éç½® |
| | | * @param userId ç¨æ·ID |
| | | * @param password å¯ç |
| | | */ |
| | | export function resetUserPwd(userId: string | number, password: string) { |
| | | export const resetUserPwd = (userId: string | number, password: string) => { |
| | | const data = { |
| | | userId, |
| | | password |
| | |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * ç¨æ·ç¶æä¿®æ¹ |
| | | * @param userId ç¨æ·ID |
| | | * @param status ç¨æ·ç¶æ |
| | | */ |
| | | export function changeUserStatus(userId: number | string, status: string) { |
| | | export const changeUserStatus = (userId: number | string, status: string) => { |
| | | const data = { |
| | | userId, |
| | | status |
| | |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢ç¨æ·ä¸ªäººä¿¡æ¯ |
| | | */ |
| | | export function getUserProfile(): AxiosPromise<UserInfoVO> { |
| | | export const getUserProfile = (): AxiosPromise<UserInfoVO> => { |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'get' |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * ä¿®æ¹ç¨æ·ä¸ªäººä¿¡æ¯ |
| | | * @param data ç¨æ·ä¿¡æ¯ |
| | | */ |
| | | export function updateUserProfile(data: UserForm) { |
| | | export const updateUserProfile = (data: UserForm) => { |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * ç¨æ·å¯ç éç½® |
| | | * @param oldPassword æ§å¯ç |
| | | * @param newPassword æ°å¯ç |
| | | */ |
| | | export function updateUserPwd(oldPassword: string, newPassword: string) { |
| | | export const updateUserPwd = (oldPassword: string, newPassword: string) => { |
| | | const data = { |
| | | oldPassword, |
| | | newPassword |
| | |
| | | method: 'put', |
| | | params: data |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * ç¨æ·å¤´åä¸ä¼ |
| | | * @param data 头åæä»¶ |
| | | */ |
| | | export function uploadAvatar(data: FormData) { |
| | | export const uploadAvatar = (data: FormData) => { |
| | | return request({ |
| | | url: '/system/user/profile/avatar', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢ææè§è² |
| | | * @param userId ç¨æ·ID |
| | | */ |
| | | export function getAuthRole(userId: string | number): AxiosPromise<{ user: UserVO; roles: RoleVO[] }> { |
| | | export const getAuthRole = (userId: string | number): AxiosPromise<{ user: UserVO; roles: RoleVO[] }> => { |
| | | return request({ |
| | | url: '/system/user/authRole/' + userId, |
| | | method: 'get' |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * ä¿åææè§è² |
| | | * @param data ç¨æ·ID |
| | | */ |
| | | export function updateAuthRole(data: { userId: string; roleIds: string }) { |
| | | export const updateAuthRole = (data: { userId: string; roleIds: string }) => { |
| | | return request({ |
| | | url: '/system/user/authRole', |
| | | method: 'put', |
| | | params: data |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢é¨é¨ä¸ææ ç»æ |
| | | */ |
| | | export function deptTreeSelect(): AxiosPromise<DeptVO[]> { |
| | | export const deptTreeSelect = (): AxiosPromise<DeptVO[]> => { |
| | | return request({ |
| | | url: '/system/user/deptTree', |
| | | method: 'get' |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | export default { |
| | | listUser, |
| | | getUser, |
| | | addUser, |
| | | updateUser, |
| | | delUser, |
| | | resetUserPwd, |
| | | changeUserStatus, |
| | | getUserProfile, |
| | | updateUserProfile, |
| | | updateUserPwd, |
| | | uploadAvatar, |
| | | getAuthRole, |
| | | updateAuthRole, |
| | | deptTreeSelect |
| | | }; |
| | |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | html.dark .svg-icon, html.dark svg { |
| | | fill: var(--el-text-color-regular); |
| | | } |
| | | |
| | | #app { |
| | | height: 100%; |
| | | } |
| | |
| | | border: 1px solid var(--el-border-color-light); |
| | | background-color: var(--el-bg-color-overlay); |
| | | padding: 0.75rem; |
| | | transition: all ease 0.3s; |
| | | |
| | | &:hover { |
| | | box-shadow: 0 2px 12px #0000001a; |
| | |
| | | .el-table__fixed-header-wrapper { |
| | | th { |
| | | word-break: break-word; |
| | | background-color: #f8f8f9 !important; |
| | | color: #515a6e; |
| | | background-color: $table-header-bg !important; |
| | | color: $table-header-text-color; |
| | | height: 40px !important; |
| | | font-size: 13px; |
| | | } |
| | |
| | | .sub-menu-title-noDropdown, |
| | | .el-sub-menu__title { |
| | | &:hover { |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | background-color: $base-sub-menu-title-hover !important; |
| | | } |
| | | } |
| | | |
| | |
| | | .el-menu-item { |
| | | &:hover { |
| | | // you can use $sub-menuHover |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | background-color: $base-menu-hover !important; |
| | | } |
| | | } |
| | | |
| | |
| | | // å
¨å±SCSSåé |
| | | :root { |
| | | --menuBg: #304156; |
| | | --menuColor: #bfcbd9; |
| | | --menuActiveText: #f4f4f5; |
| | | --menuHover: #263445; |
| | | |
| | | --subMenuBg: #1f2d3d; |
| | | --subMenuActiveText: #f4f4f5; |
| | | --subMenuHover: #001528; |
| | | --subMenuTitleHover: #293444; |
| | | |
| | | --tableHeaderBg: #f8f8f9; |
| | | --tableHeaderTextColor: #515a6e; |
| | | } |
| | | html.dark { |
| | | --menuBg: #1d1e1f; |
| | | --menuColor: #bfcbd9; |
| | | --menuActiveText: #f4f4f5; |
| | | --menuHover: #171819; |
| | | |
| | | --subMenuBg: #1d1e1f; |
| | | --subMenuActiveText: #1d1e1f; |
| | | --subMenuHover: #171819; |
| | | --subMenuTitleHover: #171819; |
| | | |
| | | --tableHeaderBg: var(--el-bg-color); |
| | | --tableHeaderTextColor: var(--el-text-color); |
| | | |
| | | // è¦çele é«äº®å½åè¡çæ åæè² |
| | | .el-tree-node__content { |
| | | --el-color-primary-light-9: #262727; |
| | | } |
| | | } |
| | | |
| | | // base color |
| | | $blue: #324157; |
| | | $light-blue: #3a71a8; |
| | |
| | | $panGreen: #30b08f; |
| | | |
| | | // é»è®¤èå主é¢é£æ ¼ |
| | | $base-menu-color: #bfcbd9; |
| | | $base-menu-color-active: #f4f4f5; |
| | | $base-menu-background: #304156; |
| | | $base-menu-color: var(--menuColor); |
| | | $base-menu-hover: var(--menuHover); |
| | | $base-menu-color-active: var(--menuActiveText); |
| | | $base-menu-background: var(--menuBg); |
| | | $base-logo-title-color: #ffffff; |
| | | |
| | | $base-menu-light-color: rgba(0, 0, 0, 0.7); |
| | | $base-menu-light-background: #ffffff; |
| | | $base-logo-light-title-color: #001529; |
| | | |
| | | $base-sub-menu-background: #1f2d3d; |
| | | $base-sub-menu-hover: #001528; |
| | | |
| | | // èªå®ä¹æè²èå飿 ¼ |
| | | /** |
| | | $base-menu-color:hsla(0,0%,100%,.65); |
| | | $base-menu-color-active:#fff; |
| | | $base-menu-background:#001529; |
| | | $base-logo-title-color: #ffffff; |
| | | |
| | | $base-menu-light-color:rgba(0,0,0,.70); |
| | | $base-menu-light-background:#ffffff; |
| | | $base-logo-light-title-color: #001529; |
| | | |
| | | $base-sub-menu-background:#000c17; |
| | | $base-sub-menu-hover:#001528; |
| | | */ |
| | | $base-sub-menu-background: var(--subMenuBg); |
| | | $base-sub-menu-hover: var(--subMenuHover); |
| | | $base-sub-menu-title-hover: var(--subMenuTitleHover); |
| | | // 表åå¤´èæ¯è²åæ é¢é¢è² |
| | | $table-header-bg: var(--tableHeaderBg); |
| | | $table-header-text-color: var(--tableHeaderTextColor); |
| | | |
| | | $--color-primary: #409eff; |
| | | $--color-success: #67c23a; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- ä»£ç æå»º --> |
| | | <script setup lang="ts"> |
| | | |
| | | const props = defineProps({ |
| | | showBtn: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | formJson: { |
| | | type: Object, |
| | | default: undefined |
| | | } |
| | | }) |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const buildRef = ref(); |
| | | const emits = defineEmits(['reJson', 'saveDesign']); |
| | | |
| | | |
| | | |
| | | //è·å表åjson |
| | | const getJson = () => { |
| | | const formJson = JSON.stringify(buildRef.value.getFormJson()) |
| | | const fieldJson = JSON.stringify(buildRef.value.getFieldWidgets()) |
| | | let data = { |
| | | formJson, fieldJson |
| | | } |
| | | emits("saveDesign", data) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | if (props.formJson) { |
| | | buildRef.value.setFormJson(props.formJson) |
| | | } |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div> |
| | | <v-form-designer |
| | | class="build" |
| | | ref="buildRef" |
| | | :designer-config="{ importJsonButton: true, exportJsonButton: true, exportCodeButton: true, generateSFCButton: true, formTemplates: true }" |
| | | > |
| | | <template #customToolButtons v-if="showBtn"> |
| | | <el-button link type="primary" icon="Select" @click="getJson">ä¿å</el-button> |
| | | </template> |
| | | </v-form-designer> |
| | | </div> |
| | | </template> |
| | | |
| | | <style lang="scss"> |
| | | .build { |
| | | margin: 0 !important; |
| | | overflow-y: auto !important; |
| | | |
| | | & header.main-header { |
| | | display: none; |
| | | } |
| | | |
| | | & .right-toolbar-con { |
| | | text-align: right !important; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!-- å¨æè¡¨åæ¸²æ --> |
| | | <script setup name="Render"> |
| | | |
| | | const props = defineProps({ |
| | | formJson: { |
| | | type: [String, Object], |
| | | default: {} |
| | | }, |
| | | formData: { |
| | | type: [String, Object], |
| | | default: {} |
| | | }, |
| | | isView: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }) |
| | | |
| | | const vFormRef = ref(null) |
| | | // è·åè¡¨åæ°æ®-弿¥ |
| | | const getFormData = () => { |
| | | return vFormRef.value.getFormData() |
| | | } |
| | | |
| | | /** |
| | | * 设置表åå
容 |
| | | * @param {表åé
ç½®} formConf |
| | | * formConfigï¼{ formTemplateï¼è¡¨å模æ¿ï¼formDataï¼è¡¨åæ°æ®ï¼hiddenFieldï¼éè¦éèçåæ®µå符串éåï¼disabledFieldï¼éè¦ç¦ç¨çèªè¯»å符串éå} |
| | | */ |
| | | const initForm = (formConf) => { |
| | | const { formTemplate, formData, hiddenField, disabledField } = toRaw(formConf) |
| | | if (formTemplate) { |
| | | vFormRef.value.setFormJson(formTemplate) |
| | | if (formData) { |
| | | vFormRef.value.setFormData(formData) |
| | | } |
| | | if (disabledField && disabledField.length > 0) { |
| | | setTimeout(() => { |
| | | vFormRef.value.disableWidgets(disabledField) |
| | | }, 200) |
| | | } |
| | | if (hiddenField && hiddenField.length > 0) { |
| | | setTimeout(() => { |
| | | vFormRef.value.hideWidgets(hiddenField) |
| | | }, 200) |
| | | } |
| | | if (props.isView) { |
| | | console.log(props.isView) |
| | | setTimeout(() => { |
| | | vFormRef.value.disableForm() |
| | | }, 100) |
| | | } |
| | | } |
| | | } |
| | | defineExpose({ getFormData, initForm }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class=""> |
| | | <v-form-render ref="vFormRef" :form-json="formJson" :form-data="formData" /> |
| | | </div> |
| | | </template> |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { PropType } from 'vue'; |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | |
| | | const props = defineProps({ |
| | |
| | | // å½åçå¼ |
| | | value: [Number, String, Array] as PropType<number | string | Array<number | string>>, |
| | | // 彿ªæ¾å°å¹é
çæ°æ®æ¶ï¼æ¾ç¤ºvalue |
| | | showValue: { |
| | | type: Boolean as PropType<boolean>, |
| | | default: true, |
| | | }, |
| | | showValue: propTypes.bool.def(true), |
| | | }); |
| | | |
| | | const values = computed(() => { |
| | |
| | | import { QuillEditor, Quill } from '@vueup/vue-quill'; |
| | | import '@vueup/vue-quill/dist/vue-quill.snow.css'; |
| | | import { getToken } from "@/utils/auth"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | const props = defineProps({ |
| | | /* ç¼è¾å¨çå
容 */ |
| | | modelValue: { |
| | | type: String, |
| | | }, |
| | | modelValue: propTypes.string, |
| | | /* é«åº¦ */ |
| | | height: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | height: propTypes.number.def(400), |
| | | /* æå°é«åº¦ */ |
| | | minHeight: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | minHeight: propTypes.number.def(400), |
| | | /* åªè¯» */ |
| | | readOnly: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | readOnly: propTypes.bool.def(false), |
| | | /* ä¸ä¼ æä»¶å¤§å°éå¶(MB) */ |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | fileSize: propTypes.number.def(5), |
| | | /* ç±»åï¼base64æ ¼å¼ãurlæ ¼å¼ï¼ */ |
| | | type: { |
| | | type: String, |
| | | default: "url", |
| | | } |
| | | type: propTypes.string.def('url') |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | </script> |
| | | |
| | | <style> |
| | | .editor, .ql-toolbar { |
| | | .editor, |
| | | .ql-toolbar { |
| | | white-space: pre-wrap !important; |
| | | line-height: normal !important; |
| | | } |
| | | |
| | | .quill-img { |
| | | display: none; |
| | | } |
| | | |
| | | .ql-snow .ql-tooltip[data-mode="link"]::before { |
| | | content: "请è¾å
¥é¾æ¥å°å:"; |
| | | } |
| | | |
| | | .ql-snow .ql-tooltip.ql-editing a.ql-action::after { |
| | | border-right: 0; |
| | | content: "ä¿å"; |
| | |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item::before { |
| | | content: "14px"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before { |
| | | content: "10px"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before { |
| | | content: "18px"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before { |
| | | content: "32px"; |
| | |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item::before { |
| | | content: "ææ¬"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { |
| | | content: "æ é¢1"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { |
| | | content: "æ é¢2"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { |
| | | content: "æ é¢3"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { |
| | | content: "æ é¢4"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { |
| | | content: "æ é¢5"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { |
| | | content: "æ é¢6"; |
| | |
| | | .ql-snow .ql-picker.ql-font .ql-picker-item::before { |
| | | content: "æ ååä½"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before, |
| | | .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before { |
| | | content: "衬线åä½"; |
| | | } |
| | | |
| | | .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before, |
| | | .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before { |
| | | content: "ç宽åä½"; |
| | |
| | | <script setup lang="ts"> |
| | | import { getToken } from "@/utils/auth"; |
| | | import { listByIds, delOss } from "@/api/system/oss"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { ElUpload, UploadFile } from "element-plus"; |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | const props = defineProps({ |
| | | modelValue: [String, Object, Array], |
| | | // æ°ééå¶ |
| | | limit: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | limit: propTypes.number.def(5), |
| | | // 大å°éå¶(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | fileSize: propTypes.number.def(5), |
| | | // æä»¶ç±»å, ä¾å¦['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array, |
| | | default: () => ["doc", "xls", "ppt", "txt", "pdf"], |
| | | }, |
| | | fileType: propTypes.array.def(["doc", "xls", "ppt", "txt", "pdf"]), |
| | | // æ¯å¦æ¾ç¤ºæç¤º |
| | | isShowTip: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | isShowTip: propTypes.bool.def(true), |
| | | }); |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | () => props.isShowTip && (props.fileType || props.fileSize) |
| | | ); |
| | | |
| | | const fileUploadRef = ref(ElUpload); |
| | | const fileUploadRef = ref<ElUploadInstance>(); |
| | | |
| | | watch(() => props.modelValue, async val => { |
| | | if (val) { |
| | |
| | | number.value--; |
| | | proxy?.$modal.closeLoading(); |
| | | proxy?.$modal.msgError(res.msg); |
| | | fileUploadRef.value.handleRemove(file); |
| | | fileUploadRef.value?.handleRemove(file); |
| | | uploadedSuccessfully(); |
| | | } |
| | | } |
| | |
| | | .upload-file-uploader { |
| | | margin-bottom: 5px; |
| | | } |
| | | |
| | | .upload-file-list .el-upload-list__item { |
| | | border: 1px solid #e4e7ed; |
| | | line-height: 2; |
| | | margin-bottom: 10px; |
| | | position: relative; |
| | | } |
| | | |
| | | .upload-file-list .ele-upload-list__item-content { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | color: inherit; |
| | | } |
| | | |
| | | .ele-upload-list__item-content-action .el-link { |
| | | margin-right: 10px; |
| | | } |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | defineProps({ |
| | | isActive: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | isActive: propTypes.bool.def(false) |
| | | }) |
| | | |
| | | const emit = defineEmits(['toggleClick']) |
| | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import Fuse from 'fuse.js' |
| | | import { getNormalPath } from '@/utils/ruoyi' |
| | | import { isHttp } from '@/utils/validate' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | import { RouteOption } from 'vue-router' |
| | | <script setup lang="ts" name="HeaderSearch"> |
| | | import Fuse from 'fuse.js'; |
| | | import { getNormalPath } from '@/utils/ruoyi'; |
| | | import { isHttp } from '@/utils/validate'; |
| | | import usePermissionStore from '@/store/modules/permission'; |
| | | import { RouteOption } from 'vue-router'; |
| | | |
| | | type Router = Array<{ |
| | | path: string; |
| | |
| | | const searchPool = ref<Router>([]); |
| | | const show = ref(false); |
| | | const fuse = ref(); |
| | | const headerSearchSelectRef = ref(ElSelect); |
| | | const headerSearchSelectRef = ref<ElSelectInstance>(); |
| | | const router = useRouter(); |
| | | const routes = computed(() => usePermissionStore().routes); |
| | | |
| | |
| | | searchPool.value = generateRoutes(routes.value); |
| | | }) |
| | | |
| | | watchEffect(() => { |
| | | searchPool.value = generateRoutes(routes.value) |
| | | }) |
| | | // watchEffect(() => { |
| | | // searchPool.value = generateRoutes(routes.value) |
| | | // }) |
| | | |
| | | watch(show, (value) => { |
| | | if (value) { |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import icons from '@/components/IconSelect/requireIcons'; |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | const props = defineProps({ |
| | | modelValue: { |
| | | type: String, |
| | | require: true |
| | | }, |
| | | width: { |
| | | type: String, |
| | | require: false, |
| | | default: '400px' |
| | | } |
| | | modelValue: propTypes.string.isRequired, |
| | | width: propTypes.string.def('400px') |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:modelValue']); |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | const props = defineProps({ |
| | | src: { |
| | | type: String, |
| | | default: "" |
| | | }, |
| | | src: propTypes.string.def(''), |
| | | width: { |
| | | type: [Number, String], |
| | | default: "" |
| | |
| | | border-radius: 5px; |
| | | background-color: #ebeef5; |
| | | box-shadow: 0 0 5px 1px #ccc; |
| | | |
| | | :deep(.el-image__inner) { |
| | | transition: all 0.3s; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | transform: scale(1.2); |
| | | } |
| | | } |
| | | |
| | | :deep(.image-slot) { |
| | | display: flex; |
| | | justify-content: center; |
| | |
| | | :on-preview="handlePictureCardPreview" |
| | | :class="{ hide: fileList.length >= limit }" |
| | | > |
| | | <el-icon class="avatar-uploader-icon"><plus /></el-icon> |
| | | <el-icon class="avatar-uploader-icon"> |
| | | <plus /> |
| | | </el-icon> |
| | | </el-upload> |
| | | <!-- ä¸ä¼ æç¤º --> |
| | | <div class="el-upload__tip" v-if="showTip"> |
| | |
| | | import { listByIds, delOss } from "@/api/system/oss"; |
| | | import { ComponentInternalInstance, PropType } from "vue"; |
| | | import { OssVO } from "@/api/system/oss/types"; |
| | | import { ElUpload, UploadFile } from "element-plus"; |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | const props = defineProps({ |
| | | modelValue: [String, Object, Array], |
| | | // å¾çæ°ééå¶ |
| | | limit: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | limit: propTypes.number.def(5), |
| | | // 大å°éå¶(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | fileSize: propTypes.number.def(5), |
| | | // æä»¶ç±»å, ä¾å¦['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array as PropType<string[]>, |
| | | default: () => ["png", "jpg", "jpeg"], |
| | | }, |
| | | fileType: propTypes.array.def(["png", "jpg", "jpeg"]), |
| | | // æ¯å¦æ¾ç¤ºæç¤º |
| | | isShowTip: { |
| | | type: Boolean, |
| | |
| | | () => props.isShowTip && (props.fileType || props.fileSize) |
| | | ); |
| | | |
| | | const imageUploadRef = ref(ElUpload); |
| | | const imageUploadRef = ref<ElUploadInstance>(); |
| | | |
| | | watch(() => props.modelValue, async val => { |
| | | if (val) { |
| | |
| | | if (file.name.lastIndexOf(".") > -1) { |
| | | fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1); |
| | | } |
| | | isImg = props.fileType.some((type) => { |
| | | isImg = props.fileType.some((type: any) => { |
| | | if (file.type.indexOf(type) > -1) return true; |
| | | if (fileExtension && fileExtension.indexOf(type) > -1) return true; |
| | | return false; |
| | |
| | | number.value--; |
| | | proxy?.$modal.closeLoading(); |
| | | proxy?.$modal.msgError(res.msg); |
| | | imageUploadRef.value.handleRemove(file); |
| | | imageUploadRef.value?.handleRemove(file); |
| | | uploadedSuccessfully(); |
| | | } |
| | | } |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import { scrollTo } from '@/utils/scroll-to' |
| | | import { PropType } from "vue"; |
| | | import { propTypes } from "@/utils/propTypes"; |
| | | |
| | | const props = defineProps({ |
| | | total: { |
| | | required: true, |
| | | type: Number |
| | | }, |
| | | page: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | limit: { |
| | | type: Number, |
| | | default: 20 |
| | | }, |
| | | total: propTypes.number, |
| | | page: propTypes.number.def(1), |
| | | limit: propTypes.number.def(20), |
| | | pageSizes: { |
| | | type: Array as PropType<number[]>, |
| | | default() { |
| | | return [10, 20, 30, 50] |
| | | } |
| | | default: () => [10, 20, 30, 50] |
| | | }, |
| | | // ç§»å¨ç«¯é¡µç æé®çæ°é端é»è®¤å¼5 |
| | | pagerCount: { |
| | | type: Number, |
| | | default: document.body.clientWidth < 992 ? 5 : 7 |
| | | }, |
| | | layout: { |
| | | type: String, |
| | | default: 'total, sizes, prev, pager, next, jumper' |
| | | }, |
| | | background: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | autoScroll: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | hidden: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | float: { |
| | | type: String, |
| | | default: 'right' |
| | | } |
| | | pagerCount: propTypes.number.def(document.body.clientWidth < 992 ? 5 : 7), |
| | | layout: propTypes.string.def('total, sizes, prev, pager, next, jumper'), |
| | | background: propTypes.bool.def(true), |
| | | autoScroll: propTypes.bool.def(true), |
| | | hidden: propTypes.bool.def(false), |
| | | float: propTypes.string.def('right') |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:page', 'update:limit', 'pagination']); |
| | |
| | | |
| | | <style lang="scss" scoped> |
| | | .pagination-container { |
| | | background: #fff; |
| | | padding: 32px 16px; |
| | | .el-pagination{ |
| | | float: v-bind(float); |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { TransferKey } from "element-plus"; |
| | | import { PropType } from "vue"; |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | const props = defineProps({ |
| | | showSearch: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | showSearch: propTypes.bool.def(true), |
| | | columns: { |
| | | type: Array as PropType<FieldOption[]>, |
| | | }, |
| | | search: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | gutter: { |
| | | type: Number, |
| | | default: 10, |
| | | }, |
| | | search: propTypes.bool.def(true), |
| | | gutter: propTypes.number.def(10), |
| | | }) |
| | | |
| | | const emits = defineEmits(['update:showSearch', 'queryTable']); |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | const props = defineProps({ |
| | | iconClass: { |
| | | type: String, |
| | | required: true |
| | | }, |
| | | className: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | color: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | iconClass: propTypes.string.isRequired, |
| | | className: propTypes.string.def(''), |
| | | color: propTypes.string.def(''), |
| | | }) |
| | | const iconName = computed(() => `#icon-${props.iconClass}`); |
| | | const svgClass = computed(() => { |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ElTreeSelect } from 'element-plus' |
| | | |
| | | const props = defineProps({ |
| | | /* é
置项 */ |
| | |
| | | }) |
| | | |
| | | |
| | | const selectTree = ref(ElTreeSelect); |
| | | const selectTree = ref<ElTreeSelectInstance>(); |
| | | |
| | | const emit = defineEmits(['update:value']); |
| | | |
| | |
| | | const valueTitle = ref(''); |
| | | const defaultExpandedKey = ref<any[]>([]); |
| | | |
| | | function initHandle() { |
| | | const initHandle = () => { |
| | | nextTick(() => { |
| | | const selectedValue = valueId.value; |
| | | if(selectedValue !== null && typeof (selectedValue) !== 'undefined') { |
| | | const node = selectTree.value.getNode(selectedValue) |
| | | const node = selectTree.value?.getNode(selectedValue) |
| | | if (node) { |
| | | valueTitle.value = node.data[props.objMap.label] |
| | | selectTree.value.setCurrentKey(selectedValue) // 设置é»è®¤éä¸ |
| | | selectTree.value?.setCurrentKey(selectedValue) // 设置é»è®¤éä¸ |
| | | defaultExpandedKey.value = [selectedValue] // 设置é»è®¤å±å¼ |
| | | } |
| | | } else { |
| | |
| | | } |
| | | }) |
| | | } |
| | | function handleNodeClick(node: any) { |
| | | const handleNodeClick = (node: any) => { |
| | | valueTitle.value = node[props.objMap.label] |
| | | valueId.value = node[props.objMap.value]; |
| | | defaultExpandedKey.value = []; |
| | | selectTree.value.blur() |
| | | selectTree.value?.blur() |
| | | selectFilterData('') |
| | | } |
| | | function selectFilterData(val: any) { |
| | | selectTree.value.filter(val) |
| | | const selectFilterData = (val: any) => { |
| | | selectTree.value?.filter(val) |
| | | } |
| | | function filterNode(value: any, data: any) { |
| | | const filterNode = (value: any, data: any) => { |
| | | if (!value) return true |
| | | return data[props.objMap['label']].indexOf(value) !== -1 |
| | | } |
| | | function clearHandle() { |
| | | const clearHandle = () => { |
| | | valueTitle.value = '' |
| | | valueId.value = '' |
| | | defaultExpandedKey.value = []; |
| | | clearSelected() |
| | | } |
| | | function clearSelected() { |
| | | const clearSelected = () => { |
| | | const allNode = document.querySelectorAll('#tree-option .el-tree-node') |
| | | allNode.forEach((element) => element.classList.remove('is-current')) |
| | | } |
| | |
| | | |
| | | <style lang="scss" scoped> |
| | | @import "@/assets/styles/variables.module.scss"; |
| | | |
| | | .el-scrollbar .el-scrollbar__view .el-select-dropdown__item { |
| | | padding: 0; |
| | | background-color: #fff; |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | |
| | | const props = defineProps({ |
| | | src: { |
| | | type: String, |
| | | required: true |
| | | } |
| | | src: propTypes.string.isRequired |
| | | }) |
| | | |
| | | const height = ref(document.documentElement.clientHeight - 94.5 + "px;") |
| | |
| | | <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template> |
| | | </el-select> |
| | | |
| | | <header-search id="header-search" class="right-menu-item" /> |
| | | |
| | | <!-- <header-search id="header-search" class="right-menu-item" /> --> |
| | | <search-menu ref="searchMenuRef" /> |
| | | <el-tooltip content="æç´¢" effect="dark" placement="bottom"> |
| | | <div class="right-menu-item hover-effect" @click="openSearchMenu"> |
| | | <svg-icon class-name="search-icon" icon-class="search" /> |
| | | </div> |
| | | </el-tooltip> |
| | | <el-tooltip content="Github" effect="dark" placement="bottom"> |
| | | <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import useAppStore from '@/store/modules/app' |
| | | import useUserStore from '@/store/modules/user' |
| | | import useSettingsStore from '@/store/modules/settings' |
| | | import SearchMenu from './topBar/search.vue'; |
| | | import useAppStore from '@/store/modules/app'; |
| | | import useUserStore from '@/store/modules/user'; |
| | | import useSettingsStore from '@/store/modules/settings'; |
| | | import { getTenantList } from "@/api/login"; |
| | | import { dynamicClear, dynamicTenant } from "@/api/system/tenant"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { TenantVO } from "@/api/types"; |
| | | |
| | | const appStore = useAppStore() |
| | | const userStore = useUserStore() |
| | | const settingsStore = useSettingsStore() |
| | | const appStore = useAppStore(); |
| | | const userStore = useUserStore(); |
| | | const settingsStore = useSettingsStore(); |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | |
| | | const dynamic = ref(false); |
| | | // ç§æ·å¼å
³ |
| | | const tenantEnabled = ref(true); |
| | | // æç´¢èå |
| | | const searchMenuRef = ref<InstanceType<typeof SearchMenu>>(); |
| | | |
| | | const openSearchMenu = () => { |
| | | searchMenuRef.value?.openSearch(); |
| | | } |
| | | |
| | | // 卿忢 |
| | | const dynamicTenantEvent = async (tenantId: string) => { |
| | |
| | | await dynamicClear(); |
| | | dynamic.value = false; |
| | | proxy?.$tab.closeAllPage(); |
| | | proxy?.$router.push('/') |
| | | proxy?.$router.push('/'); |
| | | } |
| | | |
| | | /** ç§æ·å表 */ |
| | |
| | | }) |
| | | |
| | | const toggleSideBar = () => { |
| | | appStore.toggleSideBar(false) |
| | | appStore.toggleSideBar(false); |
| | | } |
| | | |
| | | const logout = async () => { |
| | |
| | | height: 50px; |
| | | overflow: hidden; |
| | | position: relative; |
| | | background: #fff; |
| | | //background: #fff; |
| | | box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); |
| | | |
| | | .hamburger-container { |
| | |
| | | <template> |
| | | <el-drawer v-model="showSettings" :withHeader="false" direction="rtl" size="300px" close-on-click-modal> |
| | | <div class="setting-drawer-title"> |
| | | <h3 class="drawer-title">主é¢é£æ ¼è®¾ç½®</h3> |
| | | </div> |
| | | |
| | | <div class="setting-drawer-block-checbox"> |
| | | <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')"> |
| | | <img src="@/assets/images/dark.svg" alt="dark" /> |
| | |
| | | <el-color-picker v-model="theme" :predefine="predefineColors" @change="themeChange" /> |
| | | </span> |
| | | </div> |
| | | <div class="drawer-item"> |
| | | <span>æ·±è²æ¨¡å¼</span> |
| | | <span class="comp-style"> |
| | | <el-switch v-model="isDark" @change="toggleDark" class="drawer-switch" /> |
| | | </span> |
| | | </div> |
| | | |
| | | <el-divider /> |
| | | |
| | | <h3 class="drawer-title">ç³»ç»å¸å±é
ç½®</h3> |
| | |
| | | const storeSettings = computed(() => settingsStore); |
| | | const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"]); |
| | | |
| | | /** æ¯å¦éè¦topnav */ |
| | | // æ¯å¦æé»æ¨¡å¼ |
| | | const isDark = useDark({ |
| | | storageKey: 'useDarkKey', |
| | | valueDark: 'dark', |
| | | valueLight: 'light', |
| | | }); |
| | | const toggleDark = () => useToggle(isDark); |
| | | |
| | | /** æ¯å¦éè¦topNav */ |
| | | const topNav = computed({ |
| | | get: () => storeSettings.value.topNav, |
| | | set: (val) => { |
| | |
| | | } |
| | | |
| | | .drawer-item { |
| | | color: rgba(0, 0, 0, 0.65); |
| | | padding: 12px 0; |
| | | font-size: 14px; |
| | | |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import useTagsViewStore from '@/store/modules/tagsView' |
| | | import { ElScrollbar } from 'element-plus'; |
| | | import { TagView } from 'vue-router' |
| | | const tagAndTagSpacing = ref(4); |
| | | |
| | | const scrollContainerRef = ref(ElScrollbar) |
| | | const scrollWrapper = computed(() => scrollContainerRef.value.$refs.wrapRef); |
| | | const scrollContainerRef = ref<ElScrollbarInstance>() |
| | | const scrollWrapper = computed(() => scrollContainerRef.value?.$refs.wrapRef as any); |
| | | |
| | | onMounted(() => { |
| | | scrollWrapper.value.addEventListener('scroll', emitScroll, true) |
| | | scrollWrapper.value?.addEventListener('scroll', emitScroll, true) |
| | | }) |
| | | onBeforeUnmount(() => { |
| | | scrollWrapper.value.removeEventListener('scroll', emitScroll) |
| | | scrollWrapper.value?.removeEventListener('scroll', emitScroll) |
| | | }) |
| | | |
| | | const handleScroll = (e: WheelEvent) => { |
| | |
| | | const visitedViews = computed(() => tagsViewStore.visitedViews); |
| | | |
| | | const moveToTarget = (currentTag: TagView) => { |
| | | const $container = scrollContainerRef.value.$el |
| | | const $container = scrollContainerRef.value?.$el |
| | | const $containerWidth = $container.offsetWidth |
| | | const $scrollWrapper = scrollWrapper.value; |
| | | |
| | |
| | | } |
| | | const addTags = () => { |
| | | const { name } = route; |
| | | if(route.query.title) { |
| | | route.meta.title = route.query.title; |
| | | } |
| | | if (name) { |
| | | useTagsViewStore().addView(route); |
| | | if (route.meta.link) { |
| | |
| | | .tags-view-container { |
| | | height: 34px; |
| | | width: 100%; |
| | | background: #fff; |
| | | border-bottom: 1px solid #d8dce5; |
| | | background-color: var(--el-bg-color); |
| | | border: 1px solid var(--el-border-color-light); |
| | | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04); |
| | | .tags-view-wrapper { |
| | | .tags-view-item { |
| | |
| | | cursor: pointer; |
| | | height: 26px; |
| | | line-height: 23px; |
| | | border: 1px solid #d8dce5; |
| | | background-color: var(--el-bg-color); |
| | | border: 1px solid var(--el-border-color-light); |
| | | color: #495060; |
| | | background: #fff; |
| | | padding: 0 8px; |
| | | font-size: 12px; |
| | | margin-left: 5px; |
| | | margin-top: 4px; |
| | | &:hover { |
| | | color: var(--el-color-primary); |
| | | } |
| | | &:first-of-type { |
| | | margin-left: 15px; |
| | | } |
| | |
| | | } |
| | | .contextmenu { |
| | | margin: 0; |
| | | background: #fff; |
| | | background: var(--el-bg-color); |
| | | z-index: 3000; |
| | | position: absolute; |
| | | list-style-type: none; |
| | |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | font-weight: 400; |
| | | color: #333; |
| | | box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3); |
| | | li { |
| | | margin: 0; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="layout-search-dialog"> |
| | | <el-dialog v-model="state.isShowSearch" destroy-on-close :show-close="false"> |
| | | <template #footer> |
| | | <el-autocomplete |
| | | v-model="state.menuQuery" |
| | | :fetch-suggestions="menuSearch" |
| | | placeholder="æç´¢" |
| | | ref="layoutMenuAutocompleteRef" |
| | | @select="onHandleSelect" |
| | | :fit-input-width="true" |
| | | > |
| | | <template #prefix> |
| | | <svg-icon class-name="search-icon" icon-class="search" /> |
| | | </template> |
| | | <template #default="{ item }"> |
| | | <div> |
| | | <svg-icon :icon-class="item.icon" class="mr5" /> |
| | | {{ item.title }} |
| | | </div> |
| | | </template> |
| | | </el-autocomplete> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts" name="layoutBreadcrumbSearch"> |
| | | import { getNormalPath } from '@/utils/ruoyi'; |
| | | import { isHttp } from '@/utils/validate'; |
| | | import usePermissionStore from '@/store/modules/permission'; |
| | | import { RouteOption } from 'vue-router'; |
| | | type Router = Array<{ |
| | | path: string; |
| | | icon: string; |
| | | title: string[]; |
| | | }> |
| | | type SearchState<T = any> = { |
| | | isShowSearch: boolean; |
| | | menuQuery: string; |
| | | menuList: T[]; |
| | | }; |
| | | // å®ä¹åéå
容 |
| | | const layoutMenuAutocompleteRef = ref(); |
| | | const router = useRouter(); |
| | | const routes = computed(() => usePermissionStore().routes); |
| | | const state = reactive<SearchState>({ |
| | | isShowSearch: false, |
| | | menuQuery: '', |
| | | menuList: [], |
| | | }); |
| | | |
| | | // æç´¢å¼¹çªæå¼ |
| | | const openSearch = () => { |
| | | state.menuQuery = ''; |
| | | state.isShowSearch = true; |
| | | state.menuList = generateRoutes(routes.value); |
| | | nextTick(() => { |
| | | setTimeout(() => { |
| | | layoutMenuAutocompleteRef.value.focus(); |
| | | }); |
| | | }); |
| | | }; |
| | | // æç´¢å¼¹çªå
³é |
| | | const closeSearch = () => { |
| | | state.isShowSearch = false; |
| | | }; |
| | | // èåæç´¢æ°æ®è¿æ»¤ |
| | | const menuSearch = (queryString: string, cb: Function) => { |
| | | let options = state.menuList.filter((item) => { |
| | | return item.title.indexOf(queryString) > -1; |
| | | }); |
| | | cb(options); |
| | | }; |
| | | |
| | | // Filter out the routes that can be displayed in the sidebar |
| | | // And generate the internationalized title |
| | | const generateRoutes = (routes: RouteOption[], basePath = '', prefixTitle: string[] = []) => { |
| | | let res: Router = [] |
| | | routes.forEach(r => { |
| | | // skip hidden router |
| | | if (!r.hidden) { |
| | | const p = r.path.length > 0 && r.path[0] === '/' ? r.path : '/' + r.path; |
| | | const data: any = { |
| | | path: !isHttp(r.path) ? getNormalPath(basePath + p) : r.path, |
| | | icon: r.meta?.icon, |
| | | title: [...prefixTitle] |
| | | } |
| | | if (r.meta && r.meta.title) { |
| | | data.title = [...data.title, r.meta.title]; |
| | | if (r.redirect !== 'noRedirect') { |
| | | // only push the routes with title |
| | | // special case: need to exclude parent router without redirect |
| | | res.push(data); |
| | | } |
| | | } |
| | | // recursive child routes |
| | | if (r.children) { |
| | | const tempRoutes = generateRoutes(r.children, data.path, data.title); |
| | | if (tempRoutes.length >= 1) { |
| | | res = [...res, ...tempRoutes]; |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | res.forEach((item: any) => { |
| | | if (item.title instanceof Array) { |
| | | item.title = item.title.join('/'); |
| | | } |
| | | }); |
| | | return res; |
| | | } |
| | | // å½åèåé䏿¶ |
| | | const onHandleSelect = (val: any) => { |
| | | const paths = val.path; |
| | | if (isHttp(paths)) { |
| | | // http(s):// è·¯å¾æ°çªå£æå¼ |
| | | const pindex = paths.indexOf("http"); |
| | | window.open(paths.substring(pindex, paths.length), "_blank"); |
| | | } else { |
| | | router.push(paths); |
| | | } |
| | | state.menuQuery = '' |
| | | closeSearch(); |
| | | |
| | | }; |
| | | |
| | | // æ´é²åé |
| | | defineExpose({ |
| | | openSearch |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .layout-search-dialog { |
| | | position: relative; |
| | | :deep(.el-dialog) { |
| | | .el-dialog__header, |
| | | .el-dialog__body { |
| | | display: none; |
| | | } |
| | | .el-dialog__footer { |
| | | width: 100%; |
| | | position: absolute; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | top: -53vh; |
| | | } |
| | | } |
| | | :deep(.el-autocomplete) { |
| | | width: 560px; |
| | | position: absolute; |
| | | top: 150px; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | } |
| | | } |
| | | </style> |
| | |
| | | import { ElMessage, ElMessageBox, ElNotification, ElLoading, MessageBoxData } from 'element-plus'; |
| | | import { MessageBoxData } from 'element-plus'; |
| | | import { LoadingInstance } from 'element-plus/es/components/loading/src/loading'; |
| | | let loadingInstance: LoadingInstance; |
| | | export default { |
| | | // æ¶æ¯æç¤º |
| | | msg(content: string) { |
| | | msg(content: any) { |
| | | ElMessage.info(content); |
| | | }, |
| | | // éè¯¯æ¶æ¯ |
| | | msgError(content: string) { |
| | | msgError(content: any) { |
| | | ElMessage.error(content); |
| | | }, |
| | | // æåæ¶æ¯ |
| | | msgSuccess(content: string) { |
| | | msgSuccess(content: any) { |
| | | ElMessage.success(content); |
| | | }, |
| | | // è¦åæ¶æ¯ |
| | | msgWarning(content: string) { |
| | | msgWarning(content: any) { |
| | | ElMessage.warning(content); |
| | | }, |
| | | // å¼¹åºæç¤º |
| | | alert(content: string) { |
| | | alert(content: any) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º'); |
| | | }, |
| | | // é误æç¤º |
| | | alertError(content: string) { |
| | | alertError(content: any) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º', { type: 'error' }); |
| | | }, |
| | | // æåæç¤º |
| | | alertSuccess(content: string, s: string, p: { dangerouslyUseHTMLString: boolean }) { |
| | | alertSuccess(content: any) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º', { type: 'success' }); |
| | | }, |
| | | // è¦åæç¤º |
| | | alertWarning(content: string) { |
| | | alertWarning(content: any) { |
| | | ElMessageBox.alert(content, 'ç³»ç»æç¤º', { type: 'warning' }); |
| | | }, |
| | | // éç¥æç¤º |
| | | notify(content: string) { |
| | | notify(content: any) { |
| | | ElNotification.info(content); |
| | | }, |
| | | // é误éç¥ |
| | | notifyError(content: string) { |
| | | notifyError(content: any) { |
| | | ElNotification.error(content); |
| | | }, |
| | | // æåéç¥ |
| | | notifySuccess(content: string) { |
| | | notifySuccess(content: any) { |
| | | ElNotification.success(content); |
| | | }, |
| | | // è¦åéç¥ |
| | | notifyWarning(content: string) { |
| | | notifyWarning(content: any) { |
| | | ElNotification.warning(content); |
| | | }, |
| | | // 确认çªä½ |
| | | confirm(content: string): Promise<MessageBoxData> { |
| | | confirm(content: any): Promise<MessageBoxData> { |
| | | return ElMessageBox.confirm(content, 'ç³»ç»æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | |
| | | }); |
| | | }, |
| | | // æäº¤å
容 |
| | | prompt(content: string) { |
| | | prompt(content: any) { |
| | | return ElMessageBox.prompt(content, 'ç³»ç»æç¤º', { |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | |
| | | import { TagView, RouteLocationRaw } from 'vue-router'; |
| | | |
| | | export default { |
| | | // å·æ°å½åtabé¡µç¾ |
| | | async refreshPage(obj: TagView): Promise<void> { |
| | | /** |
| | | * å·æ°å½åtabé¡µç¾ |
| | | * @param obj æ ç¾å¯¹è±¡ |
| | | */ |
| | | async refreshPage(obj?: TagView): Promise<void> { |
| | | const { path, query, matched } = router.currentRoute.value; |
| | | if (obj === undefined) { |
| | | matched.forEach((m) => { |
| | |
| | | } |
| | | }); |
| | | } |
| | | // prettier-ignore |
| | | await useTagsViewStore().delCachedView(obj) |
| | | router.replace({ |
| | | path: '/redirect' + obj.path, |
| | | query: obj.query |
| | | let query1: undefined | {} = {}; |
| | | let path1: undefined | string = ''; |
| | | if (obj) { |
| | | query1 = obj.query; |
| | | path1 = obj.path; |
| | | } |
| | | await useTagsViewStore().delCachedView(obj); |
| | | await router.replace({ |
| | | path: '/redirect' + path1, |
| | | query: query1 |
| | | }); |
| | | }, |
| | | // å
³éå½åtab页ç¾ï¼æå¼æ°é¡µç¾ |
| | |
| | | if (obj === undefined) { |
| | | // prettier-ignore |
| | | const { visitedViews } = await useTagsViewStore().delView(router.currentRoute.value) as any |
| | | const latestView = visitedViews.slice(-1)[0] |
| | | const latestView = visitedViews.slice(-1)[0]; |
| | | if (latestView) { |
| | | return router.push(latestView.fullPath) |
| | | return router.push(latestView.fullPath); |
| | | } |
| | | return router.push('/'); |
| | | } |
| | |
| | | return useTagsViewStore().delAllViews(); |
| | | }, |
| | | // å
³é左侧tabé¡µç¾ |
| | | closeLeftPage(obj: TagView) { |
| | | closeLeftPage(obj?: TagView) { |
| | | return useTagsViewStore().delLeftTags(obj || router.currentRoute.value); |
| | | }, |
| | | // å
³éå³ä¾§tabé¡µç¾ |
| | | closeRightPage(obj: TagView) { |
| | | closeRightPage(obj?: TagView) { |
| | | return useTagsViewStore().delRightTags(obj || router.currentRoute.value); |
| | | }, |
| | | // å
³éå
¶ä»tabé¡µç¾ |
| | | closeOtherPage(obj: TagView) { |
| | | closeOtherPage(obj?: TagView) { |
| | | return useTagsViewStore().delOthersViews(obj || router.currentRoute.value); |
| | | }, |
| | | // æå¼tabé¡µç¾ |
| | | openPage(url: RouteLocationRaw) { |
| | | return router.push(url); |
| | | /** |
| | | * æå¼tabé¡µç¾ |
| | | * @param url è·¯ç±å°å |
| | | * @param title æ é¢ |
| | | * @param query åæ° |
| | | */ |
| | | openPage(url: string, title?: string, query?: any) { |
| | | const obj = { path: url, query: { ...query, title } }; |
| | | return router.push(obj); |
| | | }, |
| | | // ä¿®æ¹tabé¡µç¾ |
| | | /** |
| | | * ä¿®æ¹tabé¡µç¾ |
| | | * @param obj æ ç¾å¯¹è±¡ |
| | | */ |
| | | updatePage(obj: TagView) { |
| | | return useTagsViewStore().updateVisitedView(obj); |
| | | } |
| | |
| | | resolve([...visitedViews.value]); |
| | | }); |
| | | }; |
| | | const delCachedView = (view: TagView): Promise<string[]> => { |
| | | const viewName = view.name as string; |
| | | const delCachedView = (view?: TagView): Promise<string[]> => { |
| | | let viewName = ''; |
| | | if (view) { |
| | | viewName = view.name as string; |
| | | } |
| | | return new Promise((resolve) => { |
| | | const index = cachedViews.value.indexOf(viewName); |
| | | index > -1 && cachedViews.value.splice(index, 1); |
| | |
| | | |
| | | const addCachedView = (view: TagView): void => { |
| | | const viewName = view.name as string; |
| | | if (!viewName) return; |
| | | if (cachedViews.value.includes(viewName)) return; |
| | | if (!view.meta?.noCache) { |
| | | cachedViews.value.push(viewName); |
| | |
| | | import type * as ep from 'element-plus'; |
| | | declare global { |
| | | declare type ElTagType = '' | 'success' | 'warning' | 'info' | 'danger' | 'default' | 'primary'; |
| | | declare type ElFormInstance = InstanceType<typeof ep.ElForm>; |
| | | declare type ElTableInstance = InstanceType<typeof ep.ElTable>; |
| | | declare type ElTreeInstance = InstanceType<typeof ep.ElTree>; |
| | | declare type ElTreeSelectInstance = InstanceType<typeof ep.ElTreeSelect>; |
| | | declare type ElSelectInstance = InstanceType<typeof ep.ElSelect>; |
| | | declare type ElUploadInstance = InstanceType<typeof ep.ElUpload>; |
| | | declare type ElCardInstance = InstanceType<typeof ep.ElCard>; |
| | | declare type ElDialogInstance = InstanceType<typeof ep.ElDialog>; |
| | | declare type ElInputInstance = InstanceType<typeof ep.ElInput>; |
| | | declare type ElInputNumberInstance = InstanceType<typeof ep.ElInputNumber>; |
| | | declare type ElRadioInstance = InstanceType<typeof ep.ElRadio>; |
| | | declare type ElRadioGroupInstance = InstanceType<typeof ep.ElRadioGroup>; |
| | | declare type ElRadioButtonInstance = InstanceType<typeof ep.ElRadioButton>; |
| | | declare type ElCheckboxInstance = InstanceType<typeof ep.ElCheckbox>; |
| | | declare type ElCheckboxGroupInstance = InstanceType<typeof ep.ElCheckboxGroup>; |
| | | declare type ElSwitchInstance = InstanceType<typeof ep.ElSwitch>; |
| | | declare type ElDatePickerInstance = InstanceType<typeof ep.ElDatePicker>; |
| | | declare type ElTimePickerInstance = InstanceType<typeof ep.ElTimePicker>; |
| | | declare type ElTimeSelectInstance = InstanceType<typeof ep.ElTimeSelect>; |
| | | declare type ElCascaderInstance = InstanceType<typeof ep.ElCascader>; |
| | | declare type ElColorPickerInstance = InstanceType<typeof ep.ElColorPicker>; |
| | | declare type ElRateInstance = InstanceType<typeof ep.ElRate>; |
| | | declare type ElSliderInstance = InstanceType<typeof ep.ElSlider>; |
| | | declare type ElUploadInstance = InstanceType<typeof ep.ElUpload>; |
| | | declare type ElScrollbarInstance = InstanceType<typeof ep.ElScrollbar>; |
| | | |
| | | declare type TransferKey = ep.TransferKey; |
| | | declare type CheckboxValueType = ep.CheckboxValueType; |
| | | declare type ElFormRules = ep.FormRules; |
| | | declare type DateModelType = ep.DateModelType; |
| | | declare type UploadFile = typeof ep.UploadFile; |
| | | } |
| | |
| | | import { FormRules } from 'element-plus'; |
| | | import type { ComponentInternalInstance as ComponentInstance, PropType as VuePropType } from 'vue'; |
| | | |
| | | declare global { |
| | | /** vue Instance */ |
| | | declare type ComponentInternalInstance = ComponentInstance; |
| | | /**vue */ |
| | | declare type PropType<T> = VuePropType<T>; |
| | | |
| | | /** |
| | | * çé¢å段éè屿§ |
| | | */ |
| | | interface FieldOption { |
| | | declare interface FieldOption { |
| | | key: number; |
| | | label: string; |
| | | visible: boolean; |
| | |
| | | /** |
| | | * å¼¹çªå±æ§ |
| | | */ |
| | | interface DialogOption { |
| | | declare interface DialogOption { |
| | | /** |
| | | * å¼¹çªæ é¢ |
| | | */ |
| | |
| | | visible: boolean; |
| | | } |
| | | |
| | | interface UploadOption { |
| | | declare interface UploadOption { |
| | | /** 设置ä¸ä¼ ç请æ±å¤´é¨ */ |
| | | headers: { [key: string]: any }; |
| | | |
| | |
| | | /** |
| | | * 导å
¥å±æ§ |
| | | */ |
| | | interface ImportOption extends UploadOption { |
| | | declare interface ImportOption extends UploadOption { |
| | | /** æ¯å¦æ¾ç¤ºå¼¹åºå± */ |
| | | open: boolean; |
| | | /** å¼¹åºå±æ é¢ */ |
| | |
| | | /** |
| | | * åå
¸æ°æ® æ°æ®é
ç½® |
| | | */ |
| | | interface DictDataOption { |
| | | declare interface DictDataOption { |
| | | label: string; |
| | | value: string; |
| | | elTagType?: ElTagType; |
| | | elTagClass?: string; |
| | | } |
| | | |
| | | interface BaseEntity { |
| | | declare interface BaseEntity { |
| | | createBy?: any; |
| | | createDept?: any; |
| | | createTime?: string; |
| | |
| | | * T : è¡¨åæ°æ® |
| | | * D : æ¥è¯¢åæ° |
| | | */ |
| | | interface PageData<T, D> { |
| | | declare interface PageData<T, D> { |
| | | form: T; |
| | | queryParams: D; |
| | | rules: FormRules; |
| | | rules: ElFormRules; |
| | | } |
| | | /** |
| | | * å页æ¥è¯¢åæ° |
| | | */ |
| | | interface PageQuery { |
| | | declare interface PageQuery { |
| | | pageNum: number; |
| | | pageSize: number; |
| | | } |
| | |
| | | import modal from '@/plugins/modal'; |
| | | import tab from '@/plugins/tab'; |
| | | import { useDict } from '@/utils/dict'; |
| | | import { addDateRange, handleTree, selectDictLabel, selectDictLabels, parseTime } from '@/utils/ruoyi'; |
| | | import { getConfigKey, updateConfigByKey } from '@/api/system/config'; |
| | | import { download as download1 } from '@/utils/request'; |
| | | import download from '@/plugins/download'; |
| | | import animate from '@/animate'; |
| | | import type modal from '@/plugins/modal'; |
| | | import type tab from '@/plugins/tab'; |
| | | import type download from '@/plugins/download'; |
| | | import type auth from '@/plugins/auth'; |
| | | import type cache from '@/plugins/cache'; |
| | | import type animate from '@/animate'; |
| | | import type { useDict } from '@/utils/dict'; |
| | | import type { addDateRange, handleTree, selectDictLabel, selectDictLabels, parseTime } from '@/utils/ruoyi'; |
| | | import type { getConfigKey, updateConfigByKey } from '@/api/system/config'; |
| | | import type { download as rd } from '@/utils/request'; |
| | | |
| | | declare module 'vue' { |
| | | export interface ComponentCustomProperties { |
| | | declare module '@vue/runtime-core' { |
| | | interface ComponentCustomProperties { |
| | | // å
¨å±æ¹æ³å£°æ |
| | | $modal: typeof modal; |
| | | $tab: typeof tab; |
| | | $download: typeof download; |
| | | $auth: typeof auth; |
| | | $cache: typeof cache; |
| | | animate: typeof animate; |
| | | |
| | | useDict: typeof useDict; |
| | | addDateRange: typeof addDateRange; |
| | | download: typeof download1; |
| | | download: typeof rd; |
| | | handleTree: typeof handleTree; |
| | | getConfigKey: typeof getConfigKey; |
| | | updateConfigByKey: typeof updateConfigByKey; |
| | |
| | | import { RouteRecordRaw } from 'vue-router'; |
| | | |
| | | declare module 'vue-router' { |
| | | type RouteOption = { |
| | | declare type RouteOption = { |
| | | hidden?: boolean; |
| | | permissions?: string[]; |
| | | roles?: string[]; |
| | |
| | | query?: string; |
| | | } & RouteRecordRaw; |
| | | |
| | | interface _RouteLocationBase { |
| | | declare interface _RouteLocationBase { |
| | | children?: RouteOption[]; |
| | | } |
| | | |
| | | interface RouteLocationOptions { |
| | | declare interface RouteLocationOptions { |
| | | fullPath?: string; |
| | | } |
| | | |
| | | interface TagView extends Partial<_RouteLocationBase> { |
| | | declare interface TagView extends Partial<_RouteLocationBase> { |
| | | title?: string; |
| | | meta?: { |
| | | link?: string; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | declare module 'vform3-builds' { |
| | | const content: any; |
| | | export = content; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { CSSProperties } from 'vue'; |
| | | import { createTypes, VueTypeValidableDef, VueTypesInterface } from 'vue-types'; |
| | | |
| | | type PropTypes = VueTypesInterface & { |
| | | readonly style: VueTypeValidableDef<CSSProperties>; |
| | | }; |
| | | |
| | | const propTypes = createTypes({ |
| | | func: undefined, |
| | | bool: undefined, |
| | | string: undefined, |
| | | number: undefined, |
| | | object: undefined, |
| | | integer: undefined |
| | | }) as PropTypes; |
| | | |
| | | propTypes.extend([ |
| | | { |
| | | name: 'style', |
| | | getter: true, |
| | | type: [String, Object], |
| | | default: undefined |
| | | } |
| | | ]); |
| | | export { propTypes }; |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="é¨é¨id" prop="deptId"> |
| | | <el-input v-model="queryParams.deptId" placeholder="请è¾å
¥é¨é¨id" clearable @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['demo:demo:edit']">ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['demo:demo:remove']">å é¤</el-button> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['demo:demo:remove']" |
| | | >å é¤</el-button |
| | | > |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['demo:demo:export']">导åº</el-button> |
| | |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | </el-card> |
| | | <!-- æ·»å æä¿®æ¹æµè¯åå¯¹è¯æ¡ --> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | |
| | | <script setup name="Demo" lang="ts"> |
| | | import { listDemo, getDemo, delDemo, addDemo, updateDemo } from '@/api/demo/demo'; |
| | | import { DemoVO, DemoQuery, DemoForm } from '@/api/demo/demo/types'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { ElForm } from 'element-plus'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | |
| | | const multiple = ref(true); |
| | | const total = ref(0); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const demoFormRef = ref(ElForm); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const demoFormRef = ref<ElFormInstance>(); |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = {...initFormData}; |
| | | demoFormRef.value.resetFields(); |
| | | demoFormRef.value?.resetFields(); |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | |
| | |
| | | |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | demoFormRef.value.validate(async (valid: boolean) => { |
| | | demoFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | if (form.value.id) { |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="æ èç¹å" prop="treeName"> |
| | | <el-input v-model="queryParams.treeName" placeholder="请è¾å
¥æ èç¹å" clearable @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | <script setup name="Tree" lang="ts"> |
| | | import { listTree, getTree, delTree, addTree, updateTree } from "@/api/demo/tree"; |
| | | import { TreeVO, TreeQuery, TreeForm } from '@/api/demo/tree/types'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { ElForm, ElTable } from 'element-plus'; |
| | | |
| | | |
| | | type TreeOption = { |
| | |
| | | const isExpandAll = ref(true); |
| | | const loading = ref(false); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const treeFormRef = ref(ElForm); |
| | | const treeTableRef = ref(ElTable) |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const treeFormRef = ref<ElFormInstance>(); |
| | | const treeTableRef = ref<ElTableInstance>() |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | |
| | | // 表åéç½® |
| | | const reset = () => { |
| | | form.value = {...initFormData} |
| | | treeFormRef.value.resetFields(); |
| | | treeFormRef.value?.resetFields(); |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | |
| | |
| | | /** å±å¼/æå æä½ */ |
| | | const toggleExpandAll = (data: TreeVO[], status: boolean) => { |
| | | data.forEach((item) => { |
| | | treeTableRef.value.toggleRowExpansion(item, status) |
| | | treeTableRef.value?.toggleRowExpansion(item, status) |
| | | if (item.children && item.children.length > 0) toggleExpandAll(item.children, status) |
| | | }) |
| | | } |
| | |
| | | |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | treeFormRef.value.validate(async (valid: boolean) => { |
| | | treeFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | if (form.value.id) { |
| | |
| | | } |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | await getList(); |
| | | } |
| | | }); |
| | | } |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import errImage from '@/assets/401_images/401.gif'; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | |
| | | let { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | |
| | | import { encrypt, decrypt } from '@/utils/jsencrypt'; |
| | | import { useUserStore } from '@/store/modules/user'; |
| | | import { LoginData, TenantVO } from '@/api/types'; |
| | | import { ElForm, FormRules } from 'element-plus'; |
| | | import { to } from 'await-to-js'; |
| | | import { HttpStatus } from "@/enums/RespEnum"; |
| | | |
| | | const userStore = useUserStore(); |
| | | const router = useRouter(); |
| | | |
| | | const loginForm = ref<LoginData>({ |
| | | tenantId: "000000", |
| | | tenantId: '000000', |
| | | username: 'admin', |
| | | password: 'admin123', |
| | | rememberMe: false, |
| | |
| | | uuid: '' |
| | | }); |
| | | |
| | | const loginRules: FormRules = { |
| | | const loginRules: ElFormRules = { |
| | | tenantId: [{ required: true, trigger: "blur", message: "请è¾å
¥æ¨çç§æ·ç¼å·" }], |
| | | username: [{ required: true, trigger: 'blur', message: '请è¾å
¥æ¨çè´¦å·' }], |
| | | password: [{ required: true, trigger: 'blur', message: '请è¾å
¥æ¨çå¯ç ' }], |
| | |
| | | // 注åå¼å
³ |
| | | const register = ref(false); |
| | | const redirect = ref(undefined); |
| | | const loginRef = ref(ElForm); |
| | | const loginRef = ref<ElFormInstance>(); |
| | | // ç§æ·å表 |
| | | const tenantList = ref<TenantVO[]>([]); |
| | | |
| | | const handleLogin = () => { |
| | | loginRef.value.validate(async (valid: boolean, fields: any) => { |
| | | loginRef.value?.validate(async (valid: boolean, fields: any) => { |
| | | if (valid) { |
| | | loading.value = true; |
| | | // å¾éäºéè¦è®°ä½å¯ç è®¾ç½®å¨ cookie ä¸è®¾ç½®è®°ä½ç¨æ·ååå¯ç |
| | |
| | | Cookies.remove('rememberMe'); |
| | | } |
| | | // è°ç¨actionçç»å½æ¹æ³ |
| | | // prittier-ignore |
| | | const [err] = await to(userStore.login(loginForm.value)); |
| | | if (!err) { |
| | | await router.push({ path: redirect.value || '/' }); |
| | |
| | | */ |
| | | const doSocialLogin = (type: string) => { |
| | | authBinding(type).then((res: any) => { |
| | | if (res.code === 200) { |
| | | if (res.code === HttpStatus.SUCCESS) { |
| | | // è·åææå°å跳转 |
| | | window.location.href = res.data; |
| | | } else { |
| | |
| | | <div class="p-2"> |
| | | <el-row> |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <Monitor style="width: 1em; height: 1em; vertical-align: middle;" /> |
| | | <span style="vertical-align: middle;">åºæ¬ä¿¡æ¯</span> |
| | |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <PieChart style="width: 1em; height: 1em; vertical-align: middle;" /> |
| | | <span style="vertical-align: middle;">å½ä»¤ç»è®¡</span> |
| | |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <Odometer style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">å
åä¿¡æ¯</span> |
| | | </template> |
| | |
| | | <script setup name="Cache" lang="ts"> |
| | | import { getCache } from '@/api/monitor/cache'; |
| | | import * as echarts from 'echarts'; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | |
| | | const cache = ref<any>({}); |
| | | const commandstats = ref(); |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="ç»å½å°å" prop="ipaddr"> |
| | | <el-input v-model="queryParams.ipaddr" placeholder="请è¾å
¥ç»å½å°å" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | |
| | | <script setup name="Logininfor" lang="ts"> |
| | | import { list, delLoginInfo, cleanLoginInfo, unlockLoginInfo } from "@/api/monitor/loginInfo"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { LoginInfoQuery, LoginInfoVO } from "@/api/monitor/loginInfo/types"; |
| | | import { DateModelType } from 'element-plus'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { sys_common_status } = toRefs<any>(proxy?.useDict("sys_common_status")); |
| | |
| | | const dateRange = ref<[DateModelType,DateModelType]>(['', '']); |
| | | const defaultSort = ref<any>({ prop: "loginTime", order: "descending" }); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const loginInfoTableRef = ref(ElTable); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const loginInfoTableRef = ref<ElTableInstance>(); |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = ref<LoginInfoQuery>({ |
| | | pageNum: 1, |
| | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | loginInfoTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order); |
| | | loginInfoTableRef.value?.sort(defaultSort.value.prop, defaultSort.value.order); |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | const handleSelectionChange = (selection: LoginInfoVO[]) => { |
| | |
| | | const infoIds = row?.infoId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤è®¿é®ç¼å·ä¸º"' + infoIds + '"çæ°æ®é¡¹?'); |
| | | await delLoginInfo(infoIds); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | /** æ¸
空æé®æä½ */ |
| | | const handleClean = async () => { |
| | | await proxy?.$modal.confirm("æ¯å¦ç¡®è®¤æ¸
空ææç»å½æ¥å¿æ°æ®é¡¹?"); |
| | | await cleanLoginInfo(); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("æ¸
空æå"); |
| | | } |
| | | /** è§£éæé®æä½ */ |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <div class="search"> |
| | | <div class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true"> |
| | | <el-form-item label="ç»å½å°å" prop="ipaddr"> |
| | | <el-input v-model="queryParams.ipaddr" placeholder="请è¾å
¥ç»å½å°å" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | <div class="panel"> |
| | | <el-card shadow="hover"> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="onlineList.slice((queryParams.pageNum - 1) * queryParams.pageSize, queryParams.pageNum * queryParams.pageSize)" |
| | |
| | | </el-table> |
| | | |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" /> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Online" lang="ts"> |
| | | import { forceLogout, list as initData } from "@/api/monitor/online"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { OnlineQuery, OnlineVO } from "@/api/monitor/online/types"; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | const loading = ref(true); |
| | | const total = ref(0); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | |
| | | const queryParams = ref<OnlineQuery>({ |
| | | pageNum: 1, |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** 强éæé®æä½ */ |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="ç³»ç»æ¨¡å" prop="title"> |
| | | <el-input v-model="queryParams.title" placeholder="请è¾å
¥ç³»ç»æ¨¡å" clearable style="width: 240px;" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | |
| | | <script setup name="Operlog" lang="ts"> |
| | | import { list, delOperlog, cleanOperlog } from '@/api/monitor/operlog'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { OperLogForm, OperLogQuery, OperLogVO } from '@/api/monitor/operlog/types'; |
| | | import { DateModelType } from 'element-plus'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { sys_oper_type, sys_common_status } = toRefs<any>(proxy?.useDict("sys_oper_type","sys_common_status")); |
| | |
| | | const dateRange = ref<[DateModelType, DateModelType]>(['', '']); |
| | | const defaultSort = ref<any>({ prop: "operTime", order: "descending" }); |
| | | |
| | | const operLogTableRef = ref(ElTable); |
| | | const queryFormRef = ref(ElForm); |
| | | const operLogTableRef = ref<ElTableInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | operLogTableRef.value.sort(defaultSort.value.prop, defaultSort.value.order); |
| | | operLogTableRef.value?.sort(defaultSort.value.prop, defaultSort.value.order); |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | const handleSelectionChange = (selection: OperLogVO[]) => { |
| | |
| | | const operIds = row?.operId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿¥å¿ç¼å·ä¸º"' + operIds + '"çæ°æ®é¡¹?'); |
| | | await delOperlog(operIds); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | |
| | |
| | | const handleClean = async () => { |
| | | await proxy?.$modal.confirm("æ¯å¦ç¡®è®¤æ¸
ç©ºæææä½æ¥å¿æ°æ®é¡¹?"); |
| | | await cleanOperlog(); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("æ¸
空æå"); |
| | | } |
| | | |
| | |
| | | <script setup lang="ts"> |
| | | import { getCodeImg, register, getTenantList } from '@/api/login'; |
| | | import { RegisterForm, TenantVO } from '@/api/types'; |
| | | import { FormRules } from 'element-plus'; |
| | | import { to } from 'await-to-js'; |
| | | |
| | | const router = useRouter(); |
| | |
| | | } |
| | | }; |
| | | |
| | | const registerRules: FormRules = { |
| | | const registerRules: ElFormRules = { |
| | | tenantId: [ |
| | | { required: true, trigger: "blur", message: "请è¾å
¥æ¨çç§æ·ç¼å·" } |
| | | ], |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="åæ°åç§°" prop="configName"> |
| | | <el-input v-model="queryParams.configName" placeholder="请è¾å
¥åæ°åç§°" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | <script setup name="Config" lang="ts"> |
| | | import { listConfig, getConfig, delConfig, addConfig, updateConfig, refreshCache } from "@/api/system/config"; |
| | | import { ConfigForm, ConfigQuery, ConfigVO } from "@/api/system/config/types"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { DateModelType } from 'element-plus'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { sys_yes_no } = toRefs<any>(proxy?.useDict("sys_yes_no")); |
| | |
| | | const total = ref(0); |
| | | const dateRange = ref<[DateModelType, DateModelType]>(['', '']); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const configFormRef = ref(ElForm); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const configFormRef = ref<ElFormInstance>(); |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: '' |
| | |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = {...initFormData}; |
| | | configFormRef.value.resetFields(); |
| | | configFormRef.value?.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | configFormRef.value.validate(async (valid: boolean) => { |
| | | configFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.configId ? await updateConfig(form.value) : await addConfig(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | await getList(); |
| | | } |
| | | }); |
| | | } |
| | |
| | | const configIds = row?.configId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åæ°ç¼å·ä¸º"' + configIds + '"çæ°æ®é¡¹ï¼'); |
| | | await delConfig(configIds); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | /** å¯¼åºæé®æä½ */ |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px"> |
| | | <el-form-item label="èååç§°" prop="menuName"> |
| | | <el-input v-model="queryParams.deptName" placeholder="请è¾å
¥é¨é¨åç§°" clearable @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="1.5"> |
| | |
| | | |
| | | <script setup name="Dept" lang="ts"> |
| | | import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept" |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { DeptForm, DeptQuery, DeptVO } from "@/api/system/dept/types"; |
| | | |
| | | interface DeptOptionsType { |
| | |
| | | title: '' |
| | | }); |
| | | |
| | | const deptTableRef = ref(ElTable); |
| | | const queryFormRef = ref(ElForm); |
| | | const deptFormRef = ref(ElForm); |
| | | const deptTableRef = ref<ElTableInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const deptFormRef = ref<ElFormInstance>(); |
| | | |
| | | const initFormData: DeptForm = { |
| | | deptId: undefined, |
| | |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = {...initFormData}; |
| | | deptFormRef.value.resetFields(); |
| | | deptFormRef.value?.resetFields(); |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery() |
| | | } |
| | | /** æ°å¢æé®æä½ */ |
| | |
| | | /** å±å¼/æå ææ */ |
| | | const toggleExpandAll = (data: DeptVO[], status: boolean) => { |
| | | data.forEach((item) => { |
| | | deptTableRef.value.toggleRowExpansion(item, status) |
| | | deptTableRef.value?.toggleRowExpansion(item, status) |
| | | if(item.children && item.children.length > 0) toggleExpandAll(item.children, status) |
| | | }) |
| | | } |
| | |
| | | const res = await getDept(row.deptId); |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹é¨é¨"; |
| | | nextTick(async () => { |
| | | await nextTick(async () => { |
| | | reset(); |
| | | form.value = res.data |
| | | const response = await listDeptExcludeChild(row.deptId); |
| | |
| | | if (data) { |
| | | deptOptions.value = data; |
| | | if (data.length === 0) { |
| | | const noResultsOptions: DeptOptionsType = { deptId: res.data.parentId, deptName: res.data.parentName, children: [] }; |
| | | const noResultsOptions: DeptOptionsType = { |
| | | deptId: res.data.parentId, |
| | | deptName: res.data.parentName, |
| | | children: [] |
| | | }; |
| | | deptOptions.value.push(noResultsOptions); |
| | | } |
| | | } |
| | |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | deptFormRef.value.validate(async (valid: boolean) => { |
| | | deptFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.deptId ? await updateDept(form.value) : await addDept(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | await getList(); |
| | | } |
| | | }) |
| | | } |
| | |
| | | const handleDelete = async (row: DeptVO) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å称为"' + row.deptName + '"çæ°æ®é¡¹?'); |
| | | await delDept(row.deptId); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictType"> |
| | | <el-select v-model="queryParams.dictType" style="width: 200px"> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type"; |
| | | import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data"; |
| | | import { DictTypeVO } from '@/api/system/dict/type/types'; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { DictDataForm, DictDataQuery, DictDataVO } from "@/api/system/dict/data/types"; |
| | | import { ElForm } from 'element-plus'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance |
| | | const { sys_normal_disable } = toRefs<any>(proxy?.useDict("sys_normal_disable")); |
| | |
| | | const defaultDictType = ref(""); |
| | | const typeOptions = ref<DictTypeVO[]>([]); |
| | | |
| | | const dataFormRef = ref(ElForm); |
| | | const queryFormRef = ref(ElForm); |
| | | const dataFormRef = ref<ElFormInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = { ...initFormData }; |
| | | dataFormRef.value.resetFields(); |
| | | dataFormRef.value?.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.dictType = defaultDictType.value; |
| | | handleQuery(); |
| | | } |
| | |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | dataFormRef.value.validate(async (valid: boolean) => { |
| | | dataFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.dictCode ? await updateData(form.value) : await addData(form.value); |
| | | useDictStore().removeDict(queryParams.value.dictType); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | await getList(); |
| | | |
| | | } |
| | | }); |
| | |
| | | const dictCodes = row?.dictCode || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤åå
¸ç¼ç 为"' + dictCodes + '"çæ°æ®é¡¹ï¼'); |
| | | await delData(dictCodes); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | useDictStore().removeDict(queryParams.value.dictType); |
| | | |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="åå
¸åç§°" prop="dictName"> |
| | | <el-input v-model="queryParams.dictName" placeholder="请è¾å
¥åå
¸åç§°" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | <script setup name="Dict" lang="ts"> |
| | | import useDictStore from '@/store/modules/dict' |
| | | import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { DictTypeForm, DictTypeQuery, DictTypeVO } from "@/api/system/dict/type/types"; |
| | | import { DateModelType } from 'element-plus'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { sys_normal_disable } = toRefs<any>(proxy?.useDict("sys_normal_disable")) |
| | |
| | | const total = ref(0); |
| | | const dateRange = ref<[DateModelType, DateModelType]>(['', '']); |
| | | |
| | | const dictFormRef = ref(ElForm); |
| | | const queryFormRef = ref(ElForm); |
| | | const dictFormRef = ref<ElFormInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = {...initFormData}; |
| | | dictFormRef.value.resetFields(); |
| | | dictFormRef.value?.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** æ°å¢æé®æä½ */ |
| | |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | dictFormRef.value.validate(async (valid: boolean) => { |
| | | dictFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.dictId ? await updateType(form.value) : await addType(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px"> |
| | | <el-form-item label="èååç§°" prop="menuName"> |
| | | <el-input v-model="queryParams.menuName" placeholder="请è¾å
¥èååç§°" clearable @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="1.5"> |
| | |
| | | :data="menuList" |
| | | row-key="menuId" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | border |
| | | ref="menuTableRef" |
| | | :default-expand-all="isExpandAll" |
| | | > |
| | |
| | | <script setup name="Menu" lang="ts"> |
| | | import { addMenu, delMenu, getMenu, listMenu, updateMenu } from '@/api/system/menu'; |
| | | import { MenuForm, MenuQuery, MenuVO } from '@/api/system/menu/types'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { MenuTypeEnum } from '@/enums/MenuTypeEnum'; |
| | | import { ElTable, ElForm } from 'element-plus'; |
| | | |
| | | interface MenuOptionsType { |
| | | menuId: number; |
| | |
| | | title: '' |
| | | }); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const menuFormRef = ref(ElForm); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const menuFormRef = ref<ElFormInstance>(); |
| | | const initFormData = { |
| | | path: '', |
| | | menuId: undefined, |
| | |
| | | }, |
| | | }) |
| | | |
| | | const menuTableRef = ref(ElTable); |
| | | const menuTableRef = ref<ElTableInstance>(); |
| | | |
| | | const { queryParams, form, rules } = toRefs<PageData<MenuForm, MenuQuery>>(data) |
| | | /** æ¥è¯¢èåå表 */ |
| | |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = { ...initFormData }; |
| | | menuFormRef.value.resetFields(); |
| | | menuFormRef.value?.resetFields(); |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** æ°å¢æé®æä½ */ |
| | |
| | | /** å±å¼/æå ææ */ |
| | | const toggleExpandAll = (data: MenuVO[], status: boolean) => { |
| | | data.forEach((item: MenuVO) => { |
| | | menuTableRef.value.toggleRowExpansion(item, status) |
| | | menuTableRef.value?.toggleRowExpansion(item, status) |
| | | if (item.children && item.children.length > 0) toggleExpandAll(item.children, status) |
| | | }) |
| | | } |
| | |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | menuFormRef.value.validate(async (valid: boolean) => { |
| | | menuFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.menuId ? await updateMenu(form.value) : await addMenu(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | await getList(); |
| | | } |
| | | }) |
| | | } |
| | |
| | | const handleDelete = async (row: MenuVO) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å称为"' + row.menuName + '"çæ°æ®é¡¹?'); |
| | | await delMenu(row.menuId); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="å
¬åæ é¢" prop="noticeTitle"> |
| | | <el-input v-model="queryParams.noticeTitle" placeholder="请è¾å
¥å
¬åæ é¢" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | |
| | | <script setup name="Notice" lang="ts"> |
| | | import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { NoticeForm, NoticeQuery, NoticeVO } from "@/api/system/notice/types"; |
| | | import { ElForm } from 'element-plus'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { sys_notice_status, sys_notice_type } = toRefs<any>(proxy?.useDict("sys_notice_status", "sys_notice_type")); |
| | |
| | | const multiple = ref(true); |
| | | const total = ref(0); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const noticeFormRef = ref(ElForm); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const noticeFormRef = ref<ElFormInstance>(); |
| | | |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = { ...initFormData }; |
| | | noticeFormRef.value.resetFields(); |
| | | noticeFormRef.value?.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | noticeFormRef.value.validate(async (valid: boolean) => { |
| | | noticeFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.noticeId ? await updateNotice(form.value) : await addNotice(form.value); |
| | | proxy?.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | await getList(); |
| | | } |
| | | }); |
| | | } |
| | |
| | | const noticeIds = row?.noticeId || ids.value |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å
¬åç¼å·ä¸º"' + noticeIds + '"çæ°æ®é¡¹ï¼'); |
| | | await delNotice(noticeIds); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="é
ç½®key" prop="configKey"> |
| | | <el-input v-model="queryParams.configKey" placeholder="é
ç½®key" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | updateOssConfig, |
| | | changeOssConfigStatus |
| | | } from "@/api/system/ossConfig"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { OssConfigForm, OssConfigQuery, OssConfigVO } from "@/api/system/ossConfig/types"; |
| | | import { ElForm } from 'element-plus'; |
| | | |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance |
| | |
| | | const multiple = ref(true); |
| | | const total = ref(0); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const ossConfigFormRef = ref(ElForm); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const ossConfigFormRef = ref<ElFormInstance>(); |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = { ...initFormData }; |
| | | ossConfigFormRef.value.resetFields(); |
| | | ossConfigFormRef.value?.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** éæ©æ¡æ° */ |
| | |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | ossConfigFormRef.value.validate(async (valid: boolean) => { |
| | | ossConfigFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | if (form.value.ossConfigId) { |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="æä»¶å" prop="fileName"> |
| | | <el-input v-model="queryParams.fileName" placeholder="请è¾å
¥æä»¶å" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | <script setup name="Oss" lang="ts"> |
| | | import { listOss, delOss } from "@/api/system/oss"; |
| | | import ImagePreview from "@/components/ImagePreview/index.vue"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { OssForm, OssQuery, OssVO } from "@/api/system/oss/types"; |
| | | import { DateModelType } from 'element-plus'; |
| | | |
| | | const router = useRouter(); |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | // é»è®¤æåº |
| | | const defaultSort = ref({ prop: 'createTime', order: 'ascending' }); |
| | | |
| | | const ossFormRef = ref(ElForm); |
| | | const queryFormRef = ref(ElForm); |
| | | const ossFormRef = ref<ElFormInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | |
| | | const initFormData = { |
| | | file: undefined, |
| | |
| | | /** 表åéç½® */ |
| | | function reset() { |
| | | form.value = { ...initFormData }; |
| | | ossFormRef.value.resetFields(); |
| | | ossFormRef.value?.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | function handleQuery() { |
| | |
| | | function resetQuery() { |
| | | showTable.value = false; |
| | | daterangeCreateTime.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.orderByColumn = defaultSort.value.prop; |
| | | queryParams.value.isAsc = defaultSort.value.order; |
| | | handleQuery(); |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70"> |
| | | <el-form-item label="å²ä½ç¼ç " prop="postCode"> |
| | | <el-input v-model="queryParams.postCode" placeholder="请è¾å
¥å²ä½ç¼ç " clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | <script setup name="Post" lang="ts"> |
| | | import { listPost, addPost, delPost, getPost, updatePost } from "@/api/system/post"; |
| | | import { PostForm, PostQuery, PostVO } from "@/api/system/post/types"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { sys_normal_disable } = toRefs<any>(proxy?.useDict("sys_normal_disable")); |
| | |
| | | const multiple = ref(true); |
| | | const total = ref(0); |
| | | |
| | | const postFormRef = ref(ElForm); |
| | | const queryFormRef = ref(ElForm); |
| | | const postFormRef = ref<ElFormInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = {...initFormData}; |
| | | postFormRef.value.resetFields(); |
| | | postFormRef.value?.resetFields(); |
| | | } |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | postFormRef.value.validate(async (valid: boolean) => { |
| | | postFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.postId ? await updatePost(form.value) : await addPost(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | await getList(); |
| | | } |
| | | }); |
| | | } |
| | |
| | | const postIds = row?.postId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤å²ä½ç¼å·ä¸º"' + postIds + '"çæ°æ®é¡¹ï¼'); |
| | | await delPost(postIds); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | /** å¯¼åºæé®æä½ */ |
| | |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total > 0" |
| | | :total="total" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> |
| | | <select-user ref="selectRef" :roleId="queryParams.roleId" @ok="handleQuery" /> |
| | | </el-card> |
| | | </div> |
| | |
| | | <script setup name="AuthUser" lang="ts"> |
| | | import { allocatedUserList, authUserCancel, authUserCancelAll } from "@/api/system/role"; |
| | | import { UserQuery } from "@/api/system/user/types"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { UserVO } from "@/api/system/user/types"; |
| | | import SelectUser from "./selectUser.vue"; |
| | | // import { ElForm, ElSelect} from 'element-plus'; |
| | | |
| | | |
| | | const route = useRoute(); |
| | |
| | | const total = ref(0); |
| | | const userIds = ref<Array<string | number>>([]); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const selectRef = ref(SelectUser); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const selectRef = ref<InstanceType<typeof SelectUser>>(); |
| | | |
| | | const queryParams = reactive<UserQuery>({ |
| | | pageNum: 1, |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery=() =>{ |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | // å¤éæ¡é䏿°æ® |
| | |
| | | } |
| | | /** æå¼ææç¨æ·è¡¨å¼¹çª */ |
| | | const openSelectUser = () => { |
| | | selectRef.value.show(); |
| | | selectRef.value?.show(); |
| | | } |
| | | /** åæ¶æææé®æä½ */ |
| | | const cancelAuthUser = async (row: UserVO) => { |
| | | await proxy?.$modal.confirm('确认è¦åæ¶è¯¥ç¨æ·"' + row.userName + '"è§è²åï¼'); |
| | | await authUserCancel({ userId: row.userId, roleId: queryParams.roleId }); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("åæ¶æææå"); |
| | | } |
| | | /** æ¹éåæ¶æææé®æä½ */ |
| | |
| | | const uIds = userIds.value.join(","); |
| | | await proxy?.$modal.confirm("æ¯å¦åæ¶éä¸ç¨æ·æææ°æ®é¡¹?"); |
| | | await authUserCancelAll({ roleId: roleId, userIds: uIds }); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("åæ¶æææå"); |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px"> |
| | | <el-form-item label="è§è²åç§°" prop="roleName"> |
| | | <el-input v-model="queryParams.roleName" placeholder="请è¾å
¥è§è²åç§°" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | |
| | | <el-button @click="resetQuery" icon="Refresh">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="1.5"> |
| | |
| | | import { roleMenuTreeselect, treeselect as menuTreeselect } from '@/api/system/menu/index'; |
| | | import { RoleVO, RoleForm, RoleQuery, DeptTreeOption } from '@/api/system/role/types'; |
| | | import { MenuTreeOption, RoleMenuTree } from '@/api/system/menu/types'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { ElTree, ElForm, DateModelType } from 'element-plus'; |
| | | |
| | | const router = useRouter(); |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | { value: "5", label: "ä»
æ¬äººæ°æ®æé" } |
| | | ]) |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const roleFormRef = ref(ElForm); |
| | | const dataScopeRef = ref(ElForm); |
| | | const menuRef = ref(ElTree); |
| | | const deptRef = ref(ElTree); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const roleFormRef = ref<ElFormInstance>(); |
| | | const dataScopeRef = ref<ElFormInstance>(); |
| | | const menuRef = ref<ElTreeInstance>(); |
| | | const deptRef = ref<ElTreeInstance>(); |
| | | |
| | | const initForm: RoleForm = { |
| | | roleId: undefined, |
| | |
| | | /** éç½® */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['', ''] |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /**å é¤æé®æä½ */ |
| | |
| | | menuOptions.value = res.data; |
| | | } |
| | | /** ææé¨é¨èç¹æ°æ® */ |
| | | const getDeptAllCheckedKeys = () => { |
| | | const getDeptAllCheckedKeys = (): any => { |
| | | // ç®å被éä¸çé¨é¨èç¹ |
| | | let checkedKeys = deptRef.value.getCheckedKeys(); |
| | | let checkedKeys = deptRef.value?.getCheckedKeys(); |
| | | // åéä¸çé¨é¨èç¹ |
| | | let halfCheckedKeys = deptRef.value.getHalfCheckedKeys(); |
| | | checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys); |
| | | let halfCheckedKeys = deptRef.value?.getHalfCheckedKeys(); |
| | | if (halfCheckedKeys) { |
| | | checkedKeys?.unshift.apply(checkedKeys, halfCheckedKeys); |
| | | } |
| | | return checkedKeys |
| | | } |
| | | /** éç½®æ°å¢ç表å以åå
¶ä»æ°æ® */ |
| | | const reset = () => { |
| | | menuRef.value.setCheckedKeys([]); |
| | | menuRef.value?.setCheckedKeys([]); |
| | | menuExpand.value = false |
| | | menuNodeAll.value = false |
| | | deptExpand.value = true |
| | | deptNodeAll.value = false |
| | | form.value = { ...initForm }; |
| | | roleFormRef.value.resetFields(); |
| | | roleFormRef.value?.resetFields(); |
| | | |
| | | } |
| | | |
| | |
| | | const { data } = await getRole(roleId); |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹è§è²"; |
| | | nextTick(() => { |
| | | await nextTick(() => { |
| | | reset(); |
| | | Object.assign(form.value, data); |
| | | form.value.roleSort = Number(form.value.roleSort); |
| | |
| | | let checkedKeys = res.checkedKeys; |
| | | checkedKeys.forEach((v) => { |
| | | nextTick(() => { |
| | | menuRef.value.setChecked(v, true, false); |
| | | menuRef.value?.setChecked(v, true, false); |
| | | }) |
| | | }) |
| | | }) |
| | |
| | | return res.data; |
| | | } |
| | | /** æ æéï¼å±å¼/æå ï¼*/ |
| | | const handleCheckedTreeExpand = (value: any, type: string) => { |
| | | const handleCheckedTreeExpand = (value: boolean, type: string) => { |
| | | if (type == "menu") { |
| | | let treeList = menuOptions.value; |
| | | for (let i = 0; i < treeList.length; i++) { |
| | | if (menuRef.value) { |
| | | menuRef.value.store.nodesMap[treeList[i].id].expanded = value; |
| | | } |
| | | } |
| | | } else if (type == "dept") { |
| | | let treeList = deptOptions.value; |
| | | for (let i = 0; i < treeList.length; i++) { |
| | | if (deptRef.value) { |
| | | deptRef.value.store.nodesMap[treeList[i].id].expanded = value; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | /** æ æéï¼å
¨é/å
¨ä¸éï¼ */ |
| | | const handleCheckedTreeNodeAll = (value: any, type: string) => { |
| | | if (type == "menu") { |
| | | menuRef.value.setCheckedNodes(value ? menuOptions.value : []); |
| | | menuRef.value?.setCheckedNodes(value ? menuOptions.value as any : []); |
| | | } else if (type == "dept") { |
| | | deptRef.value.setCheckedNodes(value ? deptOptions.value : []); |
| | | deptRef.value?.setCheckedNodes(value ? deptOptions.value as any : []); |
| | | } |
| | | } |
| | | /** æ æéï¼ç¶åèå¨ï¼ */ |
| | |
| | | } |
| | | } |
| | | /** ææèåèç¹æ°æ® */ |
| | | const getMenuAllCheckedKeys = () => { |
| | | const getMenuAllCheckedKeys = (): any => { |
| | | // ç®å被éä¸çèåèç¹ |
| | | let checkedKeys = menuRef.value.getCheckedKeys(); |
| | | let checkedKeys = menuRef.value?.getCheckedKeys(); |
| | | // åéä¸çèåèç¹ |
| | | let halfCheckedKeys = menuRef.value.getHalfCheckedKeys(); |
| | | checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys); |
| | | let halfCheckedKeys = menuRef.value?.getHalfCheckedKeys(); |
| | | if (halfCheckedKeys) { |
| | | checkedKeys?.unshift.apply(checkedKeys, halfCheckedKeys); |
| | | } |
| | | return checkedKeys; |
| | | } |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | roleFormRef.value.validate(async (valid: boolean) => { |
| | | roleFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.menuIds = getMenuAllCheckedKeys() |
| | | form.value.roleId ? await updateRole(form.value) : await addRole(form.value); |
| | |
| | | /** éæ©è§è²æéèå´è§¦å */ |
| | | const dataScopeSelectChange = (value: string) => { |
| | | if (value !== "2") { |
| | | deptRef.value.setCheckedKeys([]) |
| | | deptRef.value?.setCheckedKeys([]) |
| | | } |
| | | } |
| | | /** åé
æ°æ®æéæä½ */ |
| | |
| | | Object.assign(form.value, response.data); |
| | | openDataScope.value = true; |
| | | dialog.title = "åé
æ°æ®æé"; |
| | | nextTick(async () => { |
| | | await nextTick(async () => { |
| | | const res = await roleDeptTreeselect; |
| | | nextTick(() => { |
| | | await nextTick(() => { |
| | | if (deptRef.value) { |
| | | deptRef.value.setCheckedKeys(res.checkedKeys); |
| | | } |
| | |
| | | } |
| | | /** åæ¶æé®ï¼æ°æ®æéï¼*/ |
| | | const cancelDataScope = () => { |
| | | dataScopeRef.value.resetFields(); |
| | | dataScopeRef.value?.resetFields(); |
| | | form.value = {...initForm}; |
| | | openDataScope.value = false; |
| | | } |
| | |
| | | import { authUserSelectAll, unallocatedUserList } from "@/api/system/role"; |
| | | import { UserVO } from '@/api/system/user/types'; |
| | | import { UserQuery } from '@/api/system/user/types'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { ElForm, ElTable } from 'element-plus'; |
| | | |
| | | |
| | | const props = defineProps({ |
| | |
| | | phonenumber: undefined |
| | | }) |
| | | |
| | | const tableRef = ref(ElTable); |
| | | const queryFormRef = ref(ElForm); |
| | | const tableRef = ref<ElTableInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | |
| | | const show = () => { |
| | | queryParams.roleId = props.roleId; |
| | |
| | | * éæ©è¡ |
| | | */ |
| | | const clickRow = (row: any) => { |
| | | tableRef.value.toggleRowSelection(row); |
| | | // eleçbug |
| | | tableRef.value?.toggleRowSelection(row); |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | const handleSelectionChange = (selection: UserVO[]) => { |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | getList(); |
| | | } |
| | | |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="ç§æ·ç¼å·" prop="tenantId"> |
| | | <el-input v-model="queryParams.tenantId" placeholder="请è¾å
¥ç§æ·ç¼å·" clearable @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | import { selectTenantPackage } from '@/api/system/tenantPackage'; |
| | | import { TenantForm, TenantQuery, TenantVO } from '@/api/system/tenant/types'; |
| | | import { TenantPkgVO } from '@/api/system/tenantPackage/types'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { ElForm } from 'element-plus'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | |
| | | const multiple = ref(true); |
| | | const total = ref(0); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const tenantFormRef = ref(ElForm); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const tenantFormRef = ref<ElFormInstance>(); |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | |
| | | // 表åéç½® |
| | | const reset = () => { |
| | | form.value = {...initFormData}; |
| | | tenantFormRef.value.resetFields(); |
| | | tenantFormRef.value?.resetFields(); |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | |
| | |
| | | dialog.title = "ä¿®æ¹ç§æ·"; |
| | | nextTick(async () => { |
| | | reset(); |
| | | getTenantPackage(); |
| | | await getTenantPackage(); |
| | | const _id = row?.id || ids.value[0]; |
| | | const res = await getTenant(_id); |
| | | loading.value = false; |
| | |
| | | |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | tenantFormRef.value.validate(async (valid: boolean) => { |
| | | tenantFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | if (form.value.id) { |
| | |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤ç§æ·ç¼å·ä¸º"' + _ids + '"çæ°æ®é¡¹ï¼') |
| | | loading.value = true; |
| | | await delTenant(_ids).finally(() => loading.value = false); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | |
| | | |
| | |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤åæ¥ç§æ·å¥é¤ç§æ·ç¼å·ä¸º"' + row.tenantId + '"çæ°æ®é¡¹ï¼'); |
| | | loading.value = true; |
| | | await syncTenantPackage(row.tenantId, row.packageId); |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("忥æå"); |
| | | } catch {return} finally { |
| | | loading.value = false; |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="å¥é¤åç§°" prop="packageName"> |
| | | <el-input v-model="queryParams.packageName" placeholder="请è¾å
¥å¥é¤åç§°" clearable @keyup.enter="handleQuery" /> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:tenantPackage:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:tenantPackage:edit']" |
| | | >ä¿®æ¹</el-button |
| | | > |
| | | <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:tenantPackage:edit']"> |
| | | ä¿®æ¹ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:tenantPackage:remove']" |
| | | >å é¤</el-button |
| | | > |
| | | <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:tenantPackage:remove']"> |
| | | å é¤ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:tenantPackage:export']">导åº</el-button> |
| | |
| | | </template> |
| | | |
| | | <script setup name="TenantPackage" lang="ts"> |
| | | import { listTenantPackage, getTenantPackage, delTenantPackage, addTenantPackage, updateTenantPackage, changePackageStatus } from "@/api/system/tenantPackage"; |
| | | import { |
| | | listTenantPackage, |
| | | getTenantPackage, |
| | | delTenantPackage, |
| | | addTenantPackage, |
| | | updateTenantPackage, |
| | | changePackageStatus |
| | | } from "@/api/system/tenantPackage"; |
| | | import { treeselect as menuTreeselect, tenantPackageMenuTreeselect } from "@/api/system/menu"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { TenantPkgForm, TenantPkgQuery, TenantPkgVO } from "@/api/system/tenantPackage/types"; |
| | | import { MenuTreeOption } from "@/api/system/menu/types"; |
| | | import { CheckboxValueType, ElTree, ElForm } from 'element-plus'; |
| | | import to from "await-to-js"; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | const menuNodeAll = ref(false); |
| | | const menuOptions = ref<MenuTreeOption[]>([]); |
| | | |
| | | const menuTreeRef = ref(ElTree); |
| | | const queryFormRef = ref(ElForm); |
| | | const tenantPackageFormRef = ref(ElForm); |
| | | const menuTreeRef = ref<ElTreeInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const tenantPackageFormRef = ref<ElFormInstance>(); |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: '' |
| | | title: "" |
| | | }); |
| | | |
| | | |
| | | const initFormData: TenantPkgForm = { |
| | | packageId: undefined, |
| | | packageName: '', |
| | | menuIds: '', |
| | | remark: '', |
| | | packageName: "", |
| | | menuIds: "", |
| | | remark: "", |
| | | menuCheckStrictly: true |
| | | }; |
| | | const data = reactive<PageData<TenantPkgForm, TenantPkgQuery>>({ |
| | |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | packageName: '' |
| | | packageName: "" |
| | | }, |
| | | rules: { |
| | | packageId: [{ required: true, message: "ç§æ·å¥é¤idä¸è½ä¸ºç©º", trigger: "blur" }], |
| | |
| | | const getMenuTreeselect = async() => { |
| | | const { data } = await menuTreeselect(); |
| | | menuOptions.value = data; |
| | | } |
| | | }; |
| | | |
| | | // ææèåèç¹æ°æ® |
| | | const getMenuAllCheckedKeys = () => { |
| | | const getMenuAllCheckedKeys = (): any => { |
| | | // ç®å被éä¸çèåèç¹ |
| | | let checkedKeys = menuTreeRef.value.getCheckedKeys(); |
| | | let checkedKeys = menuTreeRef.value?.getCheckedKeys(); |
| | | // åéä¸çèåèç¹ |
| | | let halfCheckedKeys = menuTreeRef.value.getHalfCheckedKeys(); |
| | | checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys); |
| | | return checkedKeys; |
| | | let halfCheckedKeys = menuTreeRef.value?.getHalfCheckedKeys(); |
| | | if (halfCheckedKeys) { |
| | | checkedKeys?.unshift.apply(checkedKeys, halfCheckedKeys); |
| | | } |
| | | return checkedKeys; |
| | | }; |
| | | |
| | | /** æ ¹æ®ç§æ·å¥é¤IDæ¥è¯¢èåæ ç»æ */ |
| | | const getPackageMenuTreeselect = async(packageId: string | number) => { |
| | | const res = await tenantPackageMenuTreeselect(packageId); |
| | | menuOptions.value = res.data.menus; |
| | | return Promise.resolve(res); |
| | | } |
| | | }; |
| | | |
| | | /** æ¥è¯¢ç§æ·å¥é¤å表 */ |
| | | const getList = async () => { |
| | |
| | | tenantPackageList.value = res.rows; |
| | | total.value = res.total; |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | // ç§æ·å¥é¤ç¶æä¿®æ¹ |
| | | const handleStatusChange = async (row: TenantPkgVO) => { |
| | | let text = row.status === "0" ? "å¯ç¨" : "åç¨"; |
| | | const [err] = await to(proxy?.$modal.confirm('确认è¦"' + text + '""' + row.packageName + '"å¥é¤åï¼') as Promise<any>) |
| | | const [err] = await to(proxy?.$modal.confirm("确认è¦\"" + text + "\"\"" + row.packageName + "\"å¥é¤åï¼") as Promise<any>); |
| | | if (err) { |
| | | row.status = row.status === "0" ? "1" : "0"; |
| | | } else { |
| | | await changePackageStatus(row.packageId, row.status); |
| | | proxy?.$modal.msgSuccess(text + "æå"); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // åæ¶æé® |
| | | const cancel = () => { |
| | | reset(); |
| | | dialog.visible = false; |
| | | } |
| | | }; |
| | | |
| | | // 表åéç½® |
| | | const reset = () => { |
| | | menuTreeRef.value.setCheckedKeys([]); |
| | | menuTreeRef.value?.setCheckedKeys([]); |
| | | menuExpand.value = false; |
| | | menuNodeAll.value = false; |
| | | form.value = {...initFormData}; |
| | | tenantPackageFormRef.value.resetFields(); |
| | | } |
| | | tenantPackageFormRef.value?.resetFields(); |
| | | }; |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | } |
| | | }; |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | }; |
| | | |
| | | // å¤éæ¡é䏿°æ® |
| | | const handleSelectionChange = (selection: TenantPkgVO[]) => { |
| | | ids.value = selection.map(item => item.packageId); |
| | | single.value = selection.length != 1; |
| | | multiple.value = !selection.length; |
| | | } |
| | | }; |
| | | |
| | | // æ æéï¼å±å¼/æå ï¼ |
| | | const handleCheckedTreeExpand = (value: CheckboxValueType, type: string) => { |
| | | if (type == 'menu') { |
| | | if (type == "menu") { |
| | | let treeList = menuOptions.value; |
| | | for (let i = 0; i < treeList.length; i++) { |
| | | menuTreeRef.value.store.nodesMap[treeList[i].id].expanded = value; |
| | | if (menuTreeRef.value) { |
| | | menuTreeRef.value.store.nodesMap[treeList[i].id].expanded = value as boolean; |
| | | } |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // æ æéï¼å
¨é/å
¨ä¸éï¼ |
| | | const handleCheckedTreeNodeAll = (value: CheckboxValueType, type: string) => { |
| | | if (type == 'menu') { |
| | | menuTreeRef.value.setCheckedNodes(value ? menuOptions.value: []); |
| | | if (type == "menu") { |
| | | menuTreeRef.value?.setCheckedNodes(value ? menuOptions.value as any : []); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // æ æéï¼ç¶åèå¨ï¼ |
| | | const handleCheckedTreeConnect = (value: CheckboxValueType, type: string) => { |
| | | if (type == 'menu') { |
| | | if (type == "menu") { |
| | | form.value.menuCheckStrictly = value as boolean; |
| | | } |
| | | } |
| | | }; |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | const handleAdd = () => { |
| | |
| | | nextTick(() => { |
| | | reset(); |
| | | getMenuTreeselect(); |
| | | }) |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | const handleUpdate = (row?: TenantPkgVO) => { |
| | | loading.value = true |
| | | loading.value = true; |
| | | dialog.visible = true; |
| | | dialog.title = "ä¿®æ¹ç§æ·å¥é¤"; |
| | | nextTick(async () => { |
| | |
| | | const response = await getTenantPackage(_packageId); |
| | | loading.value = false; |
| | | form.value = response.data; |
| | | nextTick(async () => { |
| | | await nextTick(async () => { |
| | | const res = await packageMenu; |
| | | let checkedKeys = res.data.checkedKeys |
| | | let checkedKeys = res.data.checkedKeys; |
| | | checkedKeys.forEach((v) => { |
| | | nextTick(() => { |
| | | menuTreeRef.value.setChecked(v, true ,false); |
| | | }) |
| | | }) |
| | | menuTreeRef.value?.setChecked(v, true, false); |
| | | }); |
| | | }) |
| | | } |
| | | }); |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | tenantPackageFormRef.value.validate(async (valid: boolean) => { |
| | | tenantPackageFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | form.value.menuIds = getMenuAllCheckedKeys(); |
| | |
| | | } |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | getList(); |
| | | await getList(); |
| | | } |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row?: TenantPkgVO) => { |
| | | const _packageIds = row?.packageId || ids.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤ç§æ·å¥é¤ç¼å·ä¸º"' + _packageIds + '"çæ°æ®é¡¹ï¼').finally(() => { |
| | | await proxy?.$modal.confirm("æ¯å¦ç¡®è®¤å é¤ç§æ·å¥é¤ç¼å·ä¸º\"" + _packageIds + "\"çæ°æ®é¡¹ï¼").finally(() => { |
| | | loading.value = false; |
| | | }); |
| | | await delTenantPackage(_packageIds); |
| | | loading.value = true; |
| | | getList(); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | }; |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | const handleExport = () => { |
| | | proxy?.download('system/tenantPackage/export', { |
| | | proxy?.download("system/tenantPackage/export", { |
| | | ...queryParams.value |
| | | }, `tenantPackage_${new Date().getTime()}.xlsx`) |
| | | } |
| | | }, `tenantPackage_${new Date().getTime()}.xlsx`); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }) |
| | | }); |
| | | </script> |
| | |
| | | </template> |
| | | |
| | | <script setup name="AuthRole" lang="ts"> |
| | | import { RoleVO } from '@/api/system/role/types'; |
| | | import { getAuthRole, updateAuthRole } from '@/api/system/user'; |
| | | import { UserForm } from '@/api/system/user/types'; |
| | | import { ElTable } from "element-plus"; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { RoleVO } from "@/api/system/role/types"; |
| | | import { getAuthRole, updateAuthRole } from "@/api/system/user"; |
| | | import { UserForm } from "@/api/system/user/types"; |
| | | |
| | | const route = useRoute(); |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | |
| | | const roles = ref<RoleVO[]>([]); |
| | | const form = ref<Partial<UserForm>>({ |
| | | nickName: undefined, |
| | | userName: '', |
| | | userName: "", |
| | | userId: undefined |
| | | }); |
| | | |
| | | const tableRef = ref(ElTable) |
| | | const tableRef = ref<ElTableInstance>(); |
| | | |
| | | /** åå»éä¸è¡æ°æ® */ |
| | | const clickRow = (row: RoleVO) => { |
| | | tableRef.value.toggleRowSelection(row); |
| | | // eleçæ¹æ³æé®é¢ï¼selectedåºè¯¥ä¸ºå¯éåæ° |
| | | tableRef.value?.toggleRowSelection(row); |
| | | }; |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | const handleSelectionChange = (selection: RoleVO[]) => { |
| | |
| | | const submitForm = async () => { |
| | | const userId = form.value.userId; |
| | | const rIds = roleIds.value.join(","); |
| | | await updateAuthRole({ userId: userId as string, roleIds: rIds }) |
| | | await updateAuthRole({ userId: userId as string, roleIds: rIds }); |
| | | proxy?.$modal.msgSuccess("æææå"); |
| | | close(); |
| | | }; |
| | |
| | | if (userId) { |
| | | loading.value = true; |
| | | const res = await getAuthRole(userId as string); |
| | | Object.assign(form.value, res.data.user) |
| | | Object.assign(roles.value, res.data.roles) |
| | | Object.assign(form.value, res.data.user); |
| | | Object.assign(roles.value, res.data.roles); |
| | | total.value = roles.value.length; |
| | | await nextTick(() => { |
| | | roles.value.forEach(row => { |
| | | if (row?.flag) { |
| | | tableRef.value.toggleRowSelection(row); |
| | | tableRef.value?.toggleRowSelection(row, true); |
| | | } |
| | | }); |
| | | }); |
| | | loading.value = false; |
| | | } |
| | | } |
| | | }; |
| | | onMounted(() => { |
| | | getList(); |
| | | }) |
| | | }); |
| | | </script> |
| | |
| | | highlight-current |
| | | default-expand-all |
| | | @node-click="handleNodeClick" |
| | | ></el-tree> |
| | | /> |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :lg="20" :xs="24"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="68px"> |
| | | <el-form-item label="ç¨æ·åç§°" prop="userName"> |
| | | <el-input v-model="queryParams.userName" placeholder="请è¾å
¥ç¨æ·åç§°" clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="ææºå·ç " prop="phonenumber"> |
| | | <el-input v-model="queryParams.phonenumber" placeholder="请è¾å
¥ææºå·ç " clearable style="width: 240px" @keyup.enter="handleQuery" /> |
| | | <el-input |
| | | v-model="queryParams.phonenumber" |
| | | placeholder="请è¾å
¥ææºå·ç " |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="ç¶æ" prop="status"> |
| | |
| | | <el-button @click="resetQuery" icon="Refresh">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | |
| | | </template> |
| | | |
| | | <script setup name="User" lang="ts"> |
| | | import { |
| | | changeUserStatus, |
| | | listUser, |
| | | resetUserPwd, |
| | | delUser, |
| | | getUser, |
| | | updateUser, |
| | | addUser, |
| | | deptTreeSelect |
| | | } from "@/api/system/user" |
| | | import api from "@/api/system/user" |
| | | import { UserForm, UserQuery, UserVO } from '@/api/system/user/types'; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { getToken } from "@/utils/auth"; |
| | | import { treeselect } from "@/api/system/dept"; |
| | | import { DeptVO } from "@/api/system/dept/types"; |
| | | import { RoleVO } from "@/api/system/role/types"; |
| | | import { PostVO } from "@/api/system/post/types"; |
| | | import { DateModelType, ElTree, ElUpload, UploadFile, ElForm } from 'element-plus'; |
| | | import { to } from "await-to-js"; |
| | | |
| | | const router = useRouter(); |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance |
| | | const { sys_normal_disable, sys_user_sex } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex')); |
| | | |
| | | |
| | | const userList = ref<UserVO[]>(); |
| | | const loading = ref(true); |
| | |
| | | ]) |
| | | |
| | | |
| | | const deptTreeRef = ref(ElTree); |
| | | const queryFormRef = ref(ElForm); |
| | | const userFormRef = ref(ElForm); |
| | | const uploadRef = ref(ElUpload); |
| | | const deptTreeRef = ref<ElTreeInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const userFormRef = ref<ElFormInstance>(); |
| | | const uploadRef = ref<ElUploadInstance>(); |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | |
| | | } |
| | | /** æ ¹æ®åç§°çéé¨é¨æ */ |
| | | watchEffect( |
| | | () => {deptTreeRef.value.filter(deptName.value);}, |
| | | () => { deptTreeRef.value?.filter(deptName.value); }, |
| | | { |
| | | flush: 'post' // watchEffectä¼å¨DOMæè½½æè
æ´æ°ä¹åå°±ä¼è§¦åï¼æ¤å±æ§æ§å¶å¨DOMå
ç´ æ´æ°åè¿è¡ |
| | | } |
| | |
| | | |
| | | /** æ¥è¯¢é¨é¨ä¸ææ ç»æ */ |
| | | const getTreeSelect = async () => { |
| | | const res = await deptTreeSelect(); |
| | | const res = await api.deptTreeSelect(); |
| | | deptOptions.value = res.data; |
| | | }; |
| | | |
| | | /** æ¥è¯¢ç¨æ·å表 */ |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const res = await listUser(proxy?.addDateRange(queryParams.value, dateRange.value)); |
| | | const res = await api.listUser(proxy?.addDateRange(queryParams.value, dateRange.value)); |
| | | loading.value = false; |
| | | userList.value = res.rows; |
| | | total.value = res.total; |
| | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['',''] |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | queryParams.value.deptId = undefined; |
| | | deptTreeRef.value.setCurrentKey(null); |
| | | deptTreeRef.value?.setCurrentKey(undefined); |
| | | handleQuery(); |
| | | } |
| | | |
| | |
| | | const userIds = row?.userId || ids.value; |
| | | const [err] = await to(proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤ç¨æ·ç¼å·ä¸º"' + userIds + '"çæ°æ®é¡¹ï¼') as any); |
| | | if (!err) { |
| | | await delUser(userIds); |
| | | await api.delUser(userIds); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | |
| | | let text = row.status === "0" ? "å¯ç¨" : "åç¨" |
| | | try { |
| | | await proxy?.$modal.confirm('确认è¦"' + text + '""' + row.userName + '"ç¨æ·å?'); |
| | | await changeUserStatus(row.userId, row.status); |
| | | await api.changeUserStatus(row.userId, row.status); |
| | | proxy?.$modal.msgSuccess(text + "æå"); |
| | | } catch (err) { |
| | | row.status = row.status === "0" ? "1" : "0"; |
| | |
| | | inputErrorMessage: "ç¨æ·å¯ç é¿åº¦å¿
é¡»ä»äº 5 å 20 ä¹é´", |
| | | })) |
| | | if (!err) { |
| | | await resetUserPwd(row.userId, res.value); |
| | | await api.resetUserPwd(row.userId, res.value); |
| | | proxy?.$modal.msgSuccess("ä¿®æ¹æåï¼æ°å¯ç æ¯ï¼" + res.value); |
| | | } |
| | | } |
| | |
| | | const handleFileSuccess = (response: any, file: UploadFile) => { |
| | | upload.open = false; |
| | | upload.isUploading = false; |
| | | uploadRef.value.handleRemove(file); |
| | | uploadRef.value?.handleRemove(file); |
| | | ElMessageBox.alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导å
¥ç»æ", { dangerouslyUseHTMLString: true }); |
| | | getList(); |
| | | } |
| | | |
| | | /** æäº¤ä¸ä¼ æä»¶ */ |
| | | function submitFileForm() { |
| | | uploadRef.value.submit(); |
| | | uploadRef.value?.submit(); |
| | | } |
| | | |
| | | /** åå§åé¨é¨æ°æ® */ |
| | |
| | | /** éç½®æä½è¡¨å */ |
| | | const reset = () => { |
| | | form.value = { ...initFormData }; |
| | | userFormRef.value.resetFields(); |
| | | userFormRef.value?.resetFields(); |
| | | } |
| | | /** åæ¶æé® */ |
| | | const cancel = () => { |
| | |
| | | nextTick(async () => { |
| | | reset(); |
| | | await initTreeData(); |
| | | const { data } = await getUser(); |
| | | const { data } = await api.getUser(); |
| | | postOptions.value = data.posts; |
| | | roleOptions.value = data.roles; |
| | | form.value.password = initPassword.value; |
| | |
| | | reset(); |
| | | await initTreeData(); |
| | | const userId = row?.userId || ids.value[0] |
| | | const { data } = await getUser(userId) |
| | | const { data } = await api.getUser(userId) |
| | | Object.assign(form.value, data.user); |
| | | postOptions.value = data.posts; |
| | | roleOptions.value = data.roles; |
| | |
| | | |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | userFormRef.value.validate(async (valid: boolean) => { |
| | | userFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | form.value.userId ? await updateUser(form.value) : await addUser(form.value); |
| | | form.value.userId ? await api.updateUser(form.value) : await api.addUser(form.value); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | await getList(); |
| | |
| | | * é置表å |
| | | */ |
| | | const resetForm = () => { |
| | | userFormRef.value.resetFields(); |
| | | userFormRef.value.clearValidate(); |
| | | userFormRef.value?.resetFields(); |
| | | userFormRef.value?.clearValidate(); |
| | | |
| | | form.value.id = undefined; |
| | | form.value.status = '1'; |
| | |
| | | import { getUserProfile } from "@/api/system/user"; |
| | | |
| | | const activeTab = ref("userinfo"); |
| | | const state = ref<{ user: any; roleGroup: string; postGroup: string; auths:any[]}>({ |
| | | const state = ref<Record<string, any>>({ |
| | | user: {}, |
| | | roleGroup: '', |
| | | postGroup: '', |
| | | auths: [], |
| | | auths: [] |
| | | }); |
| | | |
| | | const userForm = ref({}); |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { updateUserPwd } from '@/api/system/user'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { ResetPwdForm } from '@/api/system/user/types' |
| | | import { ElForm } from 'element-plus'; |
| | | import { updateUserPwd } from "@/api/system/user"; |
| | | import type { ResetPwdForm } from "@/api/system/user/types"; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | | |
| | | const pwdRef = ref(ElForm); |
| | | |
| | | const pwdRef = ref<ElFormInstance>(); |
| | | const user = ref<ResetPwdForm>({ |
| | | oldPassword: '', |
| | | newPassword: '', |
| | | confirmPassword: '' |
| | | oldPassword: "", |
| | | newPassword: "", |
| | | confirmPassword: "" |
| | | }); |
| | | |
| | | const equalToPassword = (rule: any, value: string, callback: any) => { |
| | |
| | | }; |
| | | const rules = ref({ |
| | | oldPassword: [{ required: true, message: "æ§å¯ç ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | newPassword: [{ required: true, message: "æ°å¯ç ä¸è½ä¸ºç©º", trigger: "blur" }, { min: 6, max: 20, message: "é¿åº¦å¨ 6 å° 20 个å符", trigger: "blur" }], |
| | | confirmPassword: [{ required: true, message: "确认å¯ç ä¸è½ä¸ºç©º", trigger: "blur" }, { required: true, validator: equalToPassword, trigger: "blur" }] |
| | | newPassword: [{ required: true, message: "æ°å¯ç ä¸è½ä¸ºç©º", trigger: "blur" }, { |
| | | min: 6, |
| | | max: 20, |
| | | message: "é¿åº¦å¨ 6 å° 20 个å符", |
| | | trigger: "blur" |
| | | }], |
| | | confirmPassword: [{ required: true, message: "确认å¯ç ä¸è½ä¸ºç©º", trigger: "blur" }, { |
| | | required: true, |
| | | validator: equalToPassword, |
| | | trigger: "blur" |
| | | }] |
| | | }); |
| | | |
| | | /** æäº¤æé® */ |
| | | const submit = () => { |
| | | pwdRef.value.validate(async (valid: boolean) => { |
| | | pwdRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | await updateUserPwd(user.value.oldPassword, user.value.newPassword) |
| | | await updateUserPwd(user.value.oldPassword, user.value.newPassword); |
| | | proxy?.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | } |
| | | }); |
| | |
| | | <el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload"> |
| | | <el-button> |
| | | éæ© |
| | | <el-icon class="el-icon--right"><Upload /></el-icon> |
| | | <el-icon class="el-icon--right"> |
| | | <Upload /> |
| | | </el-icon> |
| | | </el-button> |
| | | </el-upload> |
| | | </el-col> |
| | |
| | | import { VueCropper } from "vue-cropper"; |
| | | import { uploadAvatar } from "@/api/system/user"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | |
| | | interface Options { |
| | | img: string | ArrayBuffer | null // è£åªå¾ççå°å |
| | | autoCrop: boolean // æ¯å¦é»è®¤çææªå¾æ¡ |
| | | autoCropWidth: number // é»è®¤çææªå¾æ¡å®½åº¦ |
| | | autoCropHeight: number // é»è®¤çææªå¾æ¡é«åº¦ |
| | | fixedBox: boolean // åºå®æªå¾æ¡å¤§å° ä¸å
许æ¹å |
| | | fileName: string |
| | | previews: any // é¢è§æ°æ® |
| | | outputType: string |
| | | visible: boolean |
| | | img: string | ArrayBuffer | null; // è£åªå¾ççå°å |
| | | autoCrop: boolean; // æ¯å¦é»è®¤çææªå¾æ¡ |
| | | autoCropWidth: number; // é»è®¤çææªå¾æ¡å®½åº¦ |
| | | autoCropHeight: number; // é»è®¤çææªå¾æ¡é«åº¦ |
| | | fixedBox: boolean; // åºå®æªå¾æ¡å¤§å° ä¸å
许æ¹å |
| | | fileName: string; |
| | | previews: any; // é¢è§æ°æ® |
| | | outputType: string; |
| | | visible: boolean; |
| | | } |
| | | |
| | | |
| | |
| | | autoCropHeight: 200, |
| | | fixedBox: true, |
| | | outputType: "png", |
| | | fileName: '', |
| | | fileName: "", |
| | | previews: {}, |
| | | visible: false |
| | | }); |
| | |
| | | /** ç¼è¾å¤´å */ |
| | | const editCropper = () => { |
| | | open.value = true; |
| | | } |
| | | }; |
| | | /** æå¼å¼¹åºå±ç»ææ¶çåè° */ |
| | | const modalOpened = () => { |
| | | visible.value = true; |
| | | } |
| | | }; |
| | | /** è¦çé»è®¤ä¸ä¼ è¡ä¸º */ |
| | | const requestUpload = (): any => {} |
| | | const requestUpload = (): any => { |
| | | }; |
| | | /** åå·¦æè½¬ */ |
| | | const rotateLeft = () => { |
| | | cropper.value.rotateLeft(); |
| | | } |
| | | }; |
| | | /** åå³æè½¬ */ |
| | | const rotateRight = () => { |
| | | cropper.value.rotateRight(); |
| | | } |
| | | }; |
| | | /** å¾çç¼©æ¾ */ |
| | | const changeScale = (num: number) => { |
| | | num = num || 1; |
| | | cropper.value.changeScale(num); |
| | | } |
| | | }; |
| | | /** ä¸ä¼ é¢å¤ç */ |
| | | const beforeUpload = (file: any) => { |
| | | if (file.type.indexOf("image/") == -1) { |
| | |
| | | options.fileName = file.name; |
| | | }; |
| | | } |
| | | } |
| | | }; |
| | | /** ä¸ä¼ å¾ç */ |
| | | const uploadImg = async () => { |
| | | cropper.value.getCropBlob(async (data: any) => { |
| | |
| | | const res = await uploadAvatar(formData); |
| | | open.value = false; |
| | | options.img = res.data.imgUrl; |
| | | userStore.avatar = options.img as string; |
| | | userStore.avatar = options.img as string |
| | | proxy?.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | visible.value = false; |
| | | }); |
| | | } |
| | | }; |
| | | /** 宿¶é¢è§ */ |
| | | const realTime = (data: any) => { |
| | | options.previews = data; |
| | | } |
| | | }; |
| | | /** å
³éçªå£ */ |
| | | const closeDialog = () => { |
| | | options.img = userStore.avatar; |
| | | options.visible = false; |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import { updateUserProfile } from "@/api/system/user"; |
| | | import { FormRules } from "element-plus"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import { PropType } from "vue"; |
| | | import { ElForm } from "element-plus"; |
| | | |
| | | const props = defineProps({ |
| | | user: { |
| | | type: Object as PropType<any>, |
| | | required: true |
| | | } |
| | | }); |
| | | const userForm = computed(() => props.user); |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | | const userRef = ref(ElForm); |
| | | |
| | | const rules = ref<FormRules>({ |
| | | const userRef = ref<ElFormInstance>(); |
| | | const rules = ref<ElFormRules>({ |
| | | nickName: [{ required: true, message: "ç¨æ·æµç§°ä¸è½ä¸ºç©º", trigger: "blur" }], |
| | | email: [{ required: true, message: "é®ç®±å°åä¸è½ä¸ºç©º", trigger: "blur" }, { type: "email", message: "请è¾å
¥æ£ç¡®çé®ç®±å°å", trigger: ["blur", "change"] }], |
| | | phonenumber: [{ required: true, message: "ææºå·ç ä¸è½ä¸ºç©º", trigger: "blur" }, { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请è¾å
¥æ£ç¡®çææºå·ç ", trigger: "blur" }], |
| | | email: [{ required: true, message: "é®ç®±å°åä¸è½ä¸ºç©º", trigger: "blur" }, { |
| | | type: "email", |
| | | message: "请è¾å
¥æ£ç¡®çé®ç®±å°å", |
| | | trigger: ["blur", "change"] |
| | | }], |
| | | phonenumber: [{ |
| | | required: true, |
| | | message: "ææºå·ç ä¸è½ä¸ºç©º", |
| | | trigger: "blur" |
| | | }, { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请è¾å
¥æ£ç¡®çææºå·ç ", trigger: "blur" }] |
| | | }); |
| | | |
| | | |
| | | /** æäº¤æé® */ |
| | | const submit = () => { |
| | | userRef.value.validate(async (valid: boolean) => { |
| | | userRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | await updateUserProfile(props.user) |
| | | await updateUserProfile(props.user); |
| | | proxy?.$modal.msgSuccess("ä¿®æ¹æå"); |
| | | } |
| | | }); |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { PropType } from 'vue'; |
| | | import { propTypes } from "@/utils/propTypes"; |
| | | |
| | | const prop = defineProps({ |
| | | info: { |
| | | type: Object as PropType<any>, |
| | | default: () => { |
| | | return {}; |
| | | } |
| | | } |
| | | info: propTypes.any.def({}) |
| | | }); |
| | | |
| | | const infoForm = computed(() => prop.info) |
| | |
| | | import { DbColumnVO, DbTableVO } from '@/api/tool/gen/types'; |
| | | import { optionselect as getDictOptionselect } from '@/api/system/dict/type'; |
| | | import { DictTypeVO } from '@/api/system/dict/type/types'; |
| | | import basicInfoForm from './basicInfoForm.vue'; |
| | | import genInfoForm from "./genInfoForm.vue"; |
| | | import { ComponentInternalInstance } from "vue"; |
| | | import BasicInfoForm from './basicInfoForm.vue'; |
| | | import GenInfoForm from "./genInfoForm.vue"; |
| | | |
| | | const route = useRoute(); |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | const dictOptions = ref<DictTypeVO[]>([]); |
| | | const info = ref<Partial<DbTableVO>>({}); |
| | | |
| | | const basicInfo = ref(basicInfoForm); |
| | | const genInfo = ref(genInfoForm); |
| | | const basicInfo = ref<InstanceType<typeof BasicInfoForm>>(); |
| | | const genInfo = ref<InstanceType<typeof GenInfoForm>>(); |
| | | |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | const basicForm = basicInfo.value.$refs.basicInfoForm; |
| | | const genForm = genInfo.value.$refs.genInfoForm; |
| | | const basicForm = basicInfo.value?.$refs.basicInfoForm; |
| | | const genForm = genInfo.value?.$refs.genInfoForm; |
| | | |
| | | Promise.all([basicForm, genForm].map(getFormPromise)).then(async res => { |
| | | const validateResult = res.every(item => !!item); |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import { listMenu } from '@/api/system/menu'; |
| | | import { ComponentInternalInstance, PropType } from 'vue'; |
| | | import { propTypes } from "@/utils/propTypes"; |
| | | |
| | | interface MenuOptionsType { |
| | | menuId: number | string; |
| | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | | const props = defineProps({ |
| | | info: { |
| | | type: Object as PropType<any>, |
| | | default: null |
| | | }, |
| | | tables: { |
| | | type: Array as PropType<any[]>, |
| | | default: null |
| | | } |
| | | info: propTypes.any.def(null), |
| | | tables: propTypes.any.def(null) |
| | | }); |
| | | |
| | | const infoForm = computed(() => props.info); |
| | |
| | | } |
| | | } |
| | | const setSubTableColumns = (value: string) => { |
| | | table.value.forEach(item => { |
| | | table.value.forEach((item: any) => { |
| | | const name = item.tableName; |
| | | if (value === name) { |
| | | subColumns.value = item.columns; |
| | |
| | | <script setup lang="ts"> |
| | | import { listDbTable, importTable, getDataNames } from '@/api/tool/gen'; |
| | | import { DbTableQuery, DbTableVO } from '@/api/tool/gen/types'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { ElTable, ElForm } from 'element-plus'; |
| | | |
| | | const total = ref(0); |
| | | const visible = ref(false); |
| | |
| | | const dbTableList = ref<Array<DbTableVO>>([]); |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | | const tableRef = ref(ElTable); |
| | | const queryFormRef = ref(ElForm); |
| | | const tableRef = ref<ElTableInstance>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | |
| | | const queryParams = reactive<DbTableQuery>({ |
| | | pageNum: 1, |
| | |
| | | } |
| | | /** åå»éæ©è¡ */ |
| | | const clickRow = (row: DbTableVO) => { |
| | | tableRef.value.toggleRowSelection(row); |
| | | // ele bug |
| | | tableRef.value?.toggleRowSelection(row); |
| | | } |
| | | /** å¤éæ¡é䏿°æ® */ |
| | | const handleSelectionChange = (selection: DbTableVO[]) => { |
| | |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** 导å
¥æé®æä½ */ |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div class="search" v-show="showSearch"> |
| | | <div class="mb-[10px]" v-show="showSearch"> |
| | | <el-card shadow="hover"> |
| | | <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> |
| | | <el-form-item label="æ°æ®æº" prop="dataName"> |
| | | <el-select v-model="queryParams.dataName" filterable clearable placeholder="è¯·éæ©/è¾å
¥æ°æ®æºåç§°" style="width: 200px"> |
| | |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </div> |
| | | </transition> |
| | | |
| | | <el-card shadow="never"> |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | |
| | | :name="(key as any).substring((key as any).lastIndexOf('/') + 1, (key as any).indexOf('.vm'))" |
| | | :key="value" |
| | | > |
| | | <el-link :underline="false" icon="DocumentCopy" v-copyText="value" v-copyText:callback="copyTextSuccess" style="float:right" |
| | | > å¤å¶</el-link |
| | | > |
| | | <el-link :underline="false" icon="DocumentCopy" v-copyText="value" v-copyText:callback="copyTextSuccess" style="float:right"> |
| | | å¤å¶ |
| | | </el-link> |
| | | <pre>{{ value }}</pre> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | |
| | | import { listTable, previewTable, delTable, genCode, synchDb, getDataNames } from '@/api/tool/gen'; |
| | | import { TableQuery, TableVO } from '@/api/tool/gen/types'; |
| | | import router from '@/router'; |
| | | import importTable from './importTable.vue'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { ElForm, DateModelType } from 'element-plus'; |
| | | import ImportTable from './importTable.vue'; |
| | | |
| | | const route = useRoute(); |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | const uniqueId = ref(""); |
| | | const dataNameList = ref<Array<string>>([]); |
| | | |
| | | const queryFormRef = ref(ElForm); |
| | | const importRef = ref(importTable); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const importRef = ref<InstanceType<typeof ImportTable>>(); |
| | | |
| | | const queryParams = ref<TableQuery>({ |
| | | pageNum: 1, |
| | |
| | | uniqueId.value = time as string; |
| | | queryParams.value.pageNum = Number(route.query.pageNum); |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | getList(); |
| | | } |
| | | }) |
| | |
| | | } |
| | | /** æå¼å¯¼å
¥è¡¨å¼¹çª */ |
| | | const openImportTable = () => { |
| | | importRef.value.show(queryParams.value.dataName); |
| | | importRef.value?.show(queryParams.value.dataName); |
| | | } |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | dateRange.value = ['', '']; |
| | | queryFormRef.value.resetFields(); |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** é¢è§æé® */ |