Merge branch 'dev-to-dev' of https://gitee.com/puhui999/yudao-ui-admin-vue3 into dev
Conflicts: src/views/bpm/oa/leave/create.vue src/views/bpm/oa/leave/detail.vuepull/126/MERGE
						commit
						f59e4a4622
					
				|  | @ -6,6 +6,6 @@ dist-ssr | |||
| /dist* | ||||
| *-lock.* | ||||
| pnpm-debug | ||||
| 
 | ||||
| auto-*.d.ts | ||||
| .idea | ||||
| .history | ||||
|  |  | |||
|  | @ -19,10 +19,12 @@ import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' | |||
| 
 | ||||
| export function createVitePlugins() { | ||||
|   const root = process.cwd() | ||||
| 
 | ||||
|   // 路径查找
 | ||||
|   function pathResolve(dir: string) { | ||||
|     return resolve(root, '.', dir) | ||||
|   } | ||||
| 
 | ||||
|   return [ | ||||
|     Vue(), | ||||
|     VueJsx(), | ||||
|  | @ -45,8 +47,6 @@ export function createVitePlugins() { | |||
|         { | ||||
|           '@/hooks/web/useI18n': ['useI18n'], | ||||
|           '@/hooks/web/useMessage': ['useMessage'], | ||||
|           '@/hooks/web/useXTable': ['useXTable'], | ||||
|           '@/hooks/web/useVxeCrudSchemas': ['useVxeCrudSchemas'], | ||||
|           '@/hooks/web/useTable': ['useTable'], | ||||
|           '@/hooks/web/useCrudSchemas': ['useCrudSchemas'], | ||||
|           '@/utils/formRules': ['required'], | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="APP" setup> | ||||
| import { isDark } from '@/utils/is' | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  | @ -32,6 +32,7 @@ $prefix-cls: #{$namespace}-app; | |||
|   width: 100%; | ||||
|   height: 100%; | ||||
| } | ||||
| 
 | ||||
| html, | ||||
| body { | ||||
|   padding: 0 !important; | ||||
|  | @ -43,6 +44,7 @@ body { | |||
|     @extend .size; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .#{$prefix-cls}-grey-mode { | ||||
|   filter: grayscale(100%); | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="BackTop" setup> | ||||
| import { ElBacktop } from 'element-plus' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ConfigGlobal" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { useLocaleStore } from '@/store/modules/locale' | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
|  | @ -51,9 +51,9 @@ const currentLocale = computed(() => localeStore.currentLocale) | |||
| 
 | ||||
| <template> | ||||
|   <ElConfigProvider | ||||
|     :namespace="variables.elNamespace" | ||||
|     :locale="currentLocale.elLocale" | ||||
|     :message="{ max: 1 }" | ||||
|     :namespace="variables.elNamespace" | ||||
|     :size="size" | ||||
|   > | ||||
|     <slot></slot> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ContentDetailWrap" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| 
 | ||||
|  | @ -21,7 +21,7 @@ onMounted(() => { | |||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <div :class="[`${prefixCls}-container`]" ref="contentDetailWrap"> | ||||
|   <div ref="contentDetailWrap" :class="[`${prefixCls}-container`]"> | ||||
|     <Sticky :offset="offset"> | ||||
|       <div | ||||
|         :class="[ | ||||
|  | @ -31,7 +31,7 @@ onMounted(() => { | |||
|       > | ||||
|         <div :class="[`${prefixCls}-header__back`, 'flex pl-10px pr-10px ']"> | ||||
|           <ElButton @click="emit('back')"> | ||||
|             <Icon icon="ep:arrow-left" class="mr-5px" /> | ||||
|             <Icon class="mr-5px" icon="ep:arrow-left" /> | ||||
|             {{ t('common.back') }} | ||||
|           </ElButton> | ||||
|         </div> | ||||
|  | @ -47,7 +47,9 @@ onMounted(() => { | |||
|     </Sticky> | ||||
|     <div style="padding: var(--app-content-padding)"> | ||||
|       <ElCard :class="[`${prefixCls}-body`, 'mb-20px']" shadow="never"> | ||||
|         <div> <slot></slot> </div> | ||||
|         <div> | ||||
|           <slot></slot> | ||||
|         </div> | ||||
|       </ElCard> | ||||
|     </div> | ||||
|   </div> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ContentWrap" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| 
 | ||||
|  | @ -21,7 +21,7 @@ defineProps({ | |||
|           <template #content> | ||||
|             <div class="max-w-200px">{{ message }}</div> | ||||
|           </template> | ||||
|           <Icon class="ml-5px" icon="ep:question-filled" :size="14" /> | ||||
|           <Icon :size="14" class="ml-5px" icon="ep:question-filled" /> | ||||
|         </ElTooltip> | ||||
|       </div> | ||||
|     </template> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="CountTo" setup> | ||||
| import { PropType } from 'vue' | ||||
| import { isNumber } from '@/utils/is' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
|  |  | |||
|  | @ -1,10 +1,12 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Crontab" setup> | ||||
| import { ElMessage } from 'element-plus' | ||||
| import { PropType } from 'vue' | ||||
| 
 | ||||
| interface shortcutsType { | ||||
|   text: string | ||||
|   value: string | ||||
| } | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|   modelValue: { | ||||
|     type: String, | ||||
|  | @ -501,7 +503,7 @@ const submit = () => { | |||
| } | ||||
| </script> | ||||
| <template> | ||||
|   <el-input v-model="defaultValue" v-bind="$attrs" class="input-with-select"> | ||||
|   <el-input v-model="defaultValue" class="input-with-select" v-bind="$attrs"> | ||||
|     <template #append> | ||||
|       <el-select v-model="select" placeholder="生成器" style="width: 115px"> | ||||
|         <el-option label="每分钟" value="0 * * * * ?" /> | ||||
|  | @ -522,11 +524,11 @@ const submit = () => { | |||
|   </el-input> | ||||
| 
 | ||||
|   <el-dialog | ||||
|     title="cron规则生成器" | ||||
|     v-model="dialogVisible" | ||||
|     :width="580" | ||||
|     destroy-on-close | ||||
|     append-to-body | ||||
|     destroy-on-close | ||||
|     title="cron规则生成器" | ||||
|   > | ||||
|     <div class="sc-cron"> | ||||
|       <el-tabs> | ||||
|  | @ -546,38 +548,38 @@ const submit = () => { | |||
|                 <el-radio-button label="3">指定</el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="范围" v-if="cronValue.second.type == '1'"> | ||||
|             <el-form-item v-if="cronValue.second.type == '1'" label="范围"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.second.range.start" | ||||
|                 :min="0" | ||||
|                 :max="59" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               <span style="padding: 0 15px">-</span> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.second.range.end" | ||||
|                 :min="0" | ||||
|                 :max="59" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="间隔" v-if="cronValue.second.type == '2'"> | ||||
|             <el-form-item v-if="cronValue.second.type == '2'" label="间隔"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.second.loop.start" | ||||
|                 :min="0" | ||||
|                 :max="59" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               秒开始,每 | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.second.loop.end" | ||||
|                 :min="0" | ||||
|                 :max="59" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               秒执行一次 | ||||
|             </el-form-item> | ||||
|             <el-form-item label="指定" v-if="cronValue.second.type == '3'"> | ||||
|             <el-form-item v-if="cronValue.second.type == '3'" label="指定"> | ||||
|               <el-select v-model="cronValue.second.appoint" multiple style="width: 100%"> | ||||
|                 <el-option | ||||
|                   v-for="(item, index) in data.second" | ||||
|  | @ -605,38 +607,38 @@ const submit = () => { | |||
|                 <el-radio-button label="3">指定</el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="范围" v-if="cronValue.minute.type == '1'"> | ||||
|             <el-form-item v-if="cronValue.minute.type == '1'" label="范围"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.minute.range.start" | ||||
|                 :min="0" | ||||
|                 :max="59" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               <span style="padding: 0 15px">-</span> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.minute.range.end" | ||||
|                 :min="0" | ||||
|                 :max="59" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="间隔" v-if="cronValue.minute.type == '2'"> | ||||
|             <el-form-item v-if="cronValue.minute.type == '2'" label="间隔"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.minute.loop.start" | ||||
|                 :min="0" | ||||
|                 :max="59" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               分钟开始,每 | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.minute.loop.end" | ||||
|                 :min="0" | ||||
|                 :max="59" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               分钟执行一次 | ||||
|             </el-form-item> | ||||
|             <el-form-item label="指定" v-if="cronValue.minute.type == '3'"> | ||||
|             <el-form-item v-if="cronValue.minute.type == '3'" label="指定"> | ||||
|               <el-select v-model="cronValue.minute.appoint" multiple style="width: 100%"> | ||||
|                 <el-option | ||||
|                   v-for="(item, index) in data.minute" | ||||
|  | @ -664,38 +666,38 @@ const submit = () => { | |||
|                 <el-radio-button label="3">指定</el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="范围" v-if="cronValue.hour.type == '1'"> | ||||
|             <el-form-item v-if="cronValue.hour.type == '1'" label="范围"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.hour.range.start" | ||||
|                 :min="0" | ||||
|                 :max="23" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               <span style="padding: 0 15px">-</span> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.hour.range.end" | ||||
|                 :min="0" | ||||
|                 :max="23" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="间隔" v-if="cronValue.hour.type == '2'"> | ||||
|             <el-form-item v-if="cronValue.hour.type == '2'" label="间隔"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.hour.loop.start" | ||||
|                 :min="0" | ||||
|                 :max="23" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               小时开始,每 | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.hour.loop.end" | ||||
|                 :min="0" | ||||
|                 :max="23" | ||||
|                 :min="0" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               小时执行一次 | ||||
|             </el-form-item> | ||||
|             <el-form-item label="指定" v-if="cronValue.hour.type == '3'"> | ||||
|             <el-form-item v-if="cronValue.hour.type == '3'" label="指定"> | ||||
|               <el-select v-model="cronValue.hour.appoint" multiple style="width: 100%"> | ||||
|                 <el-option | ||||
|                   v-for="(item, index) in data.hour" | ||||
|  | @ -725,38 +727,38 @@ const submit = () => { | |||
|                 <el-radio-button label="5">不指定</el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="范围" v-if="cronValue.day.type == '1'"> | ||||
|             <el-form-item v-if="cronValue.day.type == '1'" label="范围"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.day.range.start" | ||||
|                 :min="1" | ||||
|                 :max="31" | ||||
|                 :min="1" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               <span style="padding: 0 15px">-</span> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.day.range.end" | ||||
|                 :min="1" | ||||
|                 :max="31" | ||||
|                 :min="1" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="间隔" v-if="cronValue.day.type == '2'"> | ||||
|             <el-form-item v-if="cronValue.day.type == '2'" label="间隔"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.day.loop.start" | ||||
|                 :min="1" | ||||
|                 :max="31" | ||||
|                 :min="1" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               号开始,每 | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.day.loop.end" | ||||
|                 :min="1" | ||||
|                 :max="31" | ||||
|                 :min="1" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               天执行一次 | ||||
|             </el-form-item> | ||||
|             <el-form-item label="指定" v-if="cronValue.day.type == '3'"> | ||||
|             <el-form-item v-if="cronValue.day.type == '3'" label="指定"> | ||||
|               <el-select v-model="cronValue.day.appoint" multiple style="width: 100%"> | ||||
|                 <el-option | ||||
|                   v-for="(item, index) in data.day" | ||||
|  | @ -784,38 +786,38 @@ const submit = () => { | |||
|                 <el-radio-button label="3">指定</el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="范围" v-if="cronValue.month.type == '1'"> | ||||
|             <el-form-item v-if="cronValue.month.type == '1'" label="范围"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.month.range.start" | ||||
|                 :min="1" | ||||
|                 :max="12" | ||||
|                 :min="1" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               <span style="padding: 0 15px">-</span> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.month.range.end" | ||||
|                 :min="1" | ||||
|                 :max="12" | ||||
|                 :min="1" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="间隔" v-if="cronValue.month.type == '2'"> | ||||
|             <el-form-item v-if="cronValue.month.type == '2'" label="间隔"> | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.month.loop.start" | ||||
|                 :min="1" | ||||
|                 :max="12" | ||||
|                 :min="1" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               月开始,每 | ||||
|               <el-input-number | ||||
|                 v-model="cronValue.month.loop.end" | ||||
|                 :min="1" | ||||
|                 :max="12" | ||||
|                 :min="1" | ||||
|                 controls-position="right" | ||||
|               /> | ||||
|               月执行一次 | ||||
|             </el-form-item> | ||||
|             <el-form-item label="指定" v-if="cronValue.month.type == '3'"> | ||||
|             <el-form-item v-if="cronValue.month.type == '3'" label="指定"> | ||||
|               <el-select v-model="cronValue.month.appoint" multiple style="width: 100%"> | ||||
|                 <el-option | ||||
|                   v-for="(item, index) in data.month" | ||||
|  | @ -846,7 +848,7 @@ const submit = () => { | |||
|                   <el-radio-button label="5">不指定</el-radio-button> | ||||
|                 </el-radio-group> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="范围" v-if="cronValue.week.type == '1'"> | ||||
|               <el-form-item v-if="cronValue.week.type == '1'" label="范围"> | ||||
|                 <el-select v-model="cronValue.week.range.start"> | ||||
|                   <el-option | ||||
|                     v-for="(item, index) in data.week" | ||||
|  | @ -865,12 +867,12 @@ const submit = () => { | |||
|                   /> | ||||
|                 </el-select> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="间隔" v-if="cronValue.week.type == '2'"> | ||||
|               <el-form-item v-if="cronValue.week.type == '2'" label="间隔"> | ||||
|                 第 | ||||
|                 <el-input-number | ||||
|                   v-model="cronValue.week.loop.start" | ||||
|                   :min="1" | ||||
|                   :max="4" | ||||
|                   :min="1" | ||||
|                   controls-position="right" | ||||
|                 /> | ||||
|                 周的星期 | ||||
|  | @ -884,7 +886,7 @@ const submit = () => { | |||
|                 </el-select> | ||||
|                 执行一次 | ||||
|               </el-form-item> | ||||
|               <el-form-item label="指定" v-if="cronValue.week.type == '3'"> | ||||
|               <el-form-item v-if="cronValue.week.type == '3'" label="指定"> | ||||
|                 <el-select v-model="cronValue.week.appoint" multiple style="width: 100%"> | ||||
|                   <el-option | ||||
|                     v-for="(item, index) in data.week" | ||||
|  | @ -894,7 +896,7 @@ const submit = () => { | |||
|                   /> | ||||
|                 </el-select> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="最后一周" v-if="cronValue.week.type == '4'"> | ||||
|               <el-form-item v-if="cronValue.week.type == '4'" label="最后一周"> | ||||
|                 <el-select v-model="cronValue.week.last"> | ||||
|                   <el-option | ||||
|                     v-for="(item, index) in data.week" | ||||
|  | @ -924,12 +926,12 @@ const submit = () => { | |||
|                 <el-radio-button label="3">指定</el-radio-button> | ||||
|               </el-radio-group> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="范围" v-if="cronValue.year.type == '1'"> | ||||
|             <el-form-item v-if="cronValue.year.type == '1'" label="范围"> | ||||
|               <el-input-number v-model="cronValue.year.range.start" controls-position="right" /> | ||||
|               <span style="padding: 0 15px">-</span> | ||||
|               <el-input-number v-model="cronValue.year.range.end" controls-position="right" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="间隔" v-if="cronValue.year.type == '2'"> | ||||
|             <el-form-item v-if="cronValue.year.type == '2'" label="间隔"> | ||||
|               <el-input-number v-model="cronValue.year.loop.start" controls-position="right" /> | ||||
|               年开始,每 | ||||
|               <el-input-number | ||||
|  | @ -939,7 +941,7 @@ const submit = () => { | |||
|               /> | ||||
|               年执行一次 | ||||
|             </el-form-item> | ||||
|             <el-form-item label="指定" v-if="cronValue.year.type == '3'"> | ||||
|             <el-form-item v-if="cronValue.year.type == '3'" label="指定"> | ||||
|               <el-select v-model="cronValue.year.appoint" multiple style="width: 100%"> | ||||
|                 <el-option | ||||
|                   v-for="(item, index) in data.year" | ||||
|  | @ -968,16 +970,19 @@ const submit = () => { | |||
|   padding: 0 7px; | ||||
|   vertical-align: bottom; | ||||
| } | ||||
| 
 | ||||
| .sc-cron-num { | ||||
|   text-align: center; | ||||
|   margin-bottom: 15px; | ||||
|   width: 100%; | ||||
| } | ||||
| 
 | ||||
| .sc-cron-num h2 { | ||||
|   font-size: 12px; | ||||
|   margin-bottom: 15px; | ||||
|   font-weight: normal; | ||||
| } | ||||
| 
 | ||||
| .sc-cron-num h4 { | ||||
|   display: block; | ||||
|   height: 32px; | ||||
|  | @ -988,13 +993,16 @@ const submit = () => { | |||
|   background: var(--el-color-primary-light-9); | ||||
|   border-radius: 4px; | ||||
| } | ||||
| 
 | ||||
| .sc-cron:deep(.el-tabs__item.is-active) .sc-cron-num h4 { | ||||
|   background: var(--el-color-primary); | ||||
|   color: #fff; | ||||
| } | ||||
| 
 | ||||
| [data-theme='dark'] .sc-cron-num h4 { | ||||
|   background: var(--el-color-white); | ||||
| } | ||||
| 
 | ||||
| .input-with-select .el-input-group__prepend { | ||||
|   background-color: var(--el-fill-color-blank); | ||||
| } | ||||
|  |  | |||
|  | @ -2,26 +2,26 @@ | |||
|   <div> | ||||
|     <Dialog | ||||
|       v-model="dialogVisible" | ||||
|       :title="t('cropper.modalTitle')" | ||||
|       width="800px" | ||||
|       maxHeight="380px" | ||||
|       :canFullscreen="false" | ||||
|       :title="t('cropper.modalTitle')" | ||||
|       maxHeight="380px" | ||||
|       width="800px" | ||||
|     > | ||||
|       <div :class="prefixCls"> | ||||
|         <div :class="`${prefixCls}-left`"> | ||||
|           <div :class="`${prefixCls}-cropper`"> | ||||
|             <CropperImage | ||||
|               v-if="src" | ||||
|               :circled="circled" | ||||
|               :src="src" | ||||
|               height="300px" | ||||
|               :circled="circled" | ||||
|               @cropend="handleCropend" | ||||
|               @ready="handleReady" | ||||
|             /> | ||||
|           </div> | ||||
| 
 | ||||
|           <div :class="`${prefixCls}-toolbar`"> | ||||
|             <el-upload :fileList="[]" accept="image/*" :beforeUpload="handleBeforeUpload"> | ||||
|             <el-upload :beforeUpload="handleBeforeUpload" :fileList="[]" accept="image/*"> | ||||
|               <el-tooltip :content="t('cropper.selectImage')" placement="bottom"> | ||||
|                 <XButton preIcon="ant-design:upload-outlined" type="primary" /> | ||||
|               </el-tooltip> | ||||
|  | @ -29,64 +29,64 @@ | |||
|             <el-space> | ||||
|               <el-tooltip :content="t('cropper.btn_reset')" placement="bottom"> | ||||
|                 <XButton | ||||
|                   type="primary" | ||||
|                   :disabled="!src" | ||||
|                   preIcon="ant-design:reload-outlined" | ||||
|                   size="small" | ||||
|                   :disabled="!src" | ||||
|                   type="primary" | ||||
|                   @click="handlerToolbar('reset')" | ||||
|                 /> | ||||
|               </el-tooltip> | ||||
|               <el-tooltip :content="t('cropper.btn_rotate_left')" placement="bottom"> | ||||
|                 <XButton | ||||
|                   type="primary" | ||||
|                   :disabled="!src" | ||||
|                   preIcon="ant-design:rotate-left-outlined" | ||||
|                   size="small" | ||||
|                   :disabled="!src" | ||||
|                   type="primary" | ||||
|                   @click="handlerToolbar('rotate', -45)" | ||||
|                 /> | ||||
|               </el-tooltip> | ||||
|               <el-tooltip :content="t('cropper.btn_rotate_right')" placement="bottom"> | ||||
|                 <XButton | ||||
|                   type="primary" | ||||
|                   :disabled="!src" | ||||
|                   preIcon="ant-design:rotate-right-outlined" | ||||
|                   size="small" | ||||
|                   :disabled="!src" | ||||
|                   type="primary" | ||||
|                   @click="handlerToolbar('rotate', 45)" | ||||
|                 /> | ||||
|               </el-tooltip> | ||||
|               <el-tooltip :content="t('cropper.btn_scale_x')" placement="bottom"> | ||||
|                 <XButton | ||||
|                   type="primary" | ||||
|                   :disabled="!src" | ||||
|                   preIcon="vaadin:arrows-long-h" | ||||
|                   size="small" | ||||
|                   :disabled="!src" | ||||
|                   type="primary" | ||||
|                   @click="handlerToolbar('scaleX')" | ||||
|                 /> | ||||
|               </el-tooltip> | ||||
|               <el-tooltip :content="t('cropper.btn_scale_y')" placement="bottom"> | ||||
|                 <XButton | ||||
|                   type="primary" | ||||
|                   :disabled="!src" | ||||
|                   preIcon="vaadin:arrows-long-v" | ||||
|                   size="small" | ||||
|                   :disabled="!src" | ||||
|                   type="primary" | ||||
|                   @click="handlerToolbar('scaleY')" | ||||
|                 /> | ||||
|               </el-tooltip> | ||||
|               <el-tooltip :content="t('cropper.btn_zoom_in')" placement="bottom"> | ||||
|                 <XButton | ||||
|                   type="primary" | ||||
|                   :disabled="!src" | ||||
|                   preIcon="ant-design:zoom-in-outlined" | ||||
|                   size="small" | ||||
|                   :disabled="!src" | ||||
|                   type="primary" | ||||
|                   @click="handlerToolbar('zoom', 0.1)" | ||||
|                 /> | ||||
|               </el-tooltip> | ||||
|               <el-tooltip :content="t('cropper.btn_zoom_out')" placement="bottom"> | ||||
|                 <XButton | ||||
|                   type="primary" | ||||
|                   :disabled="!src" | ||||
|                   preIcon="ant-design:zoom-out-outlined" | ||||
|                   size="small" | ||||
|                   :disabled="!src" | ||||
|                   type="primary" | ||||
|                   @click="handlerToolbar('zoom', -0.1)" | ||||
|                 /> | ||||
|               </el-tooltip> | ||||
|  | @ -95,14 +95,14 @@ | |||
|         </div> | ||||
|         <div :class="`${prefixCls}-right`"> | ||||
|           <div :class="`${prefixCls}-preview`"> | ||||
|             <img :src="previewSource" v-if="previewSource" :alt="t('cropper.preview')" /> | ||||
|             <img v-if="previewSource" :alt="t('cropper.preview')" :src="previewSource" /> | ||||
|           </div> | ||||
|           <template v-if="previewSource"> | ||||
|             <div :class="`${prefixCls}-group`"> | ||||
|               <el-avatar :src="previewSource" size="large" /> | ||||
|               <el-avatar :src="previewSource" :size="48" /> | ||||
|               <el-avatar :src="previewSource" :size="64" /> | ||||
|               <el-avatar :src="previewSource" :size="80" /> | ||||
|               <el-avatar :size="48" :src="previewSource" /> | ||||
|               <el-avatar :size="64" :src="previewSource" /> | ||||
|               <el-avatar :size="80" :src="previewSource" /> | ||||
|             </div> | ||||
|           </template> | ||||
|         </div> | ||||
|  | @ -113,7 +113,7 @@ | |||
|     </Dialog> | ||||
|   </div> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="CopperModal" setup> | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| import { dataURLtoBlob } from '@/utils/filt' | ||||
| import { useI18n } from 'vue-i18n' | ||||
|  | @ -173,12 +173,15 @@ async function handleOk() { | |||
|   const blob = dataURLtoBlob(previewSource.value) | ||||
|   emit('uploadSuccess', { source: previewSource.value, data: blob, filename: filename }) | ||||
| } | ||||
| 
 | ||||
| function openModal() { | ||||
|   dialogVisible.value = true | ||||
| } | ||||
| 
 | ||||
| function closeModal() { | ||||
|   dialogVisible.value = false | ||||
| } | ||||
| 
 | ||||
| defineExpose({ openModal, closeModal }) | ||||
| </script> | ||||
| <style lang="scss"> | ||||
|  |  | |||
|  | @ -3,14 +3,14 @@ | |||
|     <img | ||||
|       v-show="isReady" | ||||
|       ref="imgElRef" | ||||
|       :src="src" | ||||
|       :alt="alt" | ||||
|       :crossorigin="crossorigin" | ||||
|       :src="src" | ||||
|       :style="getImageStyle" | ||||
|     /> | ||||
|   </div> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Cropper" setup> | ||||
| import { CSSProperties, PropType } from 'vue' | ||||
| import Cropper from 'cropperjs' | ||||
| import 'cropperjs/dist/cropper.css' | ||||
|  |  | |||
|  | @ -1,17 +1,17 @@ | |||
| <template> | ||||
|   <div class="user-info-head" @click="open()"> | ||||
|     <img :src="sourceValue" v-if="sourceValue" class="img-circle img-lg" alt="avatar" /> | ||||
|     <el-button :class="`${prefixCls}-upload-btn`" @click="open()" v-if="showBtn"> | ||||
|     <img v-if="sourceValue" :src="sourceValue" alt="avatar" class="img-circle img-lg" /> | ||||
|     <el-button v-if="showBtn" :class="`${prefixCls}-upload-btn`" @click="open()"> | ||||
|       {{ btnText ? btnText : t('cropper.selectImage') }} | ||||
|     </el-button> | ||||
|     <CopperModal | ||||
|       ref="cropperModelRef" | ||||
|       @upload-success="handleUploadSuccess" | ||||
|       :srcValue="sourceValue" | ||||
|       @upload-success="handleUploadSuccess" | ||||
|     /> | ||||
|   </div> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="CropperAvatar" setup> | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| 
 | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
|  | @ -54,9 +54,11 @@ function handleUploadSuccess({ source, data, filename }) { | |||
| function open() { | ||||
|   cropperModelRef.value.openModal() | ||||
| } | ||||
| 
 | ||||
| function close() { | ||||
|   cropperModelRef.value.closeModal() | ||||
| } | ||||
| 
 | ||||
| defineExpose({ | ||||
|   open, | ||||
|   close | ||||
|  | @ -104,17 +106,21 @@ $prefix-cls: #{$namespace}--cropper-avatar; | |||
|     margin: 10px auto; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .user-info-head { | ||||
|   position: relative; | ||||
|   display: inline-block; | ||||
| } | ||||
| 
 | ||||
| .img-circle { | ||||
|   border-radius: 50%; | ||||
| } | ||||
| 
 | ||||
| .img-lg { | ||||
|   width: 120px; | ||||
|   height: 120px; | ||||
| } | ||||
| 
 | ||||
| .user-info-head:hover:after { | ||||
|   content: '+'; | ||||
|   position: absolute; | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Descriptions" setup> | ||||
| import { PropType } from 'vue' | ||||
| import dayjs from 'dayjs' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  | @ -84,7 +84,7 @@ const toggleClick = () => { | |||
|         <div class="flex items-center"> | ||||
|           {{ title }} | ||||
|           <ElTooltip v-if="message" :content="message" placement="right"> | ||||
|             <Icon icon="ep:warning" class="ml-5px" /> | ||||
|             <Icon class="ml-5px" icon="ep:warning" /> | ||||
|           </ElTooltip> | ||||
|         </div> | ||||
|       </div> | ||||
|  | @ -95,8 +95,8 @@ const toggleClick = () => { | |||
|       <div v-show="show" :class="[`${prefixCls}-content`, 'p-10px']"> | ||||
|         <ElDescriptions | ||||
|           :column="props.columns" | ||||
|           border | ||||
|           :direction="mobile ? 'vertical' : 'horizontal'" | ||||
|           border | ||||
|           v-bind="getBindValue" | ||||
|         > | ||||
|           <template v-if="slots['extra']" #extra> | ||||
|  | @ -114,8 +114,8 @@ const toggleClick = () => { | |||
|                 :row="{ | ||||
|                   label: item.label | ||||
|                 }" | ||||
|                 >{{ item.label }}</slot | ||||
|               > | ||||
|                 >{{ item.label }} | ||||
|               </slot> | ||||
|             </template> | ||||
| 
 | ||||
|             <template #default> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Dialog" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { isNumber } from '@/utils/is' | ||||
| 
 | ||||
|  | @ -59,13 +59,13 @@ const dialogStyle = computed(() => { | |||
| 
 | ||||
| <template> | ||||
|   <ElDialog | ||||
|     v-bind="getBindValue" | ||||
|     :fullscreen="isFullscreen" | ||||
|     destroy-on-close | ||||
|     lock-scroll | ||||
|     draggable | ||||
|     :width="width" | ||||
|     :close-on-click-modal="true" | ||||
|     :fullscreen="isFullscreen" | ||||
|     :width="width" | ||||
|     destroy-on-close | ||||
|     draggable | ||||
|     lock-scroll | ||||
|     v-bind="getBindValue" | ||||
|   > | ||||
|     <template #header> | ||||
|       <div class="flex justify-between"> | ||||
|  | @ -74,8 +74,8 @@ const dialogStyle = computed(() => { | |||
|         </slot> | ||||
|         <Icon | ||||
|           v-if="fullscreen" | ||||
|           class="mr-22px cursor-pointer is-hover mt-2px z-10" | ||||
|           :icon="isFullscreen ? 'zmdi:fullscreen-exit' : 'zmdi:fullscreen'" | ||||
|           class="mr-22px cursor-pointer is-hover mt-2px z-10" | ||||
|           color="var(--el-color-info)" | ||||
|           @click="toggleFull" | ||||
|         /> | ||||
|  | @ -83,7 +83,7 @@ const dialogStyle = computed(() => { | |||
|     </template> | ||||
| 
 | ||||
|     <!-- 情况一:如果 scroll 为 true,说明开启滚动条 --> | ||||
|     <ElScrollbar :style="dialogStyle" v-if="scroll"> | ||||
|     <ElScrollbar v-if="scroll" :style="dialogStyle"> | ||||
|       <slot></slot> | ||||
|     </ElScrollbar> | ||||
|     <!-- 情况二:如果 scroll 为 false,说明关闭滚动条滚动条 --> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="EChart" setup> | ||||
| import type { EChartsOption } from 'echarts' | ||||
| import echarts from '@/plugins/echarts' | ||||
| import { debounce } from 'lodash-es' | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Editor" setup> | ||||
| import { PropType } from 'vue' | ||||
| import { Editor, Toolbar } from '@wangeditor/editor-for-vue' | ||||
| import { IDomEditor, IEditorConfig, i18nChangeLanguage } from '@wangeditor/editor' | ||||
| import { i18nChangeLanguage, IDomEditor, IEditorConfig } from '@wangeditor/editor' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { isNumber } from '@/utils/is' | ||||
| import { ElMessage } from 'element-plus' | ||||
|  | @ -189,8 +189,8 @@ defineExpose({ | |||
|     <!-- 编辑器 --> | ||||
|     <Editor | ||||
|       v-model="valueHtml" | ||||
|       :editorId="editorId" | ||||
|       :defaultConfig="editorConfig" | ||||
|       :editorId="editorId" | ||||
|       :style="editorStyle" | ||||
|       @on-change="handleChange" | ||||
|       @on-created="handleCreated" | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Error" setup> | ||||
| import pageError from '@/assets/svgs/404.svg' | ||||
| import networkError from '@/assets/svgs/500.svg' | ||||
| import noPermission from '@/assets/svgs/403.svg' | ||||
|  | @ -46,7 +46,7 @@ const btnClick = () => { | |||
| <template> | ||||
|   <div class="flex justify-center"> | ||||
|     <div class="text-center"> | ||||
|       <img width="350" :src="errorMap[type].url" alt="" /> | ||||
|       <img :src="errorMap[type].url" alt="" width="350" /> | ||||
|       <div class="text-14px text-[var(--el-color-info)]">{{ errorMap[type].message }}</div> | ||||
|       <div class="mt-20px"> | ||||
|         <ElButton type="primary" @click="btnClick">{{ errorMap[type].buttonText }}</ElButton> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="IFrame" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|  | @ -20,11 +20,11 @@ onMounted(() => { | |||
| <template> | ||||
|   <div v-loading="loading" :style="'height:' + height"> | ||||
|     <iframe | ||||
|       ref="frameRef" | ||||
|       :src="props.src" | ||||
|       style="width: 100%; height: 100%" | ||||
|       frameborder="no" | ||||
|       scrolling="auto" | ||||
|       ref="frameRef" | ||||
|       style="width: 100%; height: 100%" | ||||
|     ></iframe> | ||||
|   </div> | ||||
| </template> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Icon" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import Iconify from '@purge-icons/generated' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  | @ -72,7 +72,7 @@ watch( | |||
| 
 | ||||
| <template> | ||||
|   <ElIcon :class="prefixCls" :color="color" :size="size"> | ||||
|     <svg v-if="isLocal" aria-hidden="true" :class="getSvgClass"> | ||||
|     <svg v-if="isLocal" :class="getSvgClass" aria-hidden="true"> | ||||
|       <use :xlink:href="symbolId" /> | ||||
|     </svg> | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="IconSelect" setup> | ||||
| import { CSSProperties } from 'vue' | ||||
| import { cloneDeep } from 'lodash-es' | ||||
| import { IconJson } from '@/components/Icon/src/data' | ||||
|  | @ -116,13 +116,13 @@ watch( | |||
|     <ElInput v-model="inputValue" @click="visible = !visible"> | ||||
|       <template #append> | ||||
|         <ElPopover | ||||
|           :width="350" | ||||
|           trigger="click" | ||||
|           popper-class="pure-popper" | ||||
|           :popper-options="{ | ||||
|             placement: 'auto' | ||||
|           }" | ||||
|           :visible="visible" | ||||
|           :width="350" | ||||
|           popper-class="pure-popper" | ||||
|           trigger="click" | ||||
|         > | ||||
|           <template #reference> | ||||
|             <div | ||||
|  | @ -133,7 +133,7 @@ watch( | |||
|             </div> | ||||
|           </template> | ||||
| 
 | ||||
|           <ElInput class="p-2" v-model="filterValue" placeholder="搜索图标" clearable /> | ||||
|           <ElInput v-model="filterValue" class="p-2" clearable placeholder="搜索图标" /> | ||||
|           <ElDivider border-style="dashed" /> | ||||
| 
 | ||||
|           <ElTabs v-model="currentActiveType" @tab-click="handleClick"> | ||||
|  | @ -143,15 +143,15 @@ watch( | |||
|               :label="pane.label" | ||||
|               :name="pane.name" | ||||
|             > | ||||
|               <ElDivider class="tab-divider" border-style="dashed" /> | ||||
|               <ElDivider border-style="dashed" class="tab-divider" /> | ||||
|               <ElScrollbar height="220px"> | ||||
|                 <ul class="flex flex-wrap px-2 ml-2"> | ||||
|                   <li | ||||
|                     v-for="(item, key) in pageList" | ||||
|                     :key="key" | ||||
|                     :style="iconItemStyle(item)" | ||||
|                     :title="item" | ||||
|                     class="icon-item p-2 w-1/10 cursor-pointer mr-2 mt-1 flex justify-center items-center border border-solid" | ||||
|                     :style="iconItemStyle(item)" | ||||
|                     @click="onChangeIcon(item)" | ||||
|                   > | ||||
|                     <Icon :icon="currentActiveType + item" /> | ||||
|  | @ -163,13 +163,13 @@ watch( | |||
|           <ElDivider border-style="dashed" /> | ||||
| 
 | ||||
|           <ElPagination | ||||
|             small | ||||
|             :total="iconCount" | ||||
|             :page-size="pageSize" | ||||
|             :current-page="currentPage" | ||||
|             :page-size="pageSize" | ||||
|             :total="iconCount" | ||||
|             background | ||||
|             layout="prev, pager, next" | ||||
|             class="flex items-center justify-center h-10" | ||||
|             layout="prev, pager, next" | ||||
|             small | ||||
|             @current-change="onCurrentChange" | ||||
|           /> | ||||
|         </ElPopover> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ImageViewer" setup> | ||||
| import { PropType } from 'vue' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfoTip" setup> | ||||
| import { PropType } from 'vue' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
|  | @ -34,14 +34,14 @@ const keyClick = (key: string) => { | |||
|     ]" | ||||
|   > | ||||
|     <div v-if="title" :class="[`${prefixCls}__header`, 'flex items-center']"> | ||||
|       <Icon icon="ep:warning-filled" :size="22" color="var(--el-color-primary)" /> | ||||
|       <Icon :size="22" color="var(--el-color-primary)" icon="ep:warning-filled" /> | ||||
|       <span :class="[`${prefixCls}__title`, 'pl-5px text-16px font-bold']">{{ title }}</span> | ||||
|     </div> | ||||
|     <div :class="`${prefixCls}__content`"> | ||||
|       <p v-for="(item, $index) in schema" :key="$index" class="text-14px mt-15px"> | ||||
|         <Highlight | ||||
|           :keys="typeof item === 'string' ? [] : item.keys" | ||||
|           :color="highlightColor" | ||||
|           :keys="typeof item === 'string' ? [] : item.keys" | ||||
|           @click="keyClick" | ||||
|         > | ||||
|           {{ showIndex ? `${$index + 1}、` : '' }}{{ typeof item === 'string' ? item : item.label }} | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InputPassword" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { useConfigGlobal } from '@/hooks/web/useConfigGlobal' | ||||
| import { zxcvbn } from '@zxcvbn-ts/core' | ||||
| import type { ZxcvbnResult } from '@zxcvbn-ts/core' | ||||
| import { zxcvbn } from '@zxcvbn-ts/core' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| 
 | ||||
| const { getPrefixCls } = useDesign() | ||||
|  | @ -57,9 +57,9 @@ const getIconName = computed(() => (unref(textType) === 'password' ? 'ep:hide' : | |||
| 
 | ||||
| <template> | ||||
|   <div :class="[prefixCls, `${prefixCls}--${configGlobal?.size}`]"> | ||||
|     <ElInput v-bind="$attrs" v-model="valueRef" :type="textType"> | ||||
|     <ElInput v-model="valueRef" :type="textType" v-bind="$attrs"> | ||||
|       <template #suffix> | ||||
|         <Icon class="el-input__icon cursor-pointer" :icon="getIconName" @click="changeTextType" /> | ||||
|         <Icon :icon="getIconName" class="el-input__icon cursor-pointer" @click="changeTextType" /> | ||||
|       </template> | ||||
|     </ElInput> | ||||
|     <div | ||||
|  |  | |||
|  | @ -2,19 +2,19 @@ | |||
| <template> | ||||
|   <el-pagination | ||||
|     v-show="total > 0" | ||||
|     class="float-right mt-15px mb-15px" | ||||
|     :background="true" | ||||
|     layout="total, sizes, prev, pager, next, jumper" | ||||
|     :page-sizes="[10, 20, 30, 50, 100]" | ||||
|     v-model:current-page="currentPage" | ||||
|     v-model:page-size="pageSize" | ||||
|     :background="true" | ||||
|     :page-sizes="[10, 20, 30, 50, 100]" | ||||
|     :pager-count="pagerCount" | ||||
|     :total="total" | ||||
|     class="float-right mt-15px mb-15px" | ||||
|     layout="total, sizes, prev, pager, next, jumper" | ||||
|     @size-change="handleSizeChange" | ||||
|     @current-change="handleCurrentChange" | ||||
|   /> | ||||
| </template> | ||||
| <script setup> | ||||
| <script name="Pagination" setup> | ||||
| import { computed } from 'vue' | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| <script setup lang="ts"> | ||||
| import { PropType, nextTick, ref, watch, computed, unref } from 'vue' | ||||
| import QRCode from 'qrcode' | ||||
| import { QRCodeRenderersOptions } from 'qrcode' | ||||
| <script lang="ts" name="Qrcode" setup> | ||||
| import { computed, nextTick, PropType, ref, unref, watch } from 'vue' | ||||
| import QRCode, { QRCodeRenderersOptions } from 'qrcode' | ||||
| import { cloneDeep } from 'lodash-es' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  | @ -230,7 +229,7 @@ const disabledClick = () => { | |||
|       @click="disabledClick" | ||||
|     > | ||||
|       <div class="absolute top-[50%] left-[50%] font-bold"> | ||||
|         <Icon icon="ep:refresh-right" :size="30" color="var(--el-color-primary)" /> | ||||
|         <Icon :size="30" color="var(--el-color-primary)" icon="ep:refresh-right" /> | ||||
|         <div>{{ disabledText }}</div> | ||||
|       </div> | ||||
|     </div> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Search" setup> | ||||
| import { PropType } from 'vue' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| 
 | ||||
|  | @ -100,25 +100,25 @@ const setVisible = () => { | |||
| <template> | ||||
|   <!-- update by 芋艿:class="-mb-15px" 用于降低和 ContentWrap 组件的底部距离,避免空隙过大 --> | ||||
|   <Form | ||||
|     :is-custom="false" | ||||
|     :label-width="labelWidth" | ||||
|     hide-required-asterisk | ||||
|     :inline="inline" | ||||
|     :is-col="isCol" | ||||
|     :is-custom="false" | ||||
|     :label-width="labelWidth" | ||||
|     :schema="newSchema" | ||||
|     @register="register" | ||||
|     class="-mb-15px" | ||||
|     hide-required-asterisk | ||||
|     @register="register" | ||||
|   > | ||||
|     <template #action> | ||||
|       <div v-if="layout === 'inline'"> | ||||
|         <!-- update by 芋艿:去除搜索的 type="primary",颜色变淡一点 --> | ||||
|         <ElButton v-if="showSearch" @click="search"> | ||||
|           <Icon icon="ep:search" class="mr-5px" /> | ||||
|           <Icon class="mr-5px" icon="ep:search" /> | ||||
|           {{ t('common.query') }} | ||||
|         </ElButton> | ||||
|         <!-- update by 芋艿:将 icon="ep:refresh-right" 修改成 icon="ep:refresh",和 ruoyi-vue 搜索保持一致  --> | ||||
|         <ElButton v-if="showReset" @click="reset"> | ||||
|           <Icon icon="ep:refresh" class="mr-5px" /> | ||||
|           <Icon class="mr-5px" icon="ep:refresh" /> | ||||
|           {{ t('common.reset') }} | ||||
|         </ElButton> | ||||
|         <ElButton v-if="expand" text @click="setVisible"> | ||||
|  | @ -129,19 +129,19 @@ const setVisible = () => { | |||
|         <slot name="actionMore"></slot> | ||||
|       </div> | ||||
|     </template> | ||||
|     <template #[name] v-for="name in Object.keys($slots)" :key="name" | ||||
|       ><slot :name="name"></slot | ||||
|     ></template> | ||||
|     <template v-for="name in Object.keys($slots)" :key="name" #[name]> | ||||
|       <slot :name="name"></slot> | ||||
|     </template> | ||||
|   </Form> | ||||
| 
 | ||||
|   <template v-if="layout === 'bottom'"> | ||||
|     <div :style="bottonButtonStyle"> | ||||
|       <ElButton v-if="showSearch" type="primary" @click="search"> | ||||
|         <Icon icon="ep:search" class="mr-5px" /> | ||||
|         <Icon class="mr-5px" icon="ep:search" /> | ||||
|         {{ t('common.query') }} | ||||
|       </ElButton> | ||||
|       <ElButton v-if="showReset" @click="reset"> | ||||
|         <Icon icon="ep:refresh-right" class="mr-5px" /> | ||||
|         <Icon class="mr-5px" icon="ep:refresh-right" /> | ||||
|         {{ t('common.reset') }} | ||||
|       </ElButton> | ||||
|       <ElButton v-if="expand" text @click="setVisible"> | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Sticky" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { isClient, useEventListener, useWindowSize } from '@vueuse/core' | ||||
| import type { CSSProperties } from 'vue' | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|   // 距离顶部或者底部的距离(单位px) | ||||
|   offset: propTypes.number.def(0), | ||||
|  | @ -120,7 +121,7 @@ const reset = () => { | |||
| } | ||||
| </script> | ||||
| <template> | ||||
|   <div :style="{ height: height, zIndex: zIndex }" ref="refSticky"> | ||||
|   <div ref="refSticky" :style="{ height: height, zIndex: zIndex }"> | ||||
|     <div | ||||
|       :class="className" | ||||
|       :style="{ | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Tooltip" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| 
 | ||||
| defineProps({ | ||||
|   titel: propTypes.string.def(''), | ||||
|   message: propTypes.string.def(''), | ||||
|  |  | |||
|  | @ -1,42 +1,42 @@ | |||
| <template> | ||||
|   <div :class="mode == 'pop' ? 'mask' : ''" v-show="showBox"> | ||||
|   <div v-show="showBox" :class="mode == 'pop' ? 'mask' : ''"> | ||||
|     <div | ||||
|       :class="mode == 'pop' ? 'verifybox' : ''" | ||||
|       :style="{ 'max-width': parseInt(imgSize.width) + 20 + 'px' }" | ||||
|     > | ||||
|       <div class="verifybox-top" v-if="mode == 'pop'"> | ||||
|       <div v-if="mode == 'pop'" class="verifybox-top"> | ||||
|         {{ t('captcha.verification') }} | ||||
|         <span class="verifybox-close" @click="closeBox"> | ||||
|           <i class="iconfont icon-close"></i> | ||||
|         </span> | ||||
|       </div> | ||||
|       <div class="verifybox-bottom" :style="{ padding: mode == 'pop' ? '10px' : '0' }"> | ||||
|       <div :style="{ padding: mode == 'pop' ? '10px' : '0' }" class="verifybox-bottom"> | ||||
|         <!-- 验证码容器 --> | ||||
|         <component | ||||
|           v-if="componentType" | ||||
|           :is="componentType" | ||||
|           :captchaType="captchaType" | ||||
|           :type="verifyType" | ||||
|           :figure="figure" | ||||
|           :arith="arith" | ||||
|           :mode="mode" | ||||
|           :vSpace="vSpace" | ||||
|           :explain="explain" | ||||
|           :imgSize="imgSize" | ||||
|           :blockSize="blockSize" | ||||
|           :barSize="barSize" | ||||
|           v-if="componentType" | ||||
|           ref="instance" | ||||
|           :arith="arith" | ||||
|           :barSize="barSize" | ||||
|           :blockSize="blockSize" | ||||
|           :captchaType="captchaType" | ||||
|           :explain="explain" | ||||
|           :figure="figure" | ||||
|           :imgSize="imgSize" | ||||
|           :mode="mode" | ||||
|           :type="verifyType" | ||||
|           :vSpace="vSpace" | ||||
|         /> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script type="text/babel"> | ||||
| <script name="Verify" type="text/babel"> | ||||
| /** | ||||
|  * Verify 验证码组件 | ||||
|  * @description 分发验证码使用 | ||||
|  * */ | ||||
| import { VerifySlide, VerifyPoints } from './Verify' | ||||
| import { VerifyPoints, VerifySlide } from './Verify' | ||||
| import { computed, ref, toRefs, watchEffect } from 'vue' | ||||
| 
 | ||||
| export default { | ||||
|  | @ -155,6 +155,7 @@ export default { | |||
|   border-radius: 5px; | ||||
|   transform: translate(-50%, -50%); | ||||
| } | ||||
| 
 | ||||
| .verifybox-top { | ||||
|   padding: 0 15px; | ||||
|   height: 40px; | ||||
|  | @ -165,10 +166,12 @@ export default { | |||
|   border-bottom: 1px solid #e4e7eb; | ||||
|   box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| .verifybox-bottom { | ||||
|   padding: 10px; | ||||
|   box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| .verifybox-close { | ||||
|   position: absolute; | ||||
|   top: 13px; | ||||
|  | @ -178,6 +181,7 @@ export default { | |||
|   text-align: center; | ||||
|   cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| .mask { | ||||
|   position: fixed; | ||||
|   top: 0; | ||||
|  | @ -189,6 +193,7 @@ export default { | |||
|   /* display: none; */ | ||||
|   transition: all 0.5s; | ||||
| } | ||||
| 
 | ||||
| .verify-tips { | ||||
|   text-indent: 10px; | ||||
|   position: absolute; | ||||
|  | @ -199,22 +204,27 @@ export default { | |||
|   line-height: 30px; | ||||
|   color: #fff; | ||||
| } | ||||
| 
 | ||||
| .suc-bg { | ||||
|   background-color: rgba(92, 184, 92, 0.5); | ||||
|   filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7f5CB85C, endcolorstr=#7f5CB85C); | ||||
| } | ||||
| 
 | ||||
| .err-bg { | ||||
|   background-color: rgba(217, 83, 79, 0.5); | ||||
|   filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7fD9534F, endcolorstr=#7fD9534F); | ||||
| } | ||||
| 
 | ||||
| .tips-enter, | ||||
| .tips-leave-to { | ||||
|   bottom: -30px; | ||||
| } | ||||
| 
 | ||||
| .tips-enter-active, | ||||
| .tips-leave-active { | ||||
|   transition: bottom 0.5s; | ||||
| } | ||||
| 
 | ||||
| /* ---------------------------- */ | ||||
| /*常规验证码*/ | ||||
| .verify-code { | ||||
|  |  | |||
|  | @ -2,20 +2,20 @@ | |||
|   <div style="position: relative"> | ||||
|     <div class="verify-img-out"> | ||||
|       <div | ||||
|         class="verify-img-panel" | ||||
|         :style="{ | ||||
|           width: setSize.imgWidth, | ||||
|           height: setSize.imgHeight, | ||||
|           'background-size': setSize.imgWidth + ' ' + setSize.imgHeight, | ||||
|           'margin-bottom': vSpace + 'px' | ||||
|         }" | ||||
|         class="verify-img-panel" | ||||
|       > | ||||
|         <div class="verify-refresh" style="z-index: 3" @click="refresh" v-show="showRefresh"> | ||||
|         <div v-show="showRefresh" class="verify-refresh" style="z-index: 3" @click="refresh"> | ||||
|           <i class="iconfont icon-refresh"></i> | ||||
|         </div> | ||||
|         <img | ||||
|           :src="'data:image/png;base64,' + pointBackImgBase" | ||||
|           ref="canvas" | ||||
|           :src="'data:image/png;base64,' + pointBackImgBase" | ||||
|           alt="" | ||||
|           style="width: 100%; height: 100%; display: block" | ||||
|           @click="bindingClick ? canvasClick($event) : undefined" | ||||
|  | @ -24,7 +24,6 @@ | |||
|         <div | ||||
|           v-for="(tempPoint, index) in tempPoints" | ||||
|           :key="index" | ||||
|           class="point-area" | ||||
|           :style="{ | ||||
|             'background-color': '#1abd6c', | ||||
|             color: '#fff', | ||||
|  | @ -38,6 +37,7 @@ | |||
|             top: parseInt(tempPoint.y - 10) + 'px', | ||||
|             left: parseInt(tempPoint.x - 10) + 'px' | ||||
|           }" | ||||
|           class="point-area" | ||||
|         > | ||||
|           {{ index + 1 }} | ||||
|         </div> | ||||
|  | @ -45,19 +45,19 @@ | |||
|     </div> | ||||
|     <!-- 'height': this.barSize.height, --> | ||||
|     <div | ||||
|       class="verify-bar-area" | ||||
|       :style="{ | ||||
|         width: setSize.imgWidth, | ||||
|         color: barAreaColor, | ||||
|         'border-color': barAreaBorderColor, | ||||
|         'line-height': barSize.height | ||||
|       }" | ||||
|       class="verify-bar-area" | ||||
|     > | ||||
|       <span class="verify-msg">{{ text }}</span> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script type="text/babel" setup> | ||||
| <script name="VerifyPoints" setup type="text/babel"> | ||||
| /** | ||||
|  * VerifyPoints | ||||
|  * @description 点选 | ||||
|  | @ -65,7 +65,7 @@ | |||
| import { resetSize } from './../utils/util' | ||||
| import { aesEncrypt } from './../utils/ase' | ||||
| import { getCode, reqCheck } from '@/api/login' | ||||
| import { onMounted, reactive, ref, nextTick, toRefs, getCurrentInstance } from 'vue' | ||||
| import { getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs } from 'vue' | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|   //弹出式pop,固定fixed | ||||
|  |  | |||
|  | @ -2,20 +2,20 @@ | |||
|   <div style="position: relative"> | ||||
|     <div | ||||
|       v-if="type === '2'" | ||||
|       class="verify-img-out" | ||||
|       :style="{ height: parseInt(setSize.imgHeight) + vSpace + 'px' }" | ||||
|       class="verify-img-out" | ||||
|     > | ||||
|       <div class="verify-img-panel" :style="{ width: setSize.imgWidth, height: setSize.imgHeight }"> | ||||
|       <div :style="{ width: setSize.imgWidth, height: setSize.imgHeight }" class="verify-img-panel"> | ||||
|         <img | ||||
|           :src="'data:image/png;base64,' + backImgBase" | ||||
|           alt="" | ||||
|           style="width: 100%; height: 100%; display: block" | ||||
|         /> | ||||
|         <div class="verify-refresh" @click="refresh" v-show="showRefresh"> | ||||
|         <div v-show="showRefresh" class="verify-refresh" @click="refresh"> | ||||
|           <i class="iconfont icon-refresh"></i> | ||||
|         </div> | ||||
|         <transition name="tips"> | ||||
|           <span class="verify-tips" v-if="tipWords" :class="passFlag ? 'suc-bg' : 'err-bg'"> | ||||
|           <span v-if="tipWords" :class="passFlag ? 'suc-bg' : 'err-bg'" class="verify-tips"> | ||||
|             {{ tipWords }} | ||||
|           </span> | ||||
|         </transition> | ||||
|  | @ -23,24 +23,21 @@ | |||
|     </div> | ||||
|     <!-- 公共部分 --> | ||||
|     <div | ||||
|       class="verify-bar-area" | ||||
|       :style="{ width: setSize.imgWidth, height: barSize.height, 'line-height': barSize.height }" | ||||
|       class="verify-bar-area" | ||||
|     > | ||||
|       <span class="verify-msg" v-text="text"></span> | ||||
|       <div | ||||
|         class="verify-left-bar" | ||||
|         :style="{ | ||||
|           width: leftBarWidth !== undefined ? leftBarWidth : barSize.height, | ||||
|           height: barSize.height, | ||||
|           'border-color': leftBarBorderColor, | ||||
|           transaction: transitionWidth | ||||
|         }" | ||||
|         class="verify-left-bar" | ||||
|       > | ||||
|         <span class="verify-msg" v-text="finishText"></span> | ||||
|         <div | ||||
|           class="verify-move-block" | ||||
|           @touchstart="start" | ||||
|           @mousedown="start" | ||||
|           :style="{ | ||||
|             width: barSize.height, | ||||
|             height: barSize.height, | ||||
|  | @ -48,17 +45,20 @@ | |||
|             left: moveBlockLeft, | ||||
|             transition: transitionLeft | ||||
|           }" | ||||
|           class="verify-move-block" | ||||
|           @mousedown="start" | ||||
|           @touchstart="start" | ||||
|         > | ||||
|           <i :class="['verify-icon iconfont', iconClass]" :style="{ color: iconColor }"></i> | ||||
|           <div | ||||
|             v-if="type === '2'" | ||||
|             class="verify-sub-block" | ||||
|             :style="{ | ||||
|               width: Math.floor((parseInt(setSize.imgWidth) * 47) / 310) + 'px', | ||||
|               height: setSize.imgHeight, | ||||
|               top: '-' + (parseInt(setSize.imgHeight) + vSpace) + 'px', | ||||
|               'background-size': setSize.imgWidth + ' ' + setSize.imgHeight | ||||
|             }" | ||||
|             class="verify-sub-block" | ||||
|           > | ||||
|             <img | ||||
|               :src="'data:image/png;base64,' + blockBackImgBase" | ||||
|  | @ -71,7 +71,7 @@ | |||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script type="text/babel" setup> | ||||
| <script name="VerifySlide" setup type="text/babel"> | ||||
| /** | ||||
|  * VerifySlide | ||||
|  * @description 滑块 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="XButton" setup> | ||||
| import { PropType } from 'vue' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| 
 | ||||
|  | @ -30,9 +30,9 @@ const getBindValue = computed(() => { | |||
| 
 | ||||
| <template> | ||||
|   <el-button v-bind="getBindValue" @click="onClick"> | ||||
|     <Icon :icon="preIcon" v-if="preIcon" class="mr-1px" /> | ||||
|     <Icon v-if="preIcon" :icon="preIcon" class="mr-1px" /> | ||||
|     {{ title ? title : '' }} | ||||
|     <Icon :icon="postIcon" v-if="postIcon" class="mr-1px" /> | ||||
|     <Icon v-if="postIcon" :icon="postIcon" class="mr-1px" /> | ||||
|   </el-button> | ||||
| </template> | ||||
| <style lang="scss" scoped> | ||||
|  | @ -40,6 +40,7 @@ const getBindValue = computed(() => { | |||
|   margin-left: 0; | ||||
|   padding: 8px 4px; | ||||
| } | ||||
| 
 | ||||
| :deep(.el-button.is-link) { | ||||
|   margin-left: 0; | ||||
|   padding: 8px 4px; | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="XTextButton" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { PropType } from 'vue' | ||||
| 
 | ||||
|  | @ -29,9 +29,9 @@ const getBindValue = computed(() => { | |||
| 
 | ||||
| <template> | ||||
|   <el-button link v-bind="getBindValue" @click="onClick"> | ||||
|     <Icon :icon="preIcon" v-if="preIcon" class="mr-1px" /> | ||||
|     <Icon v-if="preIcon" :icon="preIcon" class="mr-1px" /> | ||||
|     {{ title ? title : '' }} | ||||
|     <Icon :icon="postIcon" v-if="postIcon" class="mr-1px" /> | ||||
|     <Icon v-if="postIcon" :icon="postIcon" class="mr-1px" /> | ||||
|   </el-button> | ||||
| </template> | ||||
| <style lang="scss" scoped> | ||||
|  | @ -39,6 +39,7 @@ const getBindValue = computed(() => { | |||
|   margin-left: 0; | ||||
|   padding: 8px 4px; | ||||
| } | ||||
| 
 | ||||
| :deep(.el-button.is-link) { | ||||
|   margin-left: 0; | ||||
|   padding: 8px 4px; | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="AppView" setup> | ||||
| import { useTagsViewStore } from '@/store/modules/tagsView' | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| import { Footer } from '@/layout/components/Footer' | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Collapse" setup> | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  | @ -24,9 +24,9 @@ const toggleCollapse = () => { | |||
| <template> | ||||
|   <div :class="prefixCls"> | ||||
|     <Icon | ||||
|       :size="18" | ||||
|       :icon="collapse ? 'ep:expand' : 'ep:fold'" | ||||
|       :color="color" | ||||
|       :icon="collapse ? 'ep:expand' : 'ep:fold'" | ||||
|       :size="18" | ||||
|       class="cursor-pointer" | ||||
|       @click="toggleCollapse" | ||||
|     /> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ContextMenu" setup> | ||||
| import { PropType } from 'vue' | ||||
| 
 | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  | @ -51,9 +51,9 @@ defineExpose({ | |||
|     :class="prefixCls" | ||||
|     :trigger="trigger" | ||||
|     placement="bottom-start" | ||||
|     popper-class="v-context-menu-popper" | ||||
|     @command="command" | ||||
|     @visible-change="visibleChange" | ||||
|     popper-class="v-context-menu-popper" | ||||
|   > | ||||
|     <slot></slot> | ||||
|     <template #dropdown> | ||||
|  | @ -61,11 +61,12 @@ defineExpose({ | |||
|         <ElDropdownItem | ||||
|           v-for="(item, index) in schema" | ||||
|           :key="`dropdown${index}`" | ||||
|           :divided="item.divided" | ||||
|           :disabled="item.disabled" | ||||
|           :command="item" | ||||
|           :disabled="item.disabled" | ||||
|           :divided="item.divided" | ||||
|         > | ||||
|           <Icon :icon="item.icon" /> {{ t(item.label) }} | ||||
|           <Icon :icon="item.icon" /> | ||||
|           {{ t(item.label) }} | ||||
|         </ElDropdownItem> | ||||
|       </ElDropdownMenu> | ||||
|     </template> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Footer" setup> | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="LocaleDropdown" setup> | ||||
| import { useLocaleStore } from '@/store/modules/locale' | ||||
| import { useLocale } from '@/hooks/web/useLocale' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
|  | @ -33,11 +33,11 @@ const setLang = (lang: LocaleType) => { | |||
| <template> | ||||
|   <ElDropdown :class="prefixCls" trigger="click" @command="setLang"> | ||||
|     <Icon | ||||
|       :size="18" | ||||
|       icon="ion:language-sharp" | ||||
|       class="cursor-pointer" | ||||
|       :class="$attrs.class" | ||||
|       :color="color" | ||||
|       :size="18" | ||||
|       class="cursor-pointer" | ||||
|       icon="ion:language-sharp" | ||||
|     /> | ||||
|     <template #dropdown> | ||||
|       <ElDropdownMenu> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <script setup lang="ts"> | ||||
| import { ref, watch, computed, onMounted, unref } from 'vue' | ||||
| <script lang="ts" name="Logo" setup> | ||||
| import { computed, onMounted, ref, unref, watch } from 'vue' | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| 
 | ||||
|  | @ -66,8 +66,8 @@ watch( | |||
|       to="/" | ||||
|     > | ||||
|       <img | ||||
|         src="@/assets/imgs/logo.png" | ||||
|         class="w-[calc(var(--logo-height)-10px)] h-[calc(var(--logo-height)-10px)]" | ||||
|         src="@/assets/imgs/logo.png" | ||||
|       /> | ||||
|       <div | ||||
|         v-if="show" | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Message" setup> | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import * as NotifyMessageApi from '@/api/system/notify/message' | ||||
| 
 | ||||
|  | @ -40,10 +40,10 @@ onMounted(() => { | |||
| </script> | ||||
| <template> | ||||
|   <div class="message"> | ||||
|     <ElPopover placement="bottom" :width="400" trigger="click"> | ||||
|     <ElPopover :width="400" placement="bottom" trigger="click"> | ||||
|       <template #reference> | ||||
|         <ElBadge :is-dot="unreadCount > 0" class="item"> | ||||
|           <Icon icon="ep:bell" :size="18" class="cursor-pointer" @click="getList" /> | ||||
|           <Icon :size="18" class="cursor-pointer" icon="ep:bell" @click="getList" /> | ||||
|         </ElBadge> | ||||
|       </template> | ||||
|       <ElTabs v-model="activeName"> | ||||
|  | @ -51,7 +51,7 @@ onMounted(() => { | |||
|           <div class="message-list"> | ||||
|             <template v-for="item in list" :key="item.id"> | ||||
|               <div class="message-item"> | ||||
|                 <img src="@/assets/imgs/avatar.gif" alt="" class="message-icon" /> | ||||
|                 <img alt="" class="message-icon" src="@/assets/imgs/avatar.gif" /> | ||||
|                 <div class="message-content"> | ||||
|                   <span class="message-title"> | ||||
|                     {{ item.templateNickname }}:{{ item.templateContent }} | ||||
|  | @ -67,12 +67,12 @@ onMounted(() => { | |||
|       </ElTabs> | ||||
|       <!-- 更多 --> | ||||
|       <div style="text-align: right; margin-top: 10px"> | ||||
|         <XButton type="primary" preIcon="ep:view" title="查看全部" @click="goMyList" /> | ||||
|         <XButton preIcon="ep:view" title="查看全部" type="primary" @click="goMyList" /> | ||||
|       </div> | ||||
|     </ElPopover> | ||||
|   </div> | ||||
| </template> | ||||
| <style scoped lang="scss"> | ||||
| <style lang="scss" scoped> | ||||
| .message-empty { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|  | @ -81,28 +81,35 @@ onMounted(() => { | |||
|   height: 260px; | ||||
|   line-height: 45px; | ||||
| } | ||||
| 
 | ||||
| .message-list { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
| 
 | ||||
|   .message-item { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     padding: 20px 0; | ||||
|     border-bottom: 1px solid var(--el-border-color-light); | ||||
| 
 | ||||
|     &:last-child { | ||||
|       border: none; | ||||
|     } | ||||
| 
 | ||||
|     .message-icon { | ||||
|       width: 40px; | ||||
|       height: 40px; | ||||
|       margin: 0 20px 0 5px; | ||||
|     } | ||||
| 
 | ||||
|     .message-content { | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
| 
 | ||||
|       .message-title { | ||||
|         margin-bottom: 5px; | ||||
|       } | ||||
| 
 | ||||
|       .message-date { | ||||
|         font-size: 12px; | ||||
|         color: var(--el-text-color-secondary); | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ScreenFull" setup> | ||||
| import { Icon } from '@/components/Icon' | ||||
| import { useFullscreen } from '@vueuse/core' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
|  | @ -22,9 +22,9 @@ const toggleFullscreen = () => { | |||
| <template> | ||||
|   <div :class="prefixCls" @click="toggleFullscreen"> | ||||
|     <Icon | ||||
|       :size="18" | ||||
|       :icon="isFullscreen ? 'zmdi:fullscreen-exit' : 'zmdi:fullscreen'" | ||||
|       :color="color" | ||||
|       :icon="isFullscreen ? 'zmdi:fullscreen-exit' : 'zmdi:fullscreen'" | ||||
|       :size="18" | ||||
|     /> | ||||
|   </div> | ||||
| </template> | ||||
|  |  | |||
|  | @ -1,12 +1,12 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Setting" setup> | ||||
| import { ElMessage } from 'element-plus' | ||||
| import { useCssVar, useClipboard } from '@vueuse/core' | ||||
| import { useClipboard, useCssVar } from '@vueuse/core' | ||||
| 
 | ||||
| import { CACHE_KEY, useCache } from '@/hooks/web/useCache' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| 
 | ||||
| import { trim, setCssVar } from '@/utils' | ||||
| import { colorIsDark, lighten, hexToRGB } from '@/utils/color' | ||||
| import { setCssVar, trim } from '@/utils' | ||||
| import { colorIsDark, hexToRGB, lighten } from '@/utils/color' | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| import { ThemeSwitch } from '@/layout/components/ThemeSwitch' | ||||
| import ColorRadioPicker from './components/ColorRadioPicker.vue' | ||||
|  | @ -202,10 +202,10 @@ const clear = () => { | |||
|     class="fixed top-[45%] right-0 w-40px h-40px text-center leading-40px bg-[var(--el-color-primary)] cursor-pointer" | ||||
|     @click="drawer = true" | ||||
|   > | ||||
|     <Icon icon="ep:setting" color="#fff" /> | ||||
|     <Icon color="#fff" icon="ep:setting" /> | ||||
|   </div> | ||||
| 
 | ||||
|   <ElDrawer v-model="drawer" direction="rtl" size="350px" :z-index="4000"> | ||||
|   <ElDrawer v-model="drawer" :z-index="4000" direction="rtl" size="350px"> | ||||
|     <template #header> | ||||
|       <span class="text-16px font-700">{{ t('setting.projectSetting') }}</span> | ||||
|     </template> | ||||
|  | @ -279,10 +279,10 @@ const clear = () => { | |||
| 
 | ||||
|     <ElDivider /> | ||||
|     <div> | ||||
|       <ElButton type="primary" class="w-full" @click="copyConfig">{{ t('setting.copy') }}</ElButton> | ||||
|       <ElButton class="w-full" type="primary" @click="copyConfig">{{ t('setting.copy') }}</ElButton> | ||||
|     </div> | ||||
|     <div class="mt-5px"> | ||||
|       <ElButton type="danger" class="w-full" @click="clear"> | ||||
|       <ElButton class="w-full" type="danger" @click="clear"> | ||||
|         {{ t('setting.clearAndReset') }} | ||||
|       </ElButton> | ||||
|     </div> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ColorRadioPicker" setup> | ||||
| import { PropType } from 'vue' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  | @ -42,14 +42,14 @@ watch( | |||
|     <span | ||||
|       v-for="(item, i) in schema" | ||||
|       :key="`radio-${i}`" | ||||
|       class="w-20px h-20px cursor-pointer rounded-2px border-solid border-gray-300 border-2px text-center leading-20px mb-5px" | ||||
|       :class="{ 'is-active': colorVal === item }" | ||||
|       :style="{ | ||||
|         background: item | ||||
|       }" | ||||
|       class="w-20px h-20px cursor-pointer rounded-2px border-solid border-gray-300 border-2px text-center leading-20px mb-5px" | ||||
|       @click="colorVal = item" | ||||
|     > | ||||
|       <Icon v-if="colorVal === item" color="#fff" icon="ep:check" :size="16" /> | ||||
|       <Icon v-if="colorVal === item" :size="16" color="#fff" icon="ep:check" /> | ||||
|     </span> | ||||
|   </div> | ||||
| </template> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InterfaceDisplay" setup> | ||||
| import { setCssVar } from '@/utils' | ||||
| 
 | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="LayoutRadioPicker" setup> | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="SizeDropdown" setup> | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| 
 | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
|  | @ -26,7 +26,7 @@ const setCurrentSize = (size: ElementPlusSize) => { | |||
| 
 | ||||
| <template> | ||||
|   <ElDropdown :class="prefixCls" trigger="click" @command="setCurrentSize"> | ||||
|     <Icon :size="18" icon="mdi:format-size" :color="color" class="cursor-pointer" /> | ||||
|     <Icon :color="color" :size="18" class="cursor-pointer" icon="mdi:format-size" /> | ||||
|     <template #dropdown> | ||||
|       <ElDropdownMenu> | ||||
|         <ElDropdownItem v-for="item in sizeMap" :key="item" :command="item"> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="TagsView" setup> | ||||
| import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router' | ||||
| import { usePermissionStore } from '@/store/modules/permission' | ||||
| import { useTagsViewStore } from '@/store/modules/tagsView' | ||||
|  | @ -266,15 +266,24 @@ watch( | |||
|       @click="move(-200)" | ||||
|     > | ||||
|       <Icon | ||||
|         icon="ep:d-arrow-left" | ||||
|         :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'" | ||||
|         icon="ep:d-arrow-left" | ||||
|       /> | ||||
|     </span> | ||||
|     <div class="overflow-hidden flex-1"> | ||||
|       <ElScrollbar ref="scrollbarRef" class="h-full" @scroll="scroll"> | ||||
|         <div class="flex h-full"> | ||||
|           <ContextMenu | ||||
|             v-for="item in visitedViews" | ||||
|             :key="item.fullPath" | ||||
|             :ref="itemRefs.set" | ||||
|             :class="[ | ||||
|               `${prefixCls}__item`, | ||||
|               item?.meta?.affix ? `${prefixCls}__item--affix` : '', | ||||
|               { | ||||
|                 'is-active': isActive(item) | ||||
|               } | ||||
|             ]" | ||||
|             :schema="[ | ||||
|               { | ||||
|                 icon: 'ep:refresh', | ||||
|  | @ -332,23 +341,14 @@ watch( | |||
|                 } | ||||
|               } | ||||
|             ]" | ||||
|             v-for="item in visitedViews" | ||||
|             :key="item.fullPath" | ||||
|             :tag-item="item" | ||||
|             :class="[ | ||||
|               `${prefixCls}__item`, | ||||
|               item?.meta?.affix ? `${prefixCls}__item--affix` : '', | ||||
|               { | ||||
|                 'is-active': isActive(item) | ||||
|               } | ||||
|             ]" | ||||
|             @visible-change="visibleChange" | ||||
|           > | ||||
|             <div> | ||||
|               <router-link :ref="tagLinksRefs.set" :to="{ ...item }" custom v-slot="{ navigate }"> | ||||
|               <router-link :ref="tagLinksRefs.set" v-slot="{ navigate }" :to="{ ...item }" custom> | ||||
|                 <div | ||||
|                   @click="navigate" | ||||
|                   class="h-full flex justify-center items-center whitespace-nowrap pl-15px" | ||||
|                   @click="navigate" | ||||
|                 > | ||||
|                   <Icon | ||||
|                     v-if=" | ||||
|  | @ -364,9 +364,9 @@ watch( | |||
|                   {{ t(item?.meta?.title as string) }} | ||||
|                   <Icon | ||||
|                     :class="`${prefixCls}__item--close`" | ||||
|                     :size="12" | ||||
|                     color="#333" | ||||
|                     icon="ep:close" | ||||
|                     :size="12" | ||||
|                     @click.prevent.stop="closeSelectedTag(item)" | ||||
|                   /> | ||||
|                 </div> | ||||
|  | @ -382,8 +382,8 @@ watch( | |||
|       @click="move(200)" | ||||
|     > | ||||
|       <Icon | ||||
|         icon="ep:d-arrow-right" | ||||
|         :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'" | ||||
|         icon="ep:d-arrow-right" | ||||
|       /> | ||||
|     </span> | ||||
|     <span | ||||
|  | @ -392,12 +392,11 @@ watch( | |||
|       @click="refreshSelectedTag(selectedTag)" | ||||
|     > | ||||
|       <Icon | ||||
|         icon="ep:refresh-right" | ||||
|         :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'" | ||||
|         icon="ep:refresh-right" | ||||
|       /> | ||||
|     </span> | ||||
|     <ContextMenu | ||||
|       trigger="click" | ||||
|       :schema="[ | ||||
|         { | ||||
|           icon: 'ep:refresh', | ||||
|  | @ -449,14 +448,15 @@ watch( | |||
|           } | ||||
|         } | ||||
|       ]" | ||||
|       trigger="click" | ||||
|     > | ||||
|       <span | ||||
|         :class="`${prefixCls}__tool`" | ||||
|         class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer block" | ||||
|       > | ||||
|         <Icon | ||||
|           icon="ep:menu" | ||||
|           :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'" | ||||
|           icon="ep:menu" | ||||
|         /> | ||||
|       </span> | ||||
|     </ContextMenu> | ||||
|  | @ -513,6 +513,7 @@ $prefix-cls: #{$namespace}-tags-view; | |||
|       display: none; | ||||
|       transform: translate(0, -50%); | ||||
|     } | ||||
| 
 | ||||
|     &:not(.#{$prefix-cls}__item--affix):hover { | ||||
|       .#{$prefix-cls}__item--close { | ||||
|         display: block; | ||||
|  | @ -530,6 +531,7 @@ $prefix-cls: #{$namespace}-tags-view; | |||
|     color: var(--el-color-white); | ||||
|     background-color: var(--el-color-primary); | ||||
|     border: 1px solid var(--el-color-primary); | ||||
| 
 | ||||
|     .#{$prefix-cls}__item--close { | ||||
|       :deep(span) { | ||||
|         color: var(--el-color-white) !important; | ||||
|  | @ -573,6 +575,7 @@ $prefix-cls: #{$namespace}-tags-view; | |||
|     &__item.is-active { | ||||
|       color: var(--el-color-white); | ||||
|       background-color: var(--el-color-primary); | ||||
| 
 | ||||
|       .#{$prefix-cls}__item--close { | ||||
|         :deep(span) { | ||||
|           color: var(--el-color-white) !important; | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ThemeSwitch" setup> | ||||
| import { useAppStore } from '@/store/modules/app' | ||||
| import { useIcon } from '@/hooks/web/useIcon' | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  | @ -26,14 +26,14 @@ const themeChange = (val: boolean) => { | |||
| 
 | ||||
| <template> | ||||
|   <ElSwitch | ||||
|     :class="prefixCls" | ||||
|     v-model="isDark" | ||||
|     inline-prompt | ||||
|     :border-color="blackColor" | ||||
|     :inactive-color="blackColor" | ||||
|     :active-color="blackColor" | ||||
|     :active-icon="Sun" | ||||
|     :border-color="blackColor" | ||||
|     :class="prefixCls" | ||||
|     :inactive-color="blackColor" | ||||
|     :inactive-icon="CrescentMoon" | ||||
|     inline-prompt | ||||
|     @change="themeChange" | ||||
|   /> | ||||
| </template> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="UserInfo" setup> | ||||
| import { ElMessageBox } from 'element-plus' | ||||
| 
 | ||||
| import { CACHE_KEY, useCache } from '@/hooks/web/useCache' | ||||
|  |  | |||
|  | @ -1 +0,0 @@ | |||
| auto-*.d.ts | ||||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
|   <Error type="403" @error-click="push('/')" /> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Error403" setup> | ||||
| const { push } = useRouter() | ||||
| </script> | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
|   <Error @error-click="push('/')" /> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Error404" setup> | ||||
| const { push } = useRouter() | ||||
| </script> | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
|   <Error type="500" @error-click="push('/')" /> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Error500" setup> | ||||
| const { push } = useRouter() | ||||
| </script> | ||||
|  |  | |||
|  | @ -1,26 +1,26 @@ | |||
| <template> | ||||
|   <el-row :gutter="20" justify="space-between" :class="prefixCls"> | ||||
|     <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24"> | ||||
|       <el-card shadow="hover" class="mb-20px"> | ||||
|         <el-skeleton :loading="loading" animated :rows="2"> | ||||
|   <el-row :class="prefixCls" :gutter="20" justify="space-between"> | ||||
|     <el-col :lg="6" :md="12" :sm="12" :xl="6" :xs="24"> | ||||
|       <el-card class="mb-20px" shadow="hover"> | ||||
|         <el-skeleton :loading="loading" :rows="2" animated> | ||||
|           <template #default> | ||||
|             <div :class="`${prefixCls}__item flex justify-between`"> | ||||
|               <div> | ||||
|                 <div | ||||
|                   :class="`${prefixCls}__item--icon ${prefixCls}__item--peoples p-16px inline-block rounded-6px`" | ||||
|                 > | ||||
|                   <Icon icon="svg-icon:peoples" :size="40" /> | ||||
|                   <Icon :size="40" icon="svg-icon:peoples" /> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="flex flex-col justify-between"> | ||||
|                 <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{ | ||||
|                   t('analysis.newUser') | ||||
|                 }}</div> | ||||
|                 <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`" | ||||
|                   >{{ t('analysis.newUser') }} | ||||
|                 </div> | ||||
|                 <CountTo | ||||
|                   class="text-20px font-700 text-right" | ||||
|                   :start-val="0" | ||||
|                   :end-val="102400" | ||||
|                   :duration="2600" | ||||
|                   :end-val="102400" | ||||
|                   :start-val="0" | ||||
|                   class="text-20px font-700 text-right" | ||||
|                 /> | ||||
|               </div> | ||||
|             </div> | ||||
|  | @ -29,27 +29,27 @@ | |||
|       </el-card> | ||||
|     </el-col> | ||||
| 
 | ||||
|     <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24"> | ||||
|       <el-card shadow="hover" class="mb-20px"> | ||||
|         <el-skeleton :loading="loading" animated :rows="2"> | ||||
|     <el-col :lg="6" :md="12" :sm="12" :xl="6" :xs="24"> | ||||
|       <el-card class="mb-20px" shadow="hover"> | ||||
|         <el-skeleton :loading="loading" :rows="2" animated> | ||||
|           <template #default> | ||||
|             <div :class="`${prefixCls}__item flex justify-between`"> | ||||
|               <div> | ||||
|                 <div | ||||
|                   :class="`${prefixCls}__item--icon ${prefixCls}__item--message p-16px inline-block rounded-6px`" | ||||
|                 > | ||||
|                   <Icon icon="svg-icon:message" :size="40" /> | ||||
|                   <Icon :size="40" icon="svg-icon:message" /> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="flex flex-col justify-between"> | ||||
|                 <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{ | ||||
|                   t('analysis.unreadInformation') | ||||
|                 }}</div> | ||||
|                 <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`" | ||||
|                   >{{ t('analysis.unreadInformation') }} | ||||
|                 </div> | ||||
|                 <CountTo | ||||
|                   class="text-20px font-700 text-right" | ||||
|                   :start-val="0" | ||||
|                   :end-val="81212" | ||||
|                   :duration="2600" | ||||
|                   :end-val="81212" | ||||
|                   :start-val="0" | ||||
|                   class="text-20px font-700 text-right" | ||||
|                 /> | ||||
|               </div> | ||||
|             </div> | ||||
|  | @ -58,27 +58,27 @@ | |||
|       </el-card> | ||||
|     </el-col> | ||||
| 
 | ||||
|     <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24"> | ||||
|       <el-card shadow="hover" class="mb-20px"> | ||||
|         <el-skeleton :loading="loading" animated :rows="2"> | ||||
|     <el-col :lg="6" :md="12" :sm="12" :xl="6" :xs="24"> | ||||
|       <el-card class="mb-20px" shadow="hover"> | ||||
|         <el-skeleton :loading="loading" :rows="2" animated> | ||||
|           <template #default> | ||||
|             <div :class="`${prefixCls}__item flex justify-between`"> | ||||
|               <div> | ||||
|                 <div | ||||
|                   :class="`${prefixCls}__item--icon ${prefixCls}__item--money p-16px inline-block rounded-6px`" | ||||
|                 > | ||||
|                   <Icon icon="svg-icon:money" :size="40" /> | ||||
|                   <Icon :size="40" icon="svg-icon:money" /> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="flex flex-col justify-between"> | ||||
|                 <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{ | ||||
|                   t('analysis.transactionAmount') | ||||
|                 }}</div> | ||||
|                 <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`" | ||||
|                   >{{ t('analysis.transactionAmount') }} | ||||
|                 </div> | ||||
|                 <CountTo | ||||
|                   class="text-20px font-700 text-right" | ||||
|                   :start-val="0" | ||||
|                   :end-val="9280" | ||||
|                   :duration="2600" | ||||
|                   :end-val="9280" | ||||
|                   :start-val="0" | ||||
|                   class="text-20px font-700 text-right" | ||||
|                 /> | ||||
|               </div> | ||||
|             </div> | ||||
|  | @ -87,27 +87,27 @@ | |||
|       </el-card> | ||||
|     </el-col> | ||||
| 
 | ||||
|     <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24"> | ||||
|       <el-card shadow="hover" class="mb-20px"> | ||||
|         <el-skeleton :loading="loading" animated :rows="2"> | ||||
|     <el-col :lg="6" :md="12" :sm="12" :xl="6" :xs="24"> | ||||
|       <el-card class="mb-20px" shadow="hover"> | ||||
|         <el-skeleton :loading="loading" :rows="2" animated> | ||||
|           <template #default> | ||||
|             <div :class="`${prefixCls}__item flex justify-between`"> | ||||
|               <div> | ||||
|                 <div | ||||
|                   :class="`${prefixCls}__item--icon ${prefixCls}__item--shopping p-16px inline-block rounded-6px`" | ||||
|                 > | ||||
|                   <Icon icon="svg-icon:shopping" :size="40" /> | ||||
|                   <Icon :size="40" icon="svg-icon:shopping" /> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="flex flex-col justify-between"> | ||||
|                 <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`">{{ | ||||
|                   t('analysis.totalShopping') | ||||
|                 }}</div> | ||||
|                 <div :class="`${prefixCls}__item--text text-16px text-gray-500 text-right`" | ||||
|                   >{{ t('analysis.totalShopping') }} | ||||
|                 </div> | ||||
|                 <CountTo | ||||
|                   class="text-20px font-700 text-right" | ||||
|                   :start-val="0" | ||||
|                   :end-val="13600" | ||||
|                   :duration="2600" | ||||
|                   :end-val="13600" | ||||
|                   :start-val="0" | ||||
|                   class="text-20px font-700 text-right" | ||||
|                 /> | ||||
|               </div> | ||||
|             </div> | ||||
|  | @ -117,36 +117,36 @@ | |||
|     </el-col> | ||||
|   </el-row> | ||||
|   <el-row :gutter="20" justify="space-between"> | ||||
|     <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24"> | ||||
|       <el-card shadow="hover" class="mb-20px"> | ||||
|     <el-col :lg="10" :md="24" :sm="24" :xl="10" :xs="24"> | ||||
|       <el-card class="mb-20px" shadow="hover"> | ||||
|         <el-skeleton :loading="loading" animated> | ||||
|           <Echart :options="pieOptionsData" :height="300" /> | ||||
|           <Echart :height="300" :options="pieOptionsData" /> | ||||
|         </el-skeleton> | ||||
|       </el-card> | ||||
|     </el-col> | ||||
|     <el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24"> | ||||
|       <el-card shadow="hover" class="mb-20px"> | ||||
|     <el-col :lg="14" :md="24" :sm="24" :xl="14" :xs="24"> | ||||
|       <el-card class="mb-20px" shadow="hover"> | ||||
|         <el-skeleton :loading="loading" animated> | ||||
|           <Echart :options="barOptionsData" :height="300" /> | ||||
|           <Echart :height="300" :options="barOptionsData" /> | ||||
|         </el-skeleton> | ||||
|       </el-card> | ||||
|     </el-col> | ||||
|     <el-col :span="24"> | ||||
|       <el-card shadow="hover" class="mb-20px"> | ||||
|         <el-skeleton :loading="loading" animated :rows="4"> | ||||
|           <Echart :options="lineOptionsData" :height="350" /> | ||||
|       <el-card class="mb-20px" shadow="hover"> | ||||
|         <el-skeleton :loading="loading" :rows="4" animated> | ||||
|           <Echart :height="350" :options="lineOptionsData" /> | ||||
|         </el-skeleton> | ||||
|       </el-card> | ||||
|     </el-col> | ||||
|   </el-row> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="Home2" setup> | ||||
| import { set } from 'lodash-es' | ||||
| import { EChartsOption } from 'echarts' | ||||
| 
 | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
| import type { AnalysisTotalTypes } from './types' | ||||
| import { pieOptions, barOptions, lineOptions } from './echarts-data' | ||||
| import { barOptions, lineOptions, pieOptions } from './echarts-data' | ||||
| 
 | ||||
| const { t } = useI18n() | ||||
| const loading = ref(true) | ||||
|  | @ -291,18 +291,23 @@ $prefix-cls: #{$namespace}-panel; | |||
|       :deep(.#{$namespace}-icon) { | ||||
|         color: #fff !important; | ||||
|       } | ||||
| 
 | ||||
|       .#{$prefix-cls}__item--icon { | ||||
|         transition: all 0.38s ease-out; | ||||
|       } | ||||
| 
 | ||||
|       .#{$prefix-cls}__item--peoples { | ||||
|         background: #40c9c6; | ||||
|       } | ||||
| 
 | ||||
|       .#{$prefix-cls}__item--message { | ||||
|         background: #36a3f7; | ||||
|       } | ||||
| 
 | ||||
|       .#{$prefix-cls}__item--money { | ||||
|         background: #f4516c; | ||||
|       } | ||||
| 
 | ||||
|       .#{$prefix-cls}__item--shopping { | ||||
|         background: #34bfa3; | ||||
|       } | ||||
|  |  | |||
|  | @ -60,7 +60,7 @@ | |||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| <script lang="ts" name="Login" setup> | ||||
| import { underlineToHump } from '@/utils' | ||||
| 
 | ||||
| import { useDesign } from '@/hooks/web/useDesign' | ||||
|  |  | |||
|  | @ -1,13 +1,13 @@ | |||
| <template> | ||||
|   <el-form | ||||
|     :model="loginData.loginForm" | ||||
|     :rules="LoginRules" | ||||
|     label-position="top" | ||||
|     class="login-form" | ||||
|     label-width="120px" | ||||
|     size="large" | ||||
|     v-show="getShow" | ||||
|     ref="formLogin" | ||||
|     :model="loginData.loginForm" | ||||
|     :rules="LoginRules" | ||||
|     class="login-form" | ||||
|     label-position="top" | ||||
|     label-width="120px" | ||||
|     size="large" | ||||
|   > | ||||
|     <el-row style="maring-left: -10px; maring-right: -10px"> | ||||
|       <el-col :span="24" style="padding-left: 10px; padding-right: 10px"> | ||||
|  | @ -16,13 +16,13 @@ | |||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="24" style="padding-left: 10px; padding-right: 10px"> | ||||
|         <el-form-item prop="tenantName" v-if="loginData.tenantEnable === 'true'"> | ||||
|         <el-form-item v-if="loginData.tenantEnable === 'true'" prop="tenantName"> | ||||
|           <el-input | ||||
|             type="primary" | ||||
|             link | ||||
|             v-model="loginData.loginForm.tenantName" | ||||
|             :placeholder="t('login.tenantNamePlaceholder')" | ||||
|             :prefix-icon="iconHouse" | ||||
|             type="primary" | ||||
|             link | ||||
|           /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | @ -39,11 +39,11 @@ | |||
|         <el-form-item prop="password"> | ||||
|           <el-input | ||||
|             v-model="loginData.loginForm.password" | ||||
|             type="password" | ||||
|             :placeholder="t('login.passwordPlaceholder')" | ||||
|             show-password | ||||
|             @keyup.enter="getCode()" | ||||
|             :prefix-icon="iconLock" | ||||
|             show-password | ||||
|             type="password" | ||||
|             @keyup.enter="getCode()" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | @ -58,8 +58,8 @@ | |||
|                 {{ t('login.remember') }} | ||||
|               </el-checkbox> | ||||
|             </el-col> | ||||
|             <el-col :span="12" :offset="6"> | ||||
|               <el-link type="primary" style="float: right">{{ t('login.forgetPassword') }}</el-link> | ||||
|             <el-col :offset="6" :span="12"> | ||||
|               <el-link style="float: right" type="primary">{{ t('login.forgetPassword') }}</el-link> | ||||
|             </el-col> | ||||
|           </el-row> | ||||
|         </el-form-item> | ||||
|  | @ -68,41 +68,41 @@ | |||
|         <el-form-item> | ||||
|           <XButton | ||||
|             :loading="loginLoading" | ||||
|             type="primary" | ||||
|             class="w-[100%]" | ||||
|             :title="t('login.login')" | ||||
|             class="w-[100%]" | ||||
|             type="primary" | ||||
|             @click="getCode()" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <Verify | ||||
|         ref="verify" | ||||
|         mode="pop" | ||||
|         :captchaType="captchaType" | ||||
|         :imgSize="{ width: '400px', height: '200px' }" | ||||
|         mode="pop" | ||||
|         @success="handleLogin" | ||||
|       /> | ||||
|       <el-col :span="24" style="padding-left: 10px; padding-right: 10px"> | ||||
|         <el-form-item> | ||||
|           <el-row justify="space-between" style="width: 100%" :gutter="5"> | ||||
|           <el-row :gutter="5" justify="space-between" style="width: 100%"> | ||||
|             <el-col :span="8"> | ||||
|               <XButton | ||||
|                 class="w-[100%]" | ||||
|                 :title="t('login.btnMobile')" | ||||
|                 class="w-[100%]" | ||||
|                 @click="setLoginState(LoginStateEnum.MOBILE)" | ||||
|               /> | ||||
|             </el-col> | ||||
|             <el-col :span="8"> | ||||
|               <XButton | ||||
|                 class="w-[100%]" | ||||
|                 :title="t('login.btnQRCode')" | ||||
|                 class="w-[100%]" | ||||
|                 @click="setLoginState(LoginStateEnum.QR_CODE)" | ||||
|               /> | ||||
|             </el-col> | ||||
|             <el-col :span="8"> | ||||
|               <XButton | ||||
|                 class="w-[100%]" | ||||
|                 :title="t('login.btnRegister')" | ||||
|                 class="w-[100%]" | ||||
|                 @click="setLoginState(LoginStateEnum.REGISTER)" | ||||
|               /> | ||||
|             </el-col> | ||||
|  | @ -128,7 +128,7 @@ | |||
|     </el-row> | ||||
|   </el-form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="LoginForm" setup> | ||||
| import { ElLoading } from 'element-plus' | ||||
| import LoginFormTitle from './LoginFormTitle.vue' | ||||
| import type { RouteLocationNormalizedLoaded } from 'vue-router' | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
|     {{ getFormTitle }} | ||||
|   </h2> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="LoginFormTitle" setup> | ||||
| import { LoginStateEnum, useLoginState } from './useLogin' | ||||
| 
 | ||||
| const { t } = useI18n() | ||||
|  |  | |||
|  | @ -1,13 +1,13 @@ | |||
| <template> | ||||
|   <el-form | ||||
|     :model="loginData.loginForm" | ||||
|     :rules="rules" | ||||
|     label-position="top" | ||||
|     class="login-form" | ||||
|     label-width="120px" | ||||
|     size="large" | ||||
|     v-show="getShow" | ||||
|     ref="formSmsLogin" | ||||
|     :model="loginData.loginForm" | ||||
|     :rules="rules" | ||||
|     class="login-form" | ||||
|     label-position="top" | ||||
|     label-width="120px" | ||||
|     size="large" | ||||
|   > | ||||
|     <el-row style="margin-left: -10px; margin-right: -10px"> | ||||
|       <!-- 租户名 --> | ||||
|  | @ -17,13 +17,13 @@ | |||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="24" style="padding-left: 10px; padding-right: 10px"> | ||||
|         <el-form-item prop="tenantName" v-if="loginData.tenantEnable === 'true'"> | ||||
|         <el-form-item v-if="loginData.tenantEnable === 'true'" prop="tenantName"> | ||||
|           <el-input | ||||
|             type="primary" | ||||
|             link | ||||
|             v-model="loginData.loginForm.tenantName" | ||||
|             :placeholder="t('login.tenantNamePlaceholder')" | ||||
|             :prefix-icon="iconHouse" | ||||
|             type="primary" | ||||
|             link | ||||
|           /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | @ -40,7 +40,7 @@ | |||
|       <!-- 验证码 --> | ||||
|       <el-col :span="24" style="padding-left: 10px; padding-right: 10px"> | ||||
|         <el-form-item prop="code"> | ||||
|           <el-row justify="space-between" style="width: 100%" :gutter="5"> | ||||
|           <el-row :gutter="5" justify="space-between" style="width: 100%"> | ||||
|             <el-col :span="24"> | ||||
|               <el-input | ||||
|                 v-model="loginData.loginForm.code" | ||||
|  | @ -51,9 +51,9 @@ | |||
|                 <template #append> | ||||
|                   <span | ||||
|                     v-if="mobileCodeTimer <= 0" | ||||
|                     @click="getSmsCode" | ||||
|                     class="getMobileCode" | ||||
|                     style="cursor: pointer" | ||||
|                     @click="getSmsCode" | ||||
|                   > | ||||
|                     {{ t('login.getSmsCode') }} | ||||
|                   </span> | ||||
|  | @ -72,9 +72,9 @@ | |||
|         <el-form-item> | ||||
|           <XButton | ||||
|             :loading="loginLoading" | ||||
|             type="primary" | ||||
|             class="w-[100%]" | ||||
|             :title="t('login.login')" | ||||
|             class="w-[100%]" | ||||
|             type="primary" | ||||
|             @click="signIn()" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|  | @ -83,8 +83,8 @@ | |||
|         <el-form-item> | ||||
|           <XButton | ||||
|             :loading="loginLoading" | ||||
|             class="w-[100%]" | ||||
|             :title="t('login.backLogin')" | ||||
|             class="w-[100%]" | ||||
|             @click="handleBackLogin()" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|  | @ -92,7 +92,7 @@ | |||
|     </el-row> | ||||
|   </el-form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="MobileForm" setup> | ||||
| import type { RouteLocationNormalizedLoaded } from 'vue-router' | ||||
| 
 | ||||
| import { useIcon } from '@/hooks/web/useIcon' | ||||
|  | @ -101,7 +101,7 @@ import { setTenantId, setToken } from '@/utils/auth' | |||
| import { usePermissionStore } from '@/store/modules/permission' | ||||
| import { getTenantIdByName, sendSmsCode, smsLogin } from '@/api/login' | ||||
| import LoginFormTitle from './LoginFormTitle.vue' | ||||
| import { useLoginState, LoginStateEnum, useFormValid } from './useLogin' | ||||
| import { LoginStateEnum, useFormValid, useLoginState } from './useLogin' | ||||
| 
 | ||||
| const { t } = useI18n() | ||||
| const message = useMessage() | ||||
|  |  | |||
|  | @ -4,23 +4,23 @@ | |||
|       <LoginFormTitle style="width: 100%" /> | ||||
|     </el-col> | ||||
|     <el-col :span="24" style="padding-left: 10px; padding-right: 10px"> | ||||
|       <el-card shadow="hover" class="mb-10px text-center"> | ||||
|       <el-card class="mb-10px text-center" shadow="hover"> | ||||
|         <Qrcode :logo="logoImg" /> | ||||
|       </el-card> | ||||
|     </el-col> | ||||
|     <el-divider class="enter-x">{{ t('login.qrcode') }}</el-divider> | ||||
|     <el-col :span="24" style="padding-left: 10px; padding-right: 10px"> | ||||
|       <div class="w-[100%] mt-15px"> | ||||
|         <XButton class="w-[100%]" :title="t('login.backLogin')" @click="handleBackLogin()" /> | ||||
|         <XButton :title="t('login.backLogin')" class="w-[100%]" @click="handleBackLogin()" /> | ||||
|       </div> | ||||
|     </el-col> | ||||
|   </el-row> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="QrCodeForm" setup> | ||||
| import logoImg from '@/assets/imgs/logo.png' | ||||
| 
 | ||||
| import LoginFormTitle from './LoginFormTitle.vue' | ||||
| import { useLoginState, LoginStateEnum } from './useLogin' | ||||
| import { LoginStateEnum, useLoginState } from './useLogin' | ||||
| 
 | ||||
| const { t } = useI18n() | ||||
| const { handleBackLogin, getLoginState } = useLoginState() | ||||
|  |  | |||
|  | @ -1,12 +1,12 @@ | |||
| <template> | ||||
|   <Form | ||||
|     :schema="schema" | ||||
|     :rules="rules" | ||||
|     label-position="top" | ||||
|     hide-required-asterisk | ||||
|     size="large" | ||||
|     v-show="getShow" | ||||
|     :rules="rules" | ||||
|     :schema="schema" | ||||
|     class="dark:(border-1 border-[var(--el-border-color)] border-solid)" | ||||
|     hide-required-asterisk | ||||
|     label-position="top" | ||||
|     size="large" | ||||
|     @register="register" | ||||
|   > | ||||
|     <template #title> | ||||
|  | @ -23,25 +23,25 @@ | |||
|       <div class="w-[100%]"> | ||||
|         <XButton | ||||
|           :loading="loading" | ||||
|           type="primary" | ||||
|           class="w-[100%]" | ||||
|           :title="t('login.register')" | ||||
|           class="w-[100%]" | ||||
|           type="primary" | ||||
|           @click="loginRegister()" | ||||
|         /> | ||||
|       </div> | ||||
|       <div class="w-[100%] mt-15px"> | ||||
|         <XButton class="w-[100%]" :title="t('login.hasUser')" @click="handleBackLogin()" /> | ||||
|         <XButton :title="t('login.hasUser')" class="w-[100%]" @click="handleBackLogin()" /> | ||||
|       </div> | ||||
|     </template> | ||||
|   </Form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="RegisterForm" setup> | ||||
| import type { FormRules } from 'element-plus' | ||||
| 
 | ||||
| import { useForm } from '@/hooks/web/useForm' | ||||
| import { useValidator } from '@/hooks/web/useValidator' | ||||
| import LoginFormTitle from './LoginFormTitle.vue' | ||||
| import { useLoginState, LoginStateEnum } from './useLogin' | ||||
| import { LoginStateEnum, useLoginState } from './useLogin' | ||||
| import { FormSchema } from '@/types/form' | ||||
| 
 | ||||
| const { t } = useI18n() | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
|   <Form ref="formRef" :rules="rules" :schema="schema" :labelWidth="80"> | ||||
|   <Form ref="formRef" :labelWidth="80" :rules="rules" :schema="schema"> | ||||
|     <template #sex="form"> | ||||
|       <el-radio-group v-model="form['sex']"> | ||||
|         <el-radio :label="1">{{ t('profile.user.man') }}</el-radio> | ||||
|  | @ -8,9 +8,9 @@ | |||
|     </template> | ||||
|   </Form> | ||||
|   <XButton :title="t('common.save')" @click="submit()" /> | ||||
|   <XButton type="danger" :title="t('common.reset')" @click="init()" /> | ||||
|   <XButton :title="t('common.reset')" type="danger" @click="init()" /> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="BasicInfo" setup> | ||||
| import type { FormRules } from 'element-plus' | ||||
| import { ElMessage } from 'element-plus' | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,41 +5,48 @@ | |||
|     </div> | ||||
|     <ul class="list-group list-group-striped"> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:user" class="mr-5px" />{{ t('profile.user.username') }} | ||||
|         <Icon class="mr-5px" icon="ep:user" /> | ||||
|         {{ t('profile.user.username') }} | ||||
|         <div class="pull-right">{{ userInfo?.username }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:phone" class="mr-5px" />{{ t('profile.user.mobile') }} | ||||
|         <Icon class="mr-5px" icon="ep:phone" /> | ||||
|         {{ t('profile.user.mobile') }} | ||||
|         <div class="pull-right">{{ userInfo?.mobile }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="fontisto:email" class="mr-5px" />{{ t('profile.user.email') }} | ||||
|         <Icon class="mr-5px" icon="fontisto:email" /> | ||||
|         {{ t('profile.user.email') }} | ||||
|         <div class="pull-right">{{ userInfo?.email }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="carbon:tree-view-alt" class="mr-5px" />{{ t('profile.user.dept') }} | ||||
|         <div class="pull-right" v-if="userInfo?.dept">{{ userInfo?.dept.name }}</div> | ||||
|         <Icon class="mr-5px" icon="carbon:tree-view-alt" /> | ||||
|         {{ t('profile.user.dept') }} | ||||
|         <div v-if="userInfo?.dept" class="pull-right">{{ userInfo?.dept.name }}</div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:suitcase" class="mr-5px" />{{ t('profile.user.posts') }} | ||||
|         <div class="pull-right" v-if="userInfo?.posts"> | ||||
|         <Icon class="mr-5px" icon="ep:suitcase" /> | ||||
|         {{ t('profile.user.posts') }} | ||||
|         <div v-if="userInfo?.posts" class="pull-right"> | ||||
|           {{ userInfo?.posts.map((post) => post.name).join(',') }} | ||||
|         </div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="icon-park-outline:peoples" class="mr-5px" />{{ t('profile.user.roles') }} | ||||
|         <div class="pull-right" v-if="userInfo?.roles"> | ||||
|         <Icon class="mr-5px" icon="icon-park-outline:peoples" /> | ||||
|         {{ t('profile.user.roles') }} | ||||
|         <div v-if="userInfo?.roles" class="pull-right"> | ||||
|           {{ userInfo?.roles.map((role) => role.name).join(',') }} | ||||
|         </div> | ||||
|       </li> | ||||
|       <li class="list-group-item"> | ||||
|         <Icon icon="ep:calendar" class="mr-5px" />{{ t('profile.user.createTime') }} | ||||
|         <Icon class="mr-5px" icon="ep:calendar" /> | ||||
|         {{ t('profile.user.createTime') }} | ||||
|         <div class="pull-right">{{ formatDate(userInfo?.createTime) }}</div> | ||||
|       </li> | ||||
|     </ul> | ||||
|   </div> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ProfileUser" setup> | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import UserAvatar from './UserAvatar.vue' | ||||
| 
 | ||||
|  | @ -62,6 +69,7 @@ onMounted(async () => { | |||
|   position: relative; | ||||
|   height: 120px; | ||||
| } | ||||
| 
 | ||||
| .list-group-striped > .list-group-item { | ||||
|   border-left: 0; | ||||
|   border-right: 0; | ||||
|  | @ -82,6 +90,7 @@ onMounted(async () => { | |||
|   padding: 11px 0px; | ||||
|   font-size: 13px; | ||||
| } | ||||
| 
 | ||||
| .pull-right { | ||||
|   float: right !important; | ||||
| } | ||||
|  |  | |||
|  | @ -10,13 +10,13 @@ | |||
|       <InputPassword v-model="password.confirmPassword" strength /> | ||||
|     </el-form-item> | ||||
|     <el-form-item> | ||||
|       <XButton type="primary" @click="submit(formRef)" :title="t('common.save')" /> | ||||
|       <XButton type="danger" :title="t('common.reset')" @click="reset(formRef)" /> | ||||
|       <XButton :title="t('common.save')" type="primary" @click="submit(formRef)" /> | ||||
|       <XButton :title="t('common.reset')" type="danger" @click="reset(formRef)" /> | ||||
|     </el-form-item> | ||||
|   </el-form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import type { FormRules, FormInstance } from 'element-plus' | ||||
| <script lang="ts" name="ResetPwd" setup> | ||||
| import type { FormInstance, FormRules } from 'element-plus' | ||||
| 
 | ||||
| import { InputPassword } from '@/components/InputPassword' | ||||
| import { updateUserPassword } from '@/api/system/user/profile' | ||||
|  |  | |||
|  | @ -2,17 +2,18 @@ | |||
|   <div class="change-avatar"> | ||||
|     <CropperAvatar | ||||
|       ref="cropperRef" | ||||
|       :value="avatar" | ||||
|       :showBtn="false" | ||||
|       @change="handelUpload" | ||||
|       :btnProps="{ preIcon: 'ant-design:cloud-upload-outlined' }" | ||||
|       :showBtn="false" | ||||
|       :value="avatar" | ||||
|       width="120px" | ||||
|       @change="handelUpload" | ||||
|     /> | ||||
|   </div> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="UserAvatar" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { uploadAvatar } from '@/api/system/user/profile' | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|   img: propTypes.string.def('') | ||||
| }) | ||||
|  | @ -27,7 +28,7 @@ const handelUpload = async ({ data }) => { | |||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style scoped lang="scss"> | ||||
| <style lang="scss" scoped> | ||||
| .change-avatar { | ||||
|   img { | ||||
|     display: block; | ||||
|  |  | |||
|  | @ -1,30 +1,30 @@ | |||
| <template> | ||||
|   <el-table :data="socialUsers" :show-header="false"> | ||||
|     <el-table-column type="seq" title="序号" width="60" fixed="left" /> | ||||
|     <el-table-column label="社交平台" align="left" width="120"> | ||||
|     <el-table-column fixed="left" title="序号" type="seq" width="60" /> | ||||
|     <el-table-column align="left" label="社交平台" width="120"> | ||||
|       <template #default="{ row }"> | ||||
|         <img class="h-5 align-middle" :src="row.img" alt="" /> | ||||
|         <img :src="row.img" alt="" class="h-5 align-middle" /> | ||||
|         <p class="mr-5">{{ row.title }}</p> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="操作" align="center"> | ||||
|     <el-table-column align="center" label="操作"> | ||||
|       <template #default="{ row }"> | ||||
|         <template v-if="row.openid"> | ||||
|           已绑定 | ||||
|           <XTextButton type="primary" class="mr-5" @click="unbind(row)" title="(解绑)" /> | ||||
|           <XTextButton class="mr-5" title="(解绑)" type="primary" @click="unbind(row)" /> | ||||
|         </template> | ||||
|         <template v-else> | ||||
|           未绑定 | ||||
|           <XTextButton type="primary" class="mr-5" @click="bind(row)" title="(绑定)" /> | ||||
|           <XTextButton class="mr-5" title="(绑定)" type="primary" @click="bind(row)" /> | ||||
|         </template> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|   </el-table> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="UserSocial" setup> | ||||
| import { SystemUserSocialTypeEnum } from '@/utils/constants' | ||||
| import { getUserProfile, ProfileVO } from '@/api/system/user/profile' | ||||
| import { socialAuthRedirect, socialUnbind } from '@/api/system/user/socialUser' | ||||
| import { socialAuthRedirect, socialBind, socialUnbind } from '@/api/system/user/socialUser' | ||||
| 
 | ||||
| const message = useMessage() | ||||
| const socialUsers = ref<any[]>([]) | ||||
|  | @ -46,11 +46,25 @@ const initSocial = async () => { | |||
|     } | ||||
|   } | ||||
| } | ||||
| const route = useRoute() | ||||
| const bindSocial = () => { | ||||
|   // 社交绑定 | ||||
|   const type = route.query.type | ||||
|   const code = route.query.code | ||||
|   const state = route.query.state | ||||
|   if (!code) { | ||||
|     return | ||||
|   } | ||||
|   socialBind(type, code, state).then(() => { | ||||
|     message.success('绑定成功') | ||||
|     initSocial() | ||||
|   }) | ||||
| } | ||||
| const bind = (row) => { | ||||
|   const redirectUri = location.origin + '/user/profile?type=' + row.type | ||||
|   // 进行跳转 | ||||
|   socialAuthRedirect(row.type, encodeURIComponent(redirectUri)).then((res) => { | ||||
|     window.location.href = res.data | ||||
|     window.location.href = res | ||||
|   }) | ||||
| } | ||||
| const unbind = async (row) => { | ||||
|  | @ -64,4 +78,15 @@ const unbind = async (row) => { | |||
| onMounted(async () => { | ||||
|   await initSocial() | ||||
| }) | ||||
| 
 | ||||
| watch( | ||||
|   () => route, | ||||
|   (newRoute) => { | ||||
|     bindSocial() | ||||
|     console.log(newRoute) | ||||
|   }, | ||||
|   { | ||||
|     immediate: true | ||||
|   } | ||||
| ) | ||||
| </script> | ||||
|  |  | |||
|  | @ -4,14 +4,15 @@ | |||
|     <fc-designer ref="designer" height="780px"> | ||||
|       <template #handle> | ||||
|         <el-button round size="small" type="primary" @click="handleSave"> | ||||
|           <Icon icon="ep:plus" class="mr-5px" /> 保存 | ||||
|           <Icon class="mr-5px" icon="ep:plus" /> | ||||
|           保存 | ||||
|         </el-button> | ||||
|       </template> | ||||
|     </fc-designer> | ||||
|   </ContentWrap> | ||||
| 
 | ||||
|   <!-- 表单保存的弹窗 --> | ||||
|   <Dialog title="保存表单" v-model="dialogVisible" width="600"> | ||||
|   <Dialog v-model="dialogVisible" title="保存表单" width="600"> | ||||
|     <el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px"> | ||||
|       <el-form-item label="表单名" prop="name"> | ||||
|         <el-input v-model="formData.name" placeholder="请输入表单名" /> | ||||
|  | @ -28,16 +29,16 @@ | |||
|         </el-radio-group> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="备注" prop="remark"> | ||||
|         <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" /> | ||||
|         <el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" /> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="BpmFormEditor" setup> | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import { CommonStatusEnum } from '@/utils/constants' | ||||
| import * as FormApi from '@/api/bpm/form' | ||||
|  |  | |||
|  | @ -1,17 +1,17 @@ | |||
| <template> | ||||
|   <Dialog :title="dialogTitle" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="100px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="组名" prop="name"> | ||||
|         <el-input v-model="formData.name" placeholder="请输入组名" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="描述"> | ||||
|         <el-input type="textarea" v-model="formData.name" placeholder="请输入描述" /> | ||||
|         <el-input v-model="formData.name" placeholder="请输入描述" type="textarea" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="成员" prop="memberUserIds"> | ||||
|         <el-select v-model="formData.memberUserIds" multiple placeholder="请选择成员"> | ||||
|  | @ -36,12 +36,12 @@ | |||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="UserGroupForm" setup> | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import { CommonStatusEnum } from '@/utils/constants' | ||||
| import * as UserGroupApi from '@/api/bpm/userGroup' | ||||
|  |  | |||
|  | @ -1,45 +1,45 @@ | |||
| <template> | ||||
|   <Dialog :title="dialogTitle" v-model="dialogVisible" width="600"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle" width="600"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="110px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="流程标识" prop="key"> | ||||
|         <el-input | ||||
|           v-model="formData.key" | ||||
|           :disabled="!!formData.id" | ||||
|           placeholder="请输入流标标识" | ||||
|           style="width: 330px" | ||||
|           :disabled="!!formData.id" | ||||
|         /> | ||||
|         <el-tooltip | ||||
|           v-if="!formData.id" | ||||
|           class="item" | ||||
|           effect="light" | ||||
|           content="新建后,流程标识不可修改!" | ||||
|           effect="light" | ||||
|           placement="top" | ||||
|         > | ||||
|           <i style="padding-left: 5px" class="el-icon-question"></i> | ||||
|           <i class="el-icon-question" style="padding-left: 5px"></i> | ||||
|         </el-tooltip> | ||||
|         <el-tooltip v-else class="item" effect="light" content="流程标识不可修改!" placement="top"> | ||||
|           <i style="padding-left: 5px" class="el-icon-question"></i> | ||||
|         <el-tooltip v-else class="item" content="流程标识不可修改!" effect="light" placement="top"> | ||||
|           <i class="el-icon-question" style="padding-left: 5px"></i> | ||||
|         </el-tooltip> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="流程名称" prop="name"> | ||||
|         <el-input | ||||
|           v-model="formData.name" | ||||
|           placeholder="请输入流程名称" | ||||
|           :disabled="!!formData.id" | ||||
|           clearable | ||||
|           placeholder="请输入流程名称" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item v-if="formData.id" label="流程分类" prop="category"> | ||||
|         <el-select | ||||
|           v-model="formData.category" | ||||
|           placeholder="请选择流程分类" | ||||
|           clearable | ||||
|           placeholder="请选择流程分类" | ||||
|           style="width: 100%" | ||||
|         > | ||||
|           <el-option | ||||
|  | @ -51,7 +51,7 @@ | |||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="流程描述" prop="description"> | ||||
|         <el-input type="textarea" v-model="formData.description" clearable /> | ||||
|         <el-input v-model="formData.description" clearable type="textarea" /> | ||||
|       </el-form-item> | ||||
|       <div v-if="formData.id"> | ||||
|         <el-form-item label="表单类型" prop="formType"> | ||||
|  | @ -87,11 +87,11 @@ | |||
|           /> | ||||
|           <el-tooltip | ||||
|             class="item" | ||||
|             effect="light" | ||||
|             content="自定义表单的提交路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/create" | ||||
|             effect="light" | ||||
|             placement="top" | ||||
|           > | ||||
|             <i style="padding-left: 5px" class="el-icon-question"></i> | ||||
|             <i class="el-icon-question" style="padding-left: 5px"></i> | ||||
|           </el-tooltip> | ||||
|         </el-form-item> | ||||
|         <el-form-item | ||||
|  | @ -106,26 +106,27 @@ | |||
|           /> | ||||
|           <el-tooltip | ||||
|             class="item" | ||||
|             effect="light" | ||||
|             content="自定义表单的查看路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/view" | ||||
|             effect="light" | ||||
|             placement="top" | ||||
|           > | ||||
|             <i style="padding-left: 5px" class="el-icon-question"></i> | ||||
|             <i class="el-icon-question" style="padding-left: 5px"></i> | ||||
|           </el-tooltip> | ||||
|         </el-form-item> | ||||
|       </div> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ModelForm" setup> | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import { ElMessageBox } from 'element-plus' | ||||
| import * as ModelApi from '@/api/bpm/model' | ||||
| import * as FormApi from '@/api/bpm/form' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,24 +1,24 @@ | |||
| <template> | ||||
|   <Dialog title="导入流程" v-model="dialogVisible" width="400"> | ||||
|   <Dialog v-model="dialogVisible" title="导入流程" width="400"> | ||||
|     <div> | ||||
|       <el-upload | ||||
|         ref="uploadRef" | ||||
|         :action="importUrl" | ||||
|         :headers="uploadHeaders" | ||||
|         :data="formData" | ||||
|         name="bpmnFile" | ||||
|         v-model:file-list="fileList" | ||||
|         drag | ||||
|         :action="importUrl" | ||||
|         :auto-upload="false" | ||||
|         accept=".bpmn, .xml" | ||||
|         :data="formData" | ||||
|         :disabled="formLoading" | ||||
|         :headers="uploadHeaders" | ||||
|         :limit="1" | ||||
|         :on-error="submitFormError" | ||||
|         :on-exceed="handleExceed" | ||||
|         :on-success="submitFormSuccess" | ||||
|         :on-error="submitFormError" | ||||
|         :disabled="formLoading" | ||||
|         accept=".bpmn, .xml" | ||||
|         drag | ||||
|         name="bpmnFile" | ||||
|       > | ||||
|         <Icon class="el-icon--upload" icon="ep:upload-filled" /> | ||||
|         <div class="el-upload__text"> 将文件拖到此处,或 <em>点击上传</em> </div> | ||||
|         <div class="el-upload__text"> 将文件拖到此处,或 <em>点击上传</em></div> | ||||
|         <template #tip> | ||||
|           <div class="el-upload__tip" style="color: red"> | ||||
|             提示:仅允许导入“bpm”或“xml”格式文件! | ||||
|  | @ -33,10 +33,10 @@ | |||
|                 /> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="流程名称" prop="name"> | ||||
|                 <el-input v-model="formData.name" placeholder="请输入流程名称" clearable /> | ||||
|                 <el-input v-model="formData.name" clearable placeholder="请输入流程名称" /> | ||||
|               </el-form-item> | ||||
|               <el-form-item label="流程描述" prop="description"> | ||||
|                 <el-input type="textarea" v-model="formData.description" clearable /> | ||||
|                 <el-input v-model="formData.description" clearable type="textarea" /> | ||||
|               </el-form-item> | ||||
|             </el-form> | ||||
|           </div> | ||||
|  | @ -44,13 +44,14 @@ | |||
|       </el-upload> | ||||
|     </div> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ModelImportForm" setup> | ||||
| import { getAccessToken, getTenantId } from '@/utils/auth' | ||||
| 
 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
| const dialogVisible = ref(false) // 弹窗的是否展示 | ||||
|  |  | |||
|  | @ -42,7 +42,7 @@ | |||
|     </el-form-item> | ||||
|   </el-form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script setup name="BpmOALeaveCreate" lang="ts"> | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import * as LeaveApi from '@/api/bpm/leave' | ||||
| import { useTagsViewStore } from '@/store/modules/tagsView' | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ | |||
|     </el-descriptions> | ||||
|   </ContentWrap> | ||||
| </template> | ||||
| <script setup lang="ts" name="OALeaveCreate"> | ||||
| <script lang="ts" name="BpmOALeaveDetail" setup> | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
|  |  | |||
|  | @ -1,20 +1,20 @@ | |||
| <template> | ||||
|   <el-card class="box-card" v-loading="loading"> | ||||
|   <el-card v-loading="loading" class="box-card"> | ||||
|     <template #header> | ||||
|       <span class="el-icon-picture-outline">流程图</span> | ||||
|     </template> | ||||
|     <my-process-viewer | ||||
|       key="designer" | ||||
|       :value="bpmnXml" | ||||
|       v-bind="bpmnControlForm" | ||||
|       :prefix="bpmnControlForm.prefix" | ||||
|       :activityData="activityList" | ||||
|       :prefix="bpmnControlForm.prefix" | ||||
|       :processInstanceData="processInstance" | ||||
|       :taskData="tasks" | ||||
|       :value="bpmnXml" | ||||
|       v-bind="bpmnControlForm" | ||||
|     /> | ||||
|   </el-card> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="BpmProcessInstanceBpmnViewer" setup> | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import * as ActivityApi from '@/api/bpm/activity' | ||||
| // import * as DefinitionApi from '@/api/bpm/definition' | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| <template> | ||||
|   <el-card class="box-card" v-loading="loading"> | ||||
|   <el-card v-loading="loading" class="box-card"> | ||||
|     <template #header> | ||||
|       <span class="el-icon-picture-outline">审批记录</span> | ||||
|     </template> | ||||
|     <el-col :span="16" :offset="4"> | ||||
|     <el-col :offset="4" :span="16"> | ||||
|       <div class="block"> | ||||
|         <el-timeline> | ||||
|           <el-timeline-item | ||||
|  | @ -16,9 +16,9 @@ | |||
|             <el-card :body-style="{ padding: '10px' }"> | ||||
|               <label v-if="item.assigneeUser" style="font-weight: normal; margin-right: 30px"> | ||||
|                 审批人:{{ item.assigneeUser.nickname }} | ||||
|                 <el-tag type="info" size="small">{{ item.assigneeUser.deptName }}</el-tag> | ||||
|                 <el-tag size="small" type="info">{{ item.assigneeUser.deptName }}</el-tag> | ||||
|               </label> | ||||
|               <label style="font-weight: normal" v-if="item.createTime">创建时间:</label> | ||||
|               <label v-if="item.createTime" style="font-weight: normal">创建时间:</label> | ||||
|               <label style="color: #8a909c; font-weight: normal"> | ||||
|                 {{ formatDate(item?.createTime) }} | ||||
|               </label> | ||||
|  | @ -44,7 +44,7 @@ | |||
|     </el-col> | ||||
|   </el-card> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="BpmProcessInstanceTaskList" setup> | ||||
| import { formatDate, formatPast2 } from '@/utils/formatTime' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| <template> | ||||
|   <Dialog title="转派审批人" v-model="dialogVisible" width="500"> | ||||
|   <Dialog v-model="dialogVisible" title="转派审批人" width="500"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="110px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="新审批人" prop="assigneeUserId"> | ||||
|         <el-select v-model="formData.assigneeUserId" clearable style="width: 100%"> | ||||
|  | @ -19,12 +19,12 @@ | |||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="BpmTaskUpdateAssigneeForm" setup> | ||||
| import * as TaskApi from '@/api/bpm/task' | ||||
| import * as UserApi from '@/api/system/user' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
|   <Dialog title="详情" v-model="dialogVisible" :scroll="true" :max-height="500"> | ||||
|     <el-descriptions border :column="1"> | ||||
|   <Dialog v-model="dialogVisible" :max-height="500" :scroll="true" title="详情"> | ||||
|     <el-descriptions :column="1" border> | ||||
|       <el-descriptions-item label="任务编号" min-width="120"> | ||||
|         {{ detailData.id }} | ||||
|       </el-descriptions-item> | ||||
|  | @ -25,7 +25,7 @@ | |||
|     </el-descriptions> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="BpmTaskDetail" setup> | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import * as TaskApi from '@/api/bpm/task' | ||||
|  |  | |||
|  | @ -2,35 +2,41 @@ | |||
|   <ContentWrap> | ||||
|     <!-- 搜索工作栏 --> | ||||
|     <el-form | ||||
|       class="-mb-15px" | ||||
|       :model="queryParams" | ||||
|       ref="queryFormRef" | ||||
|       :inline="true" | ||||
|       :model="queryParams" | ||||
|       class="-mb-15px" | ||||
|       label-width="68px" | ||||
|     > | ||||
|       <el-form-item label="任务名称" prop="name"> | ||||
|         <el-input | ||||
|           v-model="queryParams.name" | ||||
|           placeholder="请输入任务名称" | ||||
|           clearable | ||||
|           @keyup.enter="handleQuery" | ||||
|           class="!w-240px" | ||||
|           clearable | ||||
|           placeholder="请输入任务名称" | ||||
|           @keyup.enter="handleQuery" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="创建时间" prop="createTime"> | ||||
|         <el-date-picker | ||||
|           v-model="queryParams.createTime" | ||||
|           value-format="YYYY-MM-DD HH:mm:ss" | ||||
|           type="daterange" | ||||
|           start-placeholder="开始日期" | ||||
|           end-placeholder="结束日期" | ||||
|           :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" | ||||
|           class="!w-240px" | ||||
|           end-placeholder="结束日期" | ||||
|           start-placeholder="开始日期" | ||||
|           type="daterange" | ||||
|           value-format="YYYY-MM-DD HH:mm:ss" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> | ||||
|         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> | ||||
|         <el-button @click="handleQuery"> | ||||
|           <Icon class="mr-5px" icon="ep:search" /> | ||||
|           搜索 | ||||
|         </el-button> | ||||
|         <el-button @click="resetQuery"> | ||||
|           <Icon class="mr-5px" icon="ep:refresh" /> | ||||
|           重置 | ||||
|         </el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|   </ContentWrap> | ||||
|  | @ -38,24 +44,24 @@ | |||
|   <!-- 列表 --> | ||||
|   <ContentWrap> | ||||
|     <el-table v-loading="loading" :data="list"> | ||||
|       <el-table-column label="任务编号" align="center" prop="id" width="300px" /> | ||||
|       <el-table-column label="任务名称" align="center" prop="name" /> | ||||
|       <el-table-column label="所属流程" align="center" prop="processInstance.name" /> | ||||
|       <el-table-column label="流程发起人" align="center" prop="processInstance.startUserNickname" /> | ||||
|       <el-table-column label="状态" align="center" prop="result"> | ||||
|       <el-table-column align="center" label="任务编号" prop="id" width="300px" /> | ||||
|       <el-table-column align="center" label="任务名称" prop="name" /> | ||||
|       <el-table-column align="center" label="所属流程" prop="processInstance.name" /> | ||||
|       <el-table-column align="center" label="流程发起人" prop="processInstance.startUserNickname" /> | ||||
|       <el-table-column align="center" label="状态" prop="result"> | ||||
|         <template #default="scope"> | ||||
|           <dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT" :value="scope.row.result" /> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="原因" align="center" prop="reason" /> | ||||
|       <el-table-column align="center" label="原因" prop="reason" /> | ||||
|       <el-table-column | ||||
|         label="创建时间" | ||||
|         :formatter="dateFormatter" | ||||
|         align="center" | ||||
|         label="创建时间" | ||||
|         prop="createTime" | ||||
|         width="180" | ||||
|         :formatter="dateFormatter" | ||||
|       /> | ||||
|       <el-table-column label="操作" align="center"> | ||||
|       <el-table-column align="center" label="操作"> | ||||
|         <template #default="scope"> | ||||
|           <el-button link type="primary" @click="openDetail(scope.row)">详情</el-button> | ||||
|           <el-button link type="primary" @click="handleAudit(scope.row)">流程</el-button> | ||||
|  | @ -64,9 +70,9 @@ | |||
|     </el-table> | ||||
|     <!-- 分页 --> | ||||
|     <Pagination | ||||
|       :total="total" | ||||
|       v-model:page="queryParams.pageNo" | ||||
|       v-model:limit="queryParams.pageSize" | ||||
|       v-model:page="queryParams.pageNo" | ||||
|       :total="total" | ||||
|       @pagination="getList" | ||||
|     /> | ||||
|   </ContentWrap> | ||||
|  | @ -74,11 +80,12 @@ | |||
|   <!-- 表单弹窗:详情 --> | ||||
|   <TaskDetail ref="detailRef" @success="getList" /> | ||||
| </template> | ||||
| <script setup lang="tsx" name="BpmTodoTask"> | ||||
| <script lang="ts" name="BpmTodoTask" setup> | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
| import { dateFormatter } from '@/utils/formatTime' | ||||
| import * as TaskApi from '@/api/bpm/task' | ||||
| import TaskDetail from './TaskDetail.vue' | ||||
| 
 | ||||
| const { push } = useRouter() // 路由 | ||||
| 
 | ||||
| const loading = ref(true) // 列表的加载中 | ||||
|  |  | |||
|  | @ -2,35 +2,41 @@ | |||
|   <ContentWrap> | ||||
|     <!-- 搜索工作栏 --> | ||||
|     <el-form | ||||
|       class="-mb-15px" | ||||
|       :model="queryParams" | ||||
|       ref="queryFormRef" | ||||
|       :inline="true" | ||||
|       :model="queryParams" | ||||
|       class="-mb-15px" | ||||
|       label-width="68px" | ||||
|     > | ||||
|       <el-form-item label="任务名称" prop="name"> | ||||
|         <el-input | ||||
|           v-model="queryParams.name" | ||||
|           placeholder="请输入任务名称" | ||||
|           clearable | ||||
|           @keyup.enter="handleQuery" | ||||
|           class="!w-240px" | ||||
|           clearable | ||||
|           placeholder="请输入任务名称" | ||||
|           @keyup.enter="handleQuery" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="创建时间" prop="createTime"> | ||||
|         <el-date-picker | ||||
|           v-model="queryParams.createTime" | ||||
|           value-format="YYYY-MM-DD HH:mm:ss" | ||||
|           type="daterange" | ||||
|           start-placeholder="开始日期" | ||||
|           end-placeholder="结束日期" | ||||
|           :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" | ||||
|           class="!w-240px" | ||||
|           end-placeholder="结束日期" | ||||
|           start-placeholder="开始日期" | ||||
|           type="daterange" | ||||
|           value-format="YYYY-MM-DD HH:mm:ss" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> | ||||
|         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> | ||||
|         <el-button @click="handleQuery"> | ||||
|           <Icon class="mr-5px" icon="ep:search" /> | ||||
|           搜索 | ||||
|         </el-button> | ||||
|         <el-button @click="resetQuery"> | ||||
|           <Icon class="mr-5px" icon="ep:refresh" /> | ||||
|           重置 | ||||
|         </el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|   </ContentWrap> | ||||
|  | @ -38,24 +44,24 @@ | |||
|   <!-- 列表 --> | ||||
|   <ContentWrap> | ||||
|     <el-table v-loading="loading" :data="list"> | ||||
|       <el-table-column label="任务编号" align="center" prop="id" width="300px" /> | ||||
|       <el-table-column label="任务名称" align="center" prop="name" /> | ||||
|       <el-table-column label="所属流程" align="center" prop="processInstance.name" /> | ||||
|       <el-table-column label="流程发起人" align="center" prop="processInstance.startUserNickname" /> | ||||
|       <el-table-column align="center" label="任务编号" prop="id" width="300px" /> | ||||
|       <el-table-column align="center" label="任务名称" prop="name" /> | ||||
|       <el-table-column align="center" label="所属流程" prop="processInstance.name" /> | ||||
|       <el-table-column align="center" label="流程发起人" prop="processInstance.startUserNickname" /> | ||||
|       <el-table-column | ||||
|         label="创建时间" | ||||
|         :formatter="dateFormatter" | ||||
|         align="center" | ||||
|         label="创建时间" | ||||
|         prop="createTime" | ||||
|         width="180" | ||||
|         :formatter="dateFormatter" | ||||
|       /> | ||||
|       <el-table-column label="任务状态" prop="suspensionState"> | ||||
|         <template #default="scope"> | ||||
|           <el-tag type="success" v-if="scope.row.suspensionState === 1">激活</el-tag> | ||||
|           <el-tag type="warning" v-if="scope.row.suspensionState === 2">挂起</el-tag> | ||||
|           <el-tag v-if="scope.row.suspensionState === 1" type="success">激活</el-tag> | ||||
|           <el-tag v-if="scope.row.suspensionState === 2" type="warning">挂起</el-tag> | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|       <el-table-column label="操作" align="center"> | ||||
|       <el-table-column align="center" label="操作"> | ||||
|         <template #default="scope"> | ||||
|           <el-button link type="primary" @click="handleAudit(scope.row)">审批进度</el-button> | ||||
|         </template> | ||||
|  | @ -63,19 +69,20 @@ | |||
|     </el-table> | ||||
|     <!-- 分页 --> | ||||
|     <Pagination | ||||
|       :total="total" | ||||
|       v-model:page="queryParams.pageNo" | ||||
|       v-model:limit="queryParams.pageSize" | ||||
|       v-model:page="queryParams.pageNo" | ||||
|       :total="total" | ||||
|       @pagination="getList" | ||||
|     /> | ||||
|   </ContentWrap> | ||||
| </template> | ||||
| 
 | ||||
| <script setup lang="tsx" name="BpmDoneTask"> | ||||
| <script lang="ts" name="BpmDoneTask" setup> | ||||
| import { dateFormatter } from '@/utils/formatTime' | ||||
| const { push } = useRouter() // 路由 | ||||
| import * as TaskApi from '@/api/bpm/task' | ||||
| 
 | ||||
| const { push } = useRouter() // 路由 | ||||
| 
 | ||||
| const loading = ref(true) // 列表的加载中 | ||||
| const total = ref(0) // 列表的总页数 | ||||
| const list = ref([]) // 列表的数据 | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| <template> | ||||
|   <Dialog title="修改任务规则" v-model="dialogVisible" width="600"> | ||||
|   <Dialog v-model="dialogVisible" title="修改任务规则" width="600"> | ||||
|     <el-form ref="formRef" :model="formData" :rules="formRules" label-width="80px"> | ||||
|       <el-form-item label="任务名称" prop="taskDefinitionName"> | ||||
|         <el-input v-model="formData.taskDefinitionName" placeholder="请输入流标标识" disabled /> | ||||
|         <el-input v-model="formData.taskDefinitionName" disabled placeholder="请输入流标标识" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="任务标识" prop="taskDefinitionKey"> | ||||
|         <el-input v-model="formData.taskDefinitionKey" placeholder="请输入任务标识" disabled /> | ||||
|         <el-input v-model="formData.taskDefinitionKey" disabled placeholder="请输入任务标识" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="规则类型" prop="type"> | ||||
|         <el-select v-model="formData.type" clearable style="width: 100%"> | ||||
|  | @ -18,7 +18,7 @@ | |||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item v-if="formData.type === 10" label="指定角色" prop="roleIds"> | ||||
|         <el-select v-model="formData.roleIds" multiple clearable style="width: 100%"> | ||||
|         <el-select v-model="formData.roleIds" clearable multiple style="width: 100%"> | ||||
|           <el-option | ||||
|             v-for="item in roleOptions" | ||||
|             :key="item.id" | ||||
|  | @ -28,24 +28,24 @@ | |||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item | ||||
|         v-if="formData.type === 20 || formData.type === 21" | ||||
|         label="指定部门" | ||||
|         prop="deptIds" | ||||
|         span="24" | ||||
|         v-if="formData.type === 20 || formData.type === 21" | ||||
|       > | ||||
|         <el-tree-select | ||||
|           ref="treeRef" | ||||
|           v-model="formData.deptIds" | ||||
|           node-key="id" | ||||
|           show-checkbox | ||||
|           :props="defaultProps" | ||||
|           :data="deptTreeOptions" | ||||
|           :props="defaultProps" | ||||
|           empty-text="加载中,请稍后" | ||||
|           multiple | ||||
|           node-key="id" | ||||
|           show-checkbox | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="指定岗位" prop="postIds" span="24" v-if="formData.type === 22"> | ||||
|         <el-select v-model="formData.postIds" multiple clearable style="width: 100%"> | ||||
|       <el-form-item v-if="formData.type === 22" label="指定岗位" prop="postIds" span="24"> | ||||
|         <el-select v-model="formData.postIds" clearable multiple style="width: 100%"> | ||||
|           <el-option | ||||
|             v-for="item in postOptions" | ||||
|             :key="parseInt(item.id)" | ||||
|  | @ -55,12 +55,12 @@ | |||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item | ||||
|         v-if="formData.type === 30 || formData.type === 31 || formData.type === 32" | ||||
|         label="指定用户" | ||||
|         prop="userIds" | ||||
|         span="24" | ||||
|         v-if="formData.type === 30 || formData.type === 31 || formData.type === 32" | ||||
|       > | ||||
|         <el-select v-model="formData.userIds" multiple clearable style="width: 100%"> | ||||
|         <el-select v-model="formData.userIds" clearable multiple style="width: 100%"> | ||||
|           <el-option | ||||
|             v-for="item in userOptions" | ||||
|             :key="parseInt(item.id)" | ||||
|  | @ -69,8 +69,8 @@ | |||
|           /> | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="指定用户组" prop="userGroupIds" v-if="formData.type === 40"> | ||||
|         <el-select v-model="formData.userGroupIds" multiple clearable style="width: 100%"> | ||||
|       <el-form-item v-if="formData.type === 40" label="指定用户组" prop="userGroupIds"> | ||||
|         <el-select v-model="formData.userGroupIds" clearable multiple style="width: 100%"> | ||||
|           <el-option | ||||
|             v-for="item in userGroupOptions" | ||||
|             :key="parseInt(item.id)" | ||||
|  | @ -79,8 +79,8 @@ | |||
|           /> | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="指定脚本" prop="scripts" v-if="formData.type === 50"> | ||||
|         <el-select v-model="formData.scripts" multiple clearable style="width: 100%"> | ||||
|       <el-form-item v-if="formData.type === 50" label="指定脚本" prop="scripts"> | ||||
|         <el-select v-model="formData.scripts" clearable multiple style="width: 100%"> | ||||
|           <el-option | ||||
|             v-for="dict in taskAssignScriptDictDatas" | ||||
|             :key="dict.value" | ||||
|  | @ -92,20 +92,21 @@ | |||
|     </el-form> | ||||
|     <!-- 操作按钮 --> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="BpmTaskAssignRuleForm" setup> | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import { handleTree, defaultProps } from '@/utils/tree' | ||||
| import { defaultProps, handleTree } from '@/utils/tree' | ||||
| import * as TaskAssignRuleApi from '@/api/bpm/taskAssignRule' | ||||
| import * as RoleApi from '@/api/system/role' | ||||
| import * as DeptApi from '@/api/system/dept' | ||||
| import * as PostApi from '@/api/system/post' | ||||
| import * as UserApi from '@/api/system/user' | ||||
| import * as UserGroupApi from '@/api/bpm/userGroup' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
|   <Dialog title="详情" v-model="dialogVisible" :scroll="true" :max-height="500" width="800"> | ||||
|     <el-descriptions border :column="1"> | ||||
|   <Dialog v-model="dialogVisible" :max-height="500" :scroll="true" title="详情" width="800"> | ||||
|     <el-descriptions :column="1" border> | ||||
|       <el-descriptions-item label="日志主键" min-width="120"> | ||||
|         {{ detailData.id }} | ||||
|       </el-descriptions-item> | ||||
|  | @ -33,14 +33,14 @@ | |||
|       <el-descriptions-item label="操作结果"> | ||||
|         <div v-if="detailData.resultCode === 0">正常</div> | ||||
|         <div v-else-if="detailData.resultCode > 0" | ||||
|           >失败 | {{ detailData.resultCode }} | {{ detailData.resultMsg }}</div | ||||
|         > | ||||
|           >失败 | {{ detailData.resultCode }} | {{ detailData.resultMsg }} | ||||
|         </div> | ||||
|       </el-descriptions-item> | ||||
|     </el-descriptions> | ||||
|   </Dialog> | ||||
| </template> | ||||
| 
 | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ApiAccessLogDetail" setup> | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import * as ApiAccessLog from '@/api/infra/apiAccessLog' | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
|   <Dialog title="详情" v-model="dialogVisible" :scroll="true" :max-height="500" width="800"> | ||||
|     <el-descriptions border :column="1"> | ||||
|   <Dialog v-model="dialogVisible" :max-height="500" :scroll="true" title="详情" width="800"> | ||||
|     <el-descriptions :column="1" border> | ||||
|       <el-descriptions-item label="日志主键" min-width="120"> | ||||
|         {{ detailData.id }} | ||||
|       </el-descriptions-item> | ||||
|  | @ -32,12 +32,12 @@ | |||
|       <el-descriptions-item label="异常名"> | ||||
|         {{ detailData.exceptionName }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="异常堆栈" v-if="detailData.exceptionStackTrace"> | ||||
|       <el-descriptions-item v-if="detailData.exceptionStackTrace" label="异常堆栈"> | ||||
|         <el-input | ||||
|           type="textarea" | ||||
|           :readonly="true" | ||||
|           :autosize="{ maxRows: 20 }" | ||||
|           v-model="detailData.exceptionStackTrace" | ||||
|           :autosize="{ maxRows: 20 }" | ||||
|           :readonly="true" | ||||
|           type="textarea" | ||||
|         /> | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="处理状态"> | ||||
|  | @ -46,16 +46,16 @@ | |||
|           :value="detailData.processStatus" | ||||
|         /> | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="处理人" v-if="detailData.processUserId"> | ||||
|       <el-descriptions-item v-if="detailData.processUserId" label="处理人"> | ||||
|         {{ detailData.processUserId }} | ||||
|       </el-descriptions-item> | ||||
|       <el-descriptions-item label="处理时间" v-if="detailData.processTime"> | ||||
|       <el-descriptions-item v-if="detailData.processTime" label="处理时间"> | ||||
|         {{ formatDate(detailData.processTime) }} | ||||
|       </el-descriptions-item> | ||||
|     </el-descriptions> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ApiErrorLogDetail" setup> | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import * as ApiErrorLog from '@/api/infra/apiErrorLog' | ||||
|  |  | |||
|  | @ -13,16 +13,17 @@ | |||
|     </el-tabs> | ||||
|     <el-form> | ||||
|       <el-form-item style="float: right"> | ||||
|         <el-button type="primary" @click="submitForm" :loading="formLoading">保存</el-button> | ||||
|         <el-button :loading="formLoading" type="primary" @click="submitForm">保存</el-button> | ||||
|         <el-button @click="close">返回</el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|   </ContentWrap> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraCodegenEditTable" setup> | ||||
| import { useTagsViewStore } from '@/store/modules/tagsView' | ||||
| import { BasicInfoForm, ColumInfoForm, GenerateInfoForm } from './components' | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| const { push, currentRoute } = useRouter() // 路由 | ||||
|  |  | |||
|  | @ -1,12 +1,12 @@ | |||
| <template> | ||||
|   <Dialog title="导入表" v-model="dialogVisible" width="800px"> | ||||
|   <Dialog v-model="dialogVisible" title="导入表" width="800px"> | ||||
|     <!-- 搜索栏 --> | ||||
|     <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px"> | ||||
|     <el-form ref="queryFormRef" :inline="true" :model="queryParams" label-width="68px"> | ||||
|       <el-form-item label="数据源" prop="dataSourceConfigId"> | ||||
|         <el-select | ||||
|           v-model="queryParams.dataSourceConfigId" | ||||
|           placeholder="请选择数据源" | ||||
|           class="!w-240px" | ||||
|           placeholder="请选择数据源" | ||||
|         > | ||||
|           <el-option | ||||
|             v-for="config in dataSourceConfigList" | ||||
|  | @ -19,54 +19,61 @@ | |||
|       <el-form-item label="表名称" prop="name"> | ||||
|         <el-input | ||||
|           v-model="queryParams.name" | ||||
|           placeholder="请输入表名称" | ||||
|           clearable | ||||
|           @keyup.enter="getList" | ||||
|           class="!w-240px" | ||||
|           clearable | ||||
|           placeholder="请输入表名称" | ||||
|           @keyup.enter="getList" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="表描述" prop="comment"> | ||||
|         <el-input | ||||
|           v-model="queryParams.comment" | ||||
|           placeholder="请输入表描述" | ||||
|           clearable | ||||
|           @keyup.enter="getList" | ||||
|           class="!w-240px" | ||||
|           clearable | ||||
|           placeholder="请输入表描述" | ||||
|           @keyup.enter="getList" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <el-button @click="getList"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> | ||||
|         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> | ||||
|         <el-button @click="getList"> | ||||
|           <Icon class="mr-5px" icon="ep:search" /> | ||||
|           搜索 | ||||
|         </el-button> | ||||
|         <el-button @click="resetQuery"> | ||||
|           <Icon class="mr-5px" icon="ep:refresh" /> | ||||
|           重置 | ||||
|         </el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <!-- 列表 --> | ||||
|     <el-row> | ||||
|       <el-table | ||||
|         v-loading="dbTableLoading" | ||||
|         @row-click="handleRowClick" | ||||
|         ref="tableRef" | ||||
|         v-loading="dbTableLoading" | ||||
|         :data="dbTableList" | ||||
|         @selection-change="handleSelectionChange" | ||||
|         height="260px" | ||||
|         @row-click="handleRowClick" | ||||
|         @selection-change="handleSelectionChange" | ||||
|       > | ||||
|         <el-table-column type="selection" width="55" /> | ||||
|         <el-table-column prop="name" label="表名称" :show-overflow-tooltip="true" /> | ||||
|         <el-table-column prop="comment" label="表描述" :show-overflow-tooltip="true" /> | ||||
|         <el-table-column :show-overflow-tooltip="true" label="表名称" prop="name" /> | ||||
|         <el-table-column :show-overflow-tooltip="true" label="表描述" prop="comment" /> | ||||
|       </el-table> | ||||
|     </el-row> | ||||
|     <!-- 操作 --> | ||||
|     <template #footer> | ||||
|       <el-button @click="handleImportTable" type="primary" :disabled="tableList.length === 0"> | ||||
|       <el-button :disabled="tableList.length === 0" type="primary" @click="handleImportTable"> | ||||
|         导入 | ||||
|       </el-button> | ||||
|       <el-button @click="close">关闭</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraCodegenImportTable" setup> | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| import * as DataSourceConfigApi from '@/api/infra/dataSourceConfig' | ||||
| import { ElTable } from 'element-plus' | ||||
| 
 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
| const dialogVisible = ref(false) // 弹窗的是否展示 | ||||
|  |  | |||
|  | @ -1,48 +1,48 @@ | |||
| <template> | ||||
|   <Dialog | ||||
|     title="代码预览" | ||||
|     v-model="dialogVisible" | ||||
|     align-center | ||||
|     width="80%" | ||||
|     class="app-infra-codegen-preview-container" | ||||
|     title="代码预览" | ||||
|     width="80%" | ||||
|   > | ||||
|     <div class="flex"> | ||||
|       <!-- 代码目录树 --> | ||||
|       <el-card | ||||
|         class="w-1/3" | ||||
|         :gutter="12" | ||||
|         shadow="hover" | ||||
|         v-loading="loading" | ||||
|         :gutter="12" | ||||
|         class="w-1/3" | ||||
|         element-loading-text="生成文件目录中..." | ||||
|         shadow="hover" | ||||
|       > | ||||
|         <el-scrollbar height="calc(100vh - 88px - 40px)"> | ||||
|           <el-tree | ||||
|             ref="treeRef" | ||||
|             node-key="id" | ||||
|             :data="preview.fileTree" | ||||
|             :expand-on-click-node="false" | ||||
|             highlight-current | ||||
|             @node-click="handleNodeClick" | ||||
|             default-expand-all | ||||
|             highlight-current | ||||
|             node-key="id" | ||||
|             @node-click="handleNodeClick" | ||||
|           /> | ||||
|         </el-scrollbar> | ||||
|       </el-card> | ||||
|       <!-- 代码 --> | ||||
|       <el-card | ||||
|         class="w-2/3 ml-3" | ||||
|         :gutter="12" | ||||
|         shadow="hover" | ||||
|         v-loading="loading" | ||||
|         :gutter="12" | ||||
|         class="w-2/3 ml-3" | ||||
|         element-loading-text="加载代码中..." | ||||
|         shadow="hover" | ||||
|       > | ||||
|         <el-tabs v-model="preview.activeName"> | ||||
|           <el-tab-pane | ||||
|             v-for="item in previewCodegen" | ||||
|             :key="item.filePath" | ||||
|             :label="item.filePath.substring(item.filePath.lastIndexOf('/') + 1)" | ||||
|             :name="item.filePath" | ||||
|             :key="item.filePath" | ||||
|           > | ||||
|             <el-button text type="primary" class="float-right" @click="copy(item.code)"> | ||||
|             <el-button class="float-right" text type="primary" @click="copy(item.code)"> | ||||
|               {{ t('common.copy') }} | ||||
|             </el-button> | ||||
|             <div v-highlight> | ||||
|  | @ -54,10 +54,11 @@ | |||
|     </div> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraCodegenPreviewCode" setup> | ||||
| import { useClipboard } from '@vueuse/core' | ||||
| import { handleTree2 } from '@/utils/tree' | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,12 +3,12 @@ | |||
|     <el-row> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item label="表名称" prop="tableName"> | ||||
|           <el-input placeholder="请输入仓库名称" v-model="formData.tableName" /> | ||||
|           <el-input v-model="formData.tableName" placeholder="请输入仓库名称" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item label="表描述" prop="tableComment"> | ||||
|           <el-input placeholder="请输入" v-model="formData.tableComment" /> | ||||
|           <el-input v-model="formData.tableComment" placeholder="请输入" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|  | @ -20,27 +20,27 @@ | |||
|                 content="默认去除表名的前缀。如果存在重复,则需要手动添加前缀,避免 MyBatis 报 Alias 重复的问题。" | ||||
|                 placement="top" | ||||
|               > | ||||
|                 <Icon icon="ep:question-filled" class="" /> | ||||
|                 <Icon class="" icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-input placeholder="请输入" v-model="formData.className" /> | ||||
|           <el-input v-model="formData.className" placeholder="请输入" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item label="作者" prop="author"> | ||||
|           <el-input placeholder="请输入" v-model="formData.author" /> | ||||
|           <el-input v-model="formData.author" placeholder="请输入" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="24"> | ||||
|         <el-form-item label="备注" prop="remark"> | ||||
|           <el-input type="textarea" :rows="3" v-model="formData.remark" /> | ||||
|           <el-input v-model="formData.remark" :rows="3" type="textarea" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|     </el-row> | ||||
|   </el-form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraCodegenBasicInfoForm" setup> | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| import { PropType } from 'vue' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| <template> | ||||
|   <el-table ref="dragTable" :data="formData" row-key="columnId" :max-height="tableHeight"> | ||||
|   <el-table ref="dragTable" :data="formData" :max-height="tableHeight" row-key="columnId"> | ||||
|     <el-table-column | ||||
|       label="字段列名" | ||||
|       prop="columnName" | ||||
|       min-width="10%" | ||||
|       :show-overflow-tooltip="true" | ||||
|       label="字段列名" | ||||
|       min-width="10%" | ||||
|       prop="columnName" | ||||
|     /> | ||||
|     <el-table-column label="字段描述" min-width="10%"> | ||||
|       <template #default="scope"> | ||||
|  | @ -12,10 +12,10 @@ | |||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column | ||||
|       label="物理类型" | ||||
|       prop="dataType" | ||||
|       min-width="10%" | ||||
|       :show-overflow-tooltip="true" | ||||
|       label="物理类型" | ||||
|       min-width="10%" | ||||
|       prop="dataType" | ||||
|     /> | ||||
|     <el-table-column label="Java类型" min-width="11%"> | ||||
|       <template #default="scope"> | ||||
|  | @ -37,26 +37,26 @@ | |||
|     </el-table-column> | ||||
|     <el-table-column label="插入" min-width="4%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox true-label="true" false-label="false" v-model="scope.row.createOperation" /> | ||||
|         <el-checkbox v-model="scope.row.createOperation" false-label="false" true-label="true" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="编辑" min-width="4%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox true-label="true" false-label="false" v-model="scope.row.updateOperation" /> | ||||
|         <el-checkbox v-model="scope.row.updateOperation" false-label="false" true-label="true" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="列表" min-width="4%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox | ||||
|           true-label="true" | ||||
|           false-label="false" | ||||
|           v-model="scope.row.listOperationResult" | ||||
|           false-label="false" | ||||
|           true-label="true" | ||||
|         /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="查询" min-width="4%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox true-label="true" false-label="false" v-model="scope.row.listOperation" /> | ||||
|         <el-checkbox v-model="scope.row.listOperation" false-label="false" true-label="true" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="查询方式" min-width="10%"> | ||||
|  | @ -75,7 +75,7 @@ | |||
|     </el-table-column> | ||||
|     <el-table-column label="允许空" min-width="5%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox true-label="true" false-label="false" v-model="scope.row.nullable" /> | ||||
|         <el-checkbox v-model="scope.row.nullable" false-label="false" true-label="true" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="显示类型" min-width="12%"> | ||||
|  | @ -112,7 +112,7 @@ | |||
|     </el-table-column> | ||||
|   </el-table> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraCodegenColumInfoForm" setup> | ||||
| import { PropType } from 'vue' | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| import * as DictDataApi from '@/api/system/dict/dict.type' | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
|   <el-form ref="formRef" :model="formData" :rules="rules" label-width="150px"> | ||||
|     <el-row> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="templateType" label="生成模板"> | ||||
|         <el-form-item label="生成模板" prop="templateType"> | ||||
|           <el-select v-model="formData.templateType" @change="tplSelectChange"> | ||||
|             <el-option | ||||
|               v-for="dict in getIntDictOptions(DICT_TYPE.INFRA_CODEGEN_TEMPLATE_TYPE)" | ||||
|  | @ -14,7 +14,7 @@ | |||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="frontType" label="前端类型"> | ||||
|         <el-form-item label="前端类型" prop="frontType"> | ||||
|           <el-select v-model="formData.frontType"> | ||||
|             <el-option | ||||
|               v-for="dict in getIntDictOptions(DICT_TYPE.INFRA_CODEGEN_FRONT_TYPE)" | ||||
|  | @ -27,7 +27,7 @@ | |||
|       </el-col> | ||||
| 
 | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="scene" label="生成场景"> | ||||
|         <el-form-item label="生成场景" prop="scene"> | ||||
|           <el-select v-model="formData.scene"> | ||||
|             <el-option | ||||
|               v-for="dict in getIntDictOptions(DICT_TYPE.INFRA_CODEGEN_SCENE)" | ||||
|  | @ -50,11 +50,11 @@ | |||
|           </template> | ||||
|           <el-tree-select | ||||
|             v-model="formData.parentMenuId" | ||||
|             placeholder="请选择系统菜单" | ||||
|             node-key="id" | ||||
|             check-strictly | ||||
|             :data="menus" | ||||
|             :props="menuTreeProps" | ||||
|             check-strictly | ||||
|             node-key="id" | ||||
|             placeholder="请选择系统菜单" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | @ -148,7 +148,7 @@ | |||
|         </el-form-item> | ||||
|       </el-col> | ||||
| 
 | ||||
|       <el-col :span="24" v-if="formData.genType === '1'"> | ||||
|       <el-col v-if="formData.genType === '1'" :span="24"> | ||||
|         <el-form-item prop="genPath"> | ||||
|           <template #label> | ||||
|             <span> | ||||
|  | @ -291,8 +291,8 @@ | |||
|     </el-row> | ||||
|   </el-form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { getIntDictOptions, DICT_TYPE } from '@/utils/dict' | ||||
| <script lang="ts" name="InfraCodegenGenerateInfoForm" setup> | ||||
| import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' | ||||
| import { handleTree } from '@/utils/tree' | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| import * as MenuApi from '@/api/system/menu' | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| <template> | ||||
|   <Dialog :title="dialogTitle" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="80px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="参数分类" prop="category"> | ||||
|         <el-input v-model="formData.category" placeholder="请输入参数分类" /> | ||||
|  | @ -31,16 +31,16 @@ | |||
|         </el-radio-group> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="备注" prop="remark"> | ||||
|         <el-input v-model="formData.remark" type="textarea" placeholder="请输入内容" /> | ||||
|         <el-input v-model="formData.remark" placeholder="请输入内容" type="textarea" /> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraConfigForm" setup> | ||||
| import { DICT_TYPE, getBoolDictOptions } from '@/utils/dict' | ||||
| import * as ConfigApi from '@/api/infra/config' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| <template> | ||||
|   <Dialog :title="dialogTitle" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="100px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="数据源名称" prop="name"> | ||||
|         <el-input v-model="formData.name" placeholder="请输入参数名称" /> | ||||
|  | @ -21,12 +21,12 @@ | |||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraDataSourceConfigForm" setup> | ||||
| import * as DataSourceConfigApi from '@/api/infra/dataSourceConfig' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
|  |  | |||
|  | @ -1,23 +1,23 @@ | |||
| <template> | ||||
|   <Dialog title="上传文件" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" title="上传文件"> | ||||
|     <el-upload | ||||
|       ref="uploadRef" | ||||
|       :action="url" | ||||
|       :data="data" | ||||
|       :headers="uploadHeaders" | ||||
|       v-model:file-list="fileList" | ||||
|       drag | ||||
|       accept=".jpg, .png, .gif" | ||||
|       :limit="1" | ||||
|       :on-success="submitFormSuccess" | ||||
|       :on-exceed="handleExceed" | ||||
|       :on-error="submitFormError" | ||||
|       :on-change="handleFileChange" | ||||
|       :action="url" | ||||
|       :auto-upload="false" | ||||
|       :data="data" | ||||
|       :disabled="formLoading" | ||||
|       :headers="uploadHeaders" | ||||
|       :limit="1" | ||||
|       :on-change="handleFileChange" | ||||
|       :on-error="submitFormError" | ||||
|       :on-exceed="handleExceed" | ||||
|       :on-success="submitFormSuccess" | ||||
|       accept=".jpg, .png, .gif" | ||||
|       drag | ||||
|     > | ||||
|       <i class="el-icon-upload"></i> | ||||
|       <div class="el-upload__text"> 将文件拖到此处,或 <em>点击上传</em> </div> | ||||
|       <div class="el-upload__text"> 将文件拖到此处,或 <em>点击上传</em></div> | ||||
|       <template #tip> | ||||
|         <div class="el-upload__tip" style="color: red"> | ||||
|           提示:仅允许导入 jpg、png、gif 格式文件! | ||||
|  | @ -25,13 +25,14 @@ | |||
|       </template> | ||||
|     </el-upload> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitFileForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitFileForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraFileForm" setup> | ||||
| import { getAccessToken, getTenantId } from '@/utils/auth' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| <template> | ||||
|   <Dialog :title="dialogTitle" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="120px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="配置名" prop="name"> | ||||
|         <el-input v-model="formData.name" placeholder="请输入配置名" /> | ||||
|  | @ -16,8 +16,8 @@ | |||
|       <el-form-item label="存储器" prop="storage"> | ||||
|         <el-select | ||||
|           v-model="formData.storage" | ||||
|           placeholder="请选择存储器" | ||||
|           :disabled="formData.id !== undefined" | ||||
|           placeholder="请选择存储器" | ||||
|         > | ||||
|           <el-option | ||||
|             v-for="dict in getDictOptions(DICT_TYPE.INFRA_FILE_STORAGE)" | ||||
|  | @ -48,7 +48,7 @@ | |||
|         label="主机端口" | ||||
|         prop="config.port" | ||||
|       > | ||||
|         <el-input-number :min="0" v-model="formData.config.port" placeholder="请输入主机端口" /> | ||||
|         <el-input-number v-model="formData.config.port" :min="0" placeholder="请输入主机端口" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item | ||||
|         v-if="formData.storage >= 11 && formData.storage <= 12" | ||||
|  | @ -93,14 +93,15 @@ | |||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraFileConfigForm" setup> | ||||
| import { DICT_TYPE, getDictOptions } from '@/utils/dict' | ||||
| import * as FileConfigApi from '@/api/infra/fileConfig' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
|   <Dialog title="任务详细" v-model="dialogVisible" width="700px"> | ||||
|     <el-descriptions border :column="1"> | ||||
|   <Dialog v-model="dialogVisible" title="任务详细" width="700px"> | ||||
|     <el-descriptions :column="1" border> | ||||
|       <el-descriptions-item label="任务编号" min-width="60"> | ||||
|         {{ detailData.id }} | ||||
|       </el-descriptions-item> | ||||
|  | @ -42,7 +42,7 @@ | |||
|     </el-descriptions> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraJobDetail" setup> | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import * as JobApi from '@/api/infra/job' | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
|   <Dialog title="任务详细" v-model="dialogVisible" width="700px"> | ||||
|     <el-descriptions border :column="1"> | ||||
|   <Dialog v-model="dialogVisible" title="任务详细" width="700px"> | ||||
|     <el-descriptions :column="1" border> | ||||
|       <el-descriptions-item label="日志编号" min-width="60"> | ||||
|         {{ detailData.id }} | ||||
|       </el-descriptions-item> | ||||
|  | @ -31,7 +31,7 @@ | |||
|     </el-descriptions> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="JobLogDetail" setup> | ||||
| import { DICT_TYPE } from '@/utils/dict' | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import * as JobLogApi from '@/api/infra/jobLog' | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
|   <div class="flex"> | ||||
|     <el-card class="w-1/2" :gutter="12" shadow="always"> | ||||
|     <el-card :gutter="12" class="w-1/2" shadow="always"> | ||||
|       <template #header> | ||||
|         <div class="card-header"> | ||||
|           <span>连接</span> | ||||
|  | @ -14,7 +14,7 @@ | |||
| 
 | ||||
|       <div class="flex"> | ||||
|         <el-input v-model="server" disabled> | ||||
|           <template #prepend> 服务地址 </template> | ||||
|           <template #prepend> 服务地址</template> | ||||
|         </el-input> | ||||
|         <el-button :type="getIsOpen ? 'danger' : 'primary'" @click="toggle"> | ||||
|           {{ getIsOpen ? '关闭连接' : '开启连接' }} | ||||
|  | @ -25,15 +25,15 @@ | |||
|       <el-input | ||||
|         v-model="sendValue" | ||||
|         :autosize="{ minRows: 2, maxRows: 4 }" | ||||
|         type="textarea" | ||||
|         :disabled="!getIsOpen" | ||||
|         clearable | ||||
|         type="textarea" | ||||
|       /> | ||||
|       <el-button type="primary" block class="mt-4" :disabled="!getIsOpen" @click="handlerSend"> | ||||
|       <el-button :disabled="!getIsOpen" block class="mt-4" type="primary" @click="handlerSend"> | ||||
|         发送 | ||||
|       </el-button> | ||||
|     </el-card> | ||||
|     <el-card class="w-1/2" :gutter="12" shadow="always"> | ||||
|     <el-card :gutter="12" class="w-1/2" shadow="always"> | ||||
|       <template #header> | ||||
|         <div class="card-header"> | ||||
|           <span>消息记录</span> | ||||
|  | @ -41,7 +41,7 @@ | |||
|       </template> | ||||
|       <div class="max-h-80 overflow-auto"> | ||||
|         <ul> | ||||
|           <li v-for="item in getList" class="mt-2" :key="item.time"> | ||||
|           <li v-for="item in getList" :key="item.time" class="mt-2"> | ||||
|             <div class="flex items-center"> | ||||
|               <span class="mr-2 text-primary font-medium">收到消息:</span> | ||||
|               <span>{{ formatDate(item.time) }}</span> | ||||
|  | @ -55,7 +55,7 @@ | |||
|     </el-card> | ||||
|   </div> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="InfraWebSocket" setup> | ||||
| import { formatDate } from '@/utils/formatTime' | ||||
| import { useUserStore } from '@/store/modules/user' | ||||
| import { useWebSocket } from '@vueuse/core' | ||||
|  |  | |||
|  | @ -1,27 +1,28 @@ | |||
| <template> | ||||
|   <Dialog :title="dialogTitle" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="80px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="名称" prop="name"> | ||||
|         <el-input v-model="formData.name" placeholder="请输入名称" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="备注" prop="remark"> | ||||
|         <el-input v-model="formData.remark" type="textarea" placeholder="请输入内容" /> | ||||
|         <el-input v-model="formData.remark" placeholder="请输入内容" type="textarea" /> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ProductPropertyForm" setup> | ||||
| import * as PropertyApi from '@/api/mall/product/property' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| <template> | ||||
|   <Dialog :title="dialogTitle" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="80px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="属性编号" prop="category"> | ||||
|         <el-input v-model="formData.propertyId" disabled="" /> | ||||
|  | @ -14,17 +14,18 @@ | |||
|         <el-input v-model="formData.name" placeholder="请输入名称" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="备注" prop="remark"> | ||||
|         <el-input v-model="formData.remark" type="textarea" placeholder="请输入内容" /> | ||||
|         <el-input v-model="formData.remark" placeholder="请输入内容" type="textarea" /> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="ProductPropertyValueForm" setup> | ||||
| import * as PropertyApi from '@/api/mall/product/property' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| <template> | ||||
|   <Dialog :title="dialogTitle" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="rules" | ||||
|       label-width="120px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="名称" prop="name"> | ||||
|         <el-input v-model="formData.name" placeholder="请输入名称" /> | ||||
|  | @ -59,17 +59,18 @@ | |||
|         <el-input v-model="formData.aesKey" placeholder="请输入消息加解密密钥" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="备注" prop="remark"> | ||||
|         <el-input type="textarea" v-model="formData.remark" placeholder="请输入备注" /> | ||||
|         <el-input v-model="formData.remark" placeholder="请输入备注" type="textarea" /> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="MpAccountForm" setup> | ||||
| import * as AccountApi from '@/api/mp/account' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,13 +9,13 @@ | |||
|   <div class="news-home"> | ||||
|     <div v-for="(article, index) in articles" :key="index" class="news-div"> | ||||
|       <!-- 头条 --> | ||||
|       <a target="_blank" :href="article.url" v-if="index === 0"> | ||||
|       <a v-if="index === 0" :href="article.url" target="_blank"> | ||||
|         <div class="news-main"> | ||||
|           <div class="news-content"> | ||||
|             <el-image | ||||
|               :src="article.picUrl" | ||||
|               class="material-img" | ||||
|               style="width: 100%; height: 120px" | ||||
|               :src="article.picUrl" | ||||
|             /> | ||||
|             <div class="news-content-title"> | ||||
|               <span>{{ article.title }}</span> | ||||
|  | @ -24,12 +24,12 @@ | |||
|         </div> | ||||
|       </a> | ||||
|       <!-- 二条/三条等等 --> | ||||
|       <a target="_blank" :href="article.url" v-else> | ||||
|       <a v-else :href="article.url" target="_blank"> | ||||
|         <div class="news-main-item"> | ||||
|           <div class="news-content-item"> | ||||
|             <div class="news-content-item-title">{{ article.title }}</div> | ||||
|             <div class="news-content-item-img"> | ||||
|               <img class="material-img" :src="article.picUrl" height="100%" /> | ||||
|               <img :src="article.picUrl" class="material-img" height="100%" /> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|  | @ -38,7 +38,7 @@ | |||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="WxNews" setup> | ||||
| const props = defineProps({ | ||||
|   articles: { | ||||
|     type: Array, | ||||
|  | @ -57,15 +57,18 @@ defineExpose({ | |||
|   width: 100%; | ||||
|   margin: auto; | ||||
| } | ||||
| 
 | ||||
| .news-main { | ||||
|   width: 100%; | ||||
|   margin: auto; | ||||
| } | ||||
| 
 | ||||
| .news-content { | ||||
|   background-color: #acadae; | ||||
|   width: 100%; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .news-content-title { | ||||
|   display: inline-block; | ||||
|   font-size: 12px; | ||||
|  | @ -80,14 +83,17 @@ defineExpose({ | |||
|   white-space: normal; | ||||
|   box-sizing: unset !important; | ||||
| } | ||||
| 
 | ||||
| .news-main-item { | ||||
|   background-color: #ffffff; | ||||
|   padding: 5px 0; | ||||
|   border-top: 1px solid #eaeaea; | ||||
| } | ||||
| 
 | ||||
| .news-content-item { | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .news-content-item-title { | ||||
|   display: inline-block; | ||||
|   font-size: 10px; | ||||
|  | @ -95,12 +101,14 @@ defineExpose({ | |||
|   margin-left: 1%; | ||||
|   white-space: normal; | ||||
| } | ||||
| 
 | ||||
| .news-content-item-img { | ||||
|   display: inline-block; | ||||
|   width: 25%; | ||||
|   background-color: #acadae; | ||||
|   margin-right: 1%; | ||||
| } | ||||
| 
 | ||||
| .material-img { | ||||
|   width: 100%; | ||||
| } | ||||
|  |  | |||
|  | @ -1,23 +1,23 @@ | |||
| <template> | ||||
|   <Dialog :title="dialogTitle" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" :title="dialogTitle"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="80px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="标签名称" prop="name"> | ||||
|         <el-input v-model="formData.name" placeholder="请输入标签名称" /> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="MpTagForm" setup> | ||||
| import * as MpTagApi from '@/api/mp/tag' | ||||
| import type { FormInstance, FormRules } from 'element-plus' | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| <template> | ||||
|   <Dialog title="修改" v-model="dialogVisible"> | ||||
|   <Dialog v-model="dialogVisible" title="修改"> | ||||
|     <el-form | ||||
|       ref="formRef" | ||||
|       v-loading="formLoading" | ||||
|       :model="formData" | ||||
|       :rules="formRules" | ||||
|       label-width="80px" | ||||
|       v-loading="formLoading" | ||||
|     > | ||||
|       <el-form-item label="昵称" prop="nickname"> | ||||
|         <el-input v-model="formData.nickname" placeholder="请输入昵称" /> | ||||
|  | @ -14,7 +14,7 @@ | |||
|         <el-input v-model="formData.remark" placeholder="请输入备注" /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="标签" prop="tagIds"> | ||||
|         <el-select v-model="formData.tagIds" multiple clearable placeholder="请选择标签"> | ||||
|         <el-select v-model="formData.tagIds" clearable multiple placeholder="请选择标签"> | ||||
|           <el-option | ||||
|             v-for="item in tagList" | ||||
|             :key="item.tagId" | ||||
|  | @ -25,14 +25,15 @@ | |||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <template #footer> | ||||
|       <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button> | ||||
|       <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|       <el-button @click="dialogVisible = false">取 消</el-button> | ||||
|     </template> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| <script lang="ts" name="MpUserForm" setup> | ||||
| import * as MpTagApi from '@/api/mp/tag' | ||||
| import * as MpUserApi from '@/api/mp/user' | ||||
| 
 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| 
 | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	 YunaiV
						YunaiV