Commit 6f1b9b85 by lijinqi

Merge remote-tracking branch 'origin/develop' into develop

parents dc74c1c1 7f4429c6
...@@ -14,12 +14,12 @@ VITE_APP_TENANT_ENABLE=true ...@@ -14,12 +14,12 @@ VITE_APP_TENANT_ENABLE=true
VITE_APP_CAPTCHA_ENABLE=true VITE_APP_CAPTCHA_ENABLE=true
# 文档地址的开关 # 文档地址的开关
VITE_APP_DOCALERT_ENABLE=true VITE_APP_DOCALERT_ENABLE=false
# 百度统计 # 百度统计
VITE_APP_BAIDU_CODE = a1ff8825baa73c3a78eb96aa40325abc VITE_APP_BAIDU_CODE = a1ff8825baa73c3a78eb96aa40325abc
# 默认账户密码 # 默认账户密码
VITE_APP_DEFAULT_LOGIN_TENANT = 芋道源码 VITE_APP_DEFAULT_LOGIN_TENANT = 湖南大学
VITE_APP_DEFAULT_LOGIN_USERNAME = admin VITE_APP_DEFAULT_LOGIN_USERNAME = admin
VITE_APP_DEFAULT_LOGIN_PASSWORD = admin123 VITE_APP_DEFAULT_LOGIN_PASSWORD = admin123
...@@ -4,7 +4,7 @@ NODE_ENV=development ...@@ -4,7 +4,7 @@ NODE_ENV=development
VITE_DEV=true VITE_DEV=true
# 请求路径 # 请求路径
VITE_BASE_URL='http://localhost:48080' VITE_BASE_URL='https://phsl.lijinqi.com/'
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
VITE_UPLOAD_TYPE=server VITE_UPLOAD_TYPE=server
......
...@@ -181,7 +181,7 @@ function openModal() { ...@@ -181,7 +181,7 @@ function openModal() {
} }
function closeModal() { function closeModal() {
debugger // debugger
dialogVisible.value = false dialogVisible.value = false
} }
......
...@@ -64,25 +64,31 @@ watch( ...@@ -64,25 +64,31 @@ watch(
layout !== 'classic' ? `${prefixCls}__Top` : '', layout !== 'classic' ? `${prefixCls}__Top` : '',
'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative decoration-none overflow-hidden' 'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative decoration-none overflow-hidden'
]" ]"
style="display: flex; align-items: center; justify-content: center"
to="/" to="/"
> >
<img <img
class="h-[calc(var(--logo-height)-10px)] w-[calc(var(--logo-height)-10px)]" class="h-[calc(var(--logo-height)-10px)] w-[calc(var(--logo-height)-10px)]"
src="@/assets/imgs/logo.png" src="@/assets/imgs/xjjt-logo.png"
style="margin-right: 12px;"
/> />
<div <img
v-if="show" class="h-[calc(var(--logo-height)-10px)] w-[calc(var(--logo-height)-10px)]"
:class="[ src="@/assets/imgs/nscc-logo.png"
'ml-10px text-16px font-700', />
{ <!-- <div-->
'text-[var(--logo-title-text-color)]': layout === 'classic', <!-- v-if="show"-->
'text-[var(--top-header-text-color)]': <!-- :class="[-->
layout === 'topLeft' || layout === 'top' || layout === 'cutMenu' <!-- 'ml-10px text-16px font-700',-->
} <!-- {-->
]" <!-- 'text-[var(&#45;&#45;logo-title-text-color)]': layout === 'classic',-->
> <!-- 'text-[var(&#45;&#45;top-header-text-color)]':-->
{{ title }} <!-- layout === 'topLeft' || layout === 'top' || layout === 'cutMenu'-->
</div> <!-- }-->
<!-- ]"-->
<!-- >-->
<!-- {{ title }}-->
<!-- </div>-->
</router-link> </router-link>
</div> </div>
</template> </template>
...@@ -201,6 +201,7 @@ const clear = () => { ...@@ -201,6 +201,7 @@ const clear = () => {
<template> <template>
<div <div
v-if="false"
:class="prefixCls" :class="prefixCls"
class="fixed right-0 top-[45%] h-40px w-40px cursor-pointer bg-[var(--el-color-primary)] text-center leading-40px" class="fixed right-0 top-[45%] h-40px w-40px cursor-pointer bg-[var(--el-color-primary)] text-center leading-40px"
@click="drawer = true" @click="drawer = true"
......
...@@ -51,6 +51,7 @@ const hasTenantVisitPermission = computed( ...@@ -51,6 +51,7 @@ const hasTenantVisitPermission = computed(
export default defineComponent({ export default defineComponent({
name: 'ToolHeader', name: 'ToolHeader',
setup() { setup() {
//73 {hasTenantVisitPermission.value ? <TenantVisit /> : undefined}
return () => ( return () => (
<div <div
id={`${variables.namespace}-tool-header`} id={`${variables.namespace}-tool-header`}
...@@ -69,7 +70,7 @@ export default defineComponent({ ...@@ -69,7 +70,7 @@ export default defineComponent({
</div> </div>
) : undefined} ) : undefined}
<div class="h-full flex items-center"> <div class="h-full flex items-center">
{hasTenantVisitPermission.value ? <TenantVisit /> : undefined} {hasTenantVisitPermission.value ? undefined : undefined}
{screenfull.value ? ( {screenfull.value ? (
<Screenfull class="custom-hover" color="var(--top-header-text-color)"></Screenfull> <Screenfull class="custom-hover" color="var(--top-header-text-color)"></Screenfull>
) : undefined} ) : undefined}
......
...@@ -54,14 +54,14 @@ export const useAppStore = defineStore('app', { ...@@ -54,14 +54,14 @@ export const useAppStore = defineStore('app', {
collapse: false, // 折叠菜单 collapse: false, // 折叠菜单
uniqueOpened: true, // 是否只保持一个子菜单的展开 uniqueOpened: true, // 是否只保持一个子菜单的展开
hamburger: true, // 折叠图标 hamburger: true, // 折叠图标
screenfull: true, // 全屏图标 screenfull: false, // 全屏图标
search: true, // 搜索图标 search: false, // 搜索图标
size: true, // 尺寸图标 size: false, // 尺寸图标
locale: true, // 多语言图标 locale: false, // 多语言图标
message: true, // 消息图标 message: false, // 消息图标
tagsView: true, // 标签页 tagsView: true, // 标签页
tagsViewImmerse: false, // 标签页沉浸 tagsViewImmerse: false, // 标签页沉浸
tagsViewIcon: true, // 是否显示标签图标 tagsViewIcon: false, // 是否显示标签图标
logo: true, // logo logo: true, // logo
fixedHeader: true, // 固定toolheader fixedHeader: true, // 固定toolheader
footer: true, // 显示页脚 footer: true, // 显示页脚
...@@ -77,19 +77,19 @@ export const useAppStore = defineStore('app', { ...@@ -77,19 +77,19 @@ export const useAppStore = defineStore('app', {
// 左侧菜单边框颜色 // 左侧菜单边框颜色
leftMenuBorderColor: 'inherit', leftMenuBorderColor: 'inherit',
// 左侧菜单背景颜色 // 左侧菜单背景颜色
leftMenuBgColor: '#001529', leftMenuBgColor: '#ffffff',
// 左侧菜单浅色背景颜色 // 左侧菜单浅色背景颜色
leftMenuBgLightColor: '#0f2438', leftMenuBgLightColor: '#ffffff',
// 左侧菜单选中背景颜色 // 左侧菜单选中背景颜色
leftMenuBgActiveColor: 'var(--el-color-primary)', leftMenuBgActiveColor: 'transparent',
// 左侧菜单收起选中背景颜色 // 左侧菜单收起选中背景颜色
leftMenuCollapseBgActiveColor: 'var(--el-color-primary)', leftMenuCollapseBgActiveColor: 'var(--el-color-primary)',
// 左侧菜单字体颜色 // 左侧菜单字体颜色
leftMenuTextColor: '#bfcbd9', leftMenuTextColor: '#000',
// 左侧菜单选中字体颜色 // 左侧菜单选中字体颜色
leftMenuTextActiveColor: '#fff', leftMenuTextActiveColor: '#409eff',
// logo字体颜色 // logo字体颜色
logoTitleTextColor: '#fff', logoTitleTextColor: '#000',
// logo边框颜色 // logo边框颜色
logoBorderColor: 'inherit', logoBorderColor: 'inherit',
// 头部背景颜色 // 头部背景颜色
......
...@@ -25,9 +25,8 @@ ...@@ -25,9 +25,8 @@
} }
& .peg { & .peg {
box-shadow: box-shadow: 0 0 10px var(--el-color-primary),
0 0 10px var(--el-color-primary), 0 0 5px var(--el-color-primary) !important;
0 0 5px var(--el-color-primary) !important;
} }
& .spinner-icon { & .spinner-icon {
...@@ -35,3 +34,12 @@ ...@@ -35,3 +34,12 @@
border-left-color: var(--el-color-primary); border-left-color: var(--el-color-primary);
} }
} }
.bt-b10 {
padding-bottom: 10px;
}
.upload-box {
display: flex;
flex-direction: column;
}
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
--left-menu-min-width: 64px; --left-menu-min-width: 64px;
--left-menu-bg-color: #001529; --left-menu-bg-color: #ffffff;
--left-menu-bg-light-color: #0f2438; --left-menu-bg-light-color: #0f2438;
--left-menu-bg-active-color: var(--el-color-primary); --left-menu-bg-active-color: transparent;
--left-menu-text-color: #bfcbd9; --left-menu-text-color: #000000;
--left-menu-text-active-color: #fff; --left-menu-text-active-color: #409eff;
--left-menu-collapse-bg-active-color: var(--el-color-primary); --left-menu-collapse-bg-active-color: var(--el-color-primary);
/* left menu end */ /* left menu end */
......
...@@ -3,62 +3,30 @@ ...@@ -3,62 +3,30 @@
:class="prefixCls" :class="prefixCls"
class="relative h-[100%] lt-md:px-10px lt-sm:px-10px lt-xl:px-10px lt-xl:px-10px" class="relative h-[100%] lt-md:px-10px lt-sm:px-10px lt-xl:px-10px lt-xl:px-10px"
> >
<div class="relative mx-auto h-full flex"> <div class="relative mx-auto h-full flex bg">
<!-- <div-->
<!-- :class="`${prefixCls}__left flex-1 bg-opacity-20 relative p-30px lt-xl:hidden overflow-x-hidden overflow-y-auto`"-->
<!-- >-->
<!-- </div>-->
<div <div
:class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px lt-xl:hidden overflow-x-hidden overflow-y-auto`" class="flex-1 p-30px lt-sm:p-10px overflow-x-hidden overflow-y-auto"
style="display: flex; justify-content: center; align-items: center"
> >
<!-- 左上角的 logo + 系统标题 -->
<div class="relative flex items-center text-white">
<img alt="" class="mr-10px h-48px w-48px" src="@/assets/imgs/logo.png" />
<span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
</div>
<!-- 左边的背景图 + 欢迎语 -->
<div class="h-[calc(100%-60px)] flex items-center justify-center">
<TransitionGroup
appear
enter-active-class="animate__animated animate__bounceInLeft"
tag="div"
>
<img key="1" alt="" class="w-350px" src="@/assets/svgs/login-box-bg.svg" />
<div key="2" class="text-3xl text-white">{{ t('login.welcome') }}</div>
<div key="3" class="mt-5 text-14px font-normal text-white">
{{ t('login.message') }}
</div>
</TransitionGroup>
</div>
</div>
<div
class="relative flex-1 p-30px dark:bg-[var(--login-bg-color)] lt-sm:p-10px overflow-x-hidden overflow-y-auto"
>
<!-- 右上角的主题、语言选择 -->
<div
class="flex items-center justify-between at-2xl:justify-end at-xl:justify-end"
style="color: var(--el-text-color-primary);"
>
<div class="flex items-center at-2xl:hidden at-xl:hidden">
<img alt="" class="mr-10px h-48px w-48px" src="@/assets/imgs/logo.png" />
<span class="text-20px font-bold" >{{ underlineToHump(appStore.getTitle) }}</span>
</div>
<div class="flex items-center justify-end space-x-10px h-48px">
<ThemeSwitch />
<LocaleDropdown />
</div>
</div>
<!-- 右边的登录界面 --> <!-- 右边的登录界面 -->
<Transition appear enter-active-class="animate__animated animate__bounceInRight"> <Transition appear enter-active-class="animate__animated animate__bounceInRight">
<div <div
class="m-auto h-[calc(100%-60px)] w-[100%] flex items-center at-2xl:max-w-500px at-lg:max-w-500px at-md:max-w-500px at-xl:max-w-500px" class="form-bg m-auto w-[100%] flex items-center at-2xl:max-w-400px at-lg:max-w-400px at-md:max-w-400px at-xl:max-w-400px"
> >
<!-- 账号登录 --> <!-- 账号登录 -->
<LoginForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" /> <LoginForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
<!-- 手机登录 --> <!-- &lt;!&ndash; 手机登录 &ndash;&gt;-->
<MobileForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" /> <!-- <MobileForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
<!-- 二维码登录 --> <!-- &lt;!&ndash; 二维码登录 &ndash;&gt;-->
<QrCodeForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" /> <!-- <QrCodeForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
<!-- 注册 --> <!-- &lt;!&ndash; 注册 &ndash;&gt;-->
<RegisterForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" /> <!-- <RegisterForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
<!-- 三方登录 --> <!-- &lt;!&ndash; 三方登录 &ndash;&gt;-->
<SSOLoginVue class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" /> <!-- <SSOLoginVue class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
<!-- 忘记密码 --> <!-- 忘记密码 -->
<ForgetPasswordForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" /> <ForgetPasswordForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
</div> </div>
...@@ -68,14 +36,19 @@ ...@@ -68,14 +36,19 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { underlineToHump } from '@/utils'
import { useDesign } from '@/hooks/web/useDesign' import { useDesign } from '@/hooks/web/useDesign'
import { useAppStore } from '@/store/modules/app' import { useAppStore } from '@/store/modules/app'
import { ThemeSwitch } from '@/layout/components/ThemeSwitch' import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
import { LocaleDropdown } from '@/layout/components/LocaleDropdown' import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
import { LoginForm, MobileForm, QrCodeForm, RegisterForm, SSOLoginVue, ForgetPasswordForm } from './components' import {
LoginForm,
MobileForm,
QrCodeForm,
RegisterForm,
SSOLoginVue,
ForgetPasswordForm
} from './components'
defineOptions({ name: 'Login' }) defineOptions({ name: 'Login' })
...@@ -118,4 +91,12 @@ $prefix-cls: #{$namespace}-login; ...@@ -118,4 +91,12 @@ $prefix-cls: #{$namespace}-login;
background-color: var(--login-bg-color); background-color: var(--login-bg-color);
} }
} }
</style>
\ No newline at end of file .bg {
background: url('@/assets/imgs/login-background.png') no-repeat center center/100%;
}
.form-bg {
background: #ffffff;
}
</style>
...@@ -12,7 +12,10 @@ ...@@ -12,7 +12,10 @@
<el-row style="margin-right: -10px; margin-left: -10px"> <el-row style="margin-right: -10px; margin-left: -10px">
<el-col :span="24" style="padding-right: 10px; padding-left: 10px"> <el-col :span="24" style="padding-right: 10px; padding-left: 10px">
<el-form-item> <el-form-item>
<LoginFormTitle style="width: 100%" /> <!-- <LoginFormTitle style="width: 100%" />-->
<div class="loginFormTitle"
>{{ underlineToHump(appStore.getTitle) }} <br />后台管理系统
</div>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24" style="padding-right: 10px; padding-left: 10px"> <el-col :span="24" style="padding-right: 10px; padding-left: 10px">
...@@ -89,64 +92,6 @@ ...@@ -89,64 +92,6 @@
mode="pop" mode="pop"
@success="handleLogin" @success="handleLogin"
/> />
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
<el-form-item>
<el-row :gutter="5" justify="space-between" style="width: 100%">
<el-col :span="8">
<XButton
:title="t('login.btnMobile')"
class="w-[100%]"
@click="setLoginState(LoginStateEnum.MOBILE)"
/>
</el-col>
<el-col :span="8">
<XButton
:title="t('login.btnQRCode')"
class="w-[100%]"
@click="setLoginState(LoginStateEnum.QR_CODE)"
/>
</el-col>
<el-col :span="8">
<XButton
:title="t('login.btnRegister')"
class="w-[100%]"
@click="setLoginState(LoginStateEnum.REGISTER)"
/>
</el-col>
</el-row>
</el-form-item>
</el-col>
<el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
<el-form-item>
<div class="w-[100%] flex justify-between">
<Icon
v-for="(item, key) in socialList"
:key="key"
:icon="item.icon"
:size="30"
class="anticon cursor-pointer"
color="#999"
@click="doSocialLogin(item.type)"
/>
</div>
</el-form-item>
</el-col>
<el-divider content-position="center">萌新必读</el-divider>
<el-col :span="24" style="padding-right: 10px; padding-left: 10px">
<el-form-item>
<div class="w-[100%] flex justify-between">
<el-link href="https://doc.iocoder.cn/" target="_blank">📚开发指南</el-link>
<el-link href="https://doc.iocoder.cn/video/" target="_blank">🔥视频教程</el-link>
<el-link href="https://www.iocoder.cn/Interview/good-collection/" target="_blank">
⚡面试手册
</el-link>
<el-link href="http://static.yudao.iocoder.cn/mp/Aix9975.jpeg" target="_blank">
🤝外包咨询
</el-link>
</div>
</el-form-item>
</el-col>
</el-row> </el-row>
</el-form> </el-form>
</template> </template>
...@@ -161,6 +106,8 @@ import * as authUtil from '@/utils/auth' ...@@ -161,6 +106,8 @@ import * as authUtil from '@/utils/auth'
import { usePermissionStore } from '@/store/modules/permission' import { usePermissionStore } from '@/store/modules/permission'
import * as LoginApi from '@/api/login' import * as LoginApi from '@/api/login'
import { LoginStateEnum, useFormValid, useLoginState } from './useLogin' import { LoginStateEnum, useFormValid, useLoginState } from './useLogin'
import { underlineToHump } from '@/utils'
import { useAppStore } from '@/store/modules/app'
defineOptions({ name: 'LoginForm' }) defineOptions({ name: 'LoginForm' })
...@@ -178,7 +125,7 @@ const redirect = ref<string>('') ...@@ -178,7 +125,7 @@ const redirect = ref<string>('')
const loginLoading = ref(false) const loginLoading = ref(false)
const verify = ref() const verify = ref()
const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字 const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字
const appStore = useAppStore()
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN) const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN)
const LoginRules = { const LoginRules = {
...@@ -358,4 +305,20 @@ onMounted(() => { ...@@ -358,4 +305,20 @@ onMounted(() => {
cursor: pointer; cursor: pointer;
} }
} }
.loginFormTitle {
color: #2e77e3;
margin: 0 auto;
text-align: center;
font-size: 30px;
font-family: YouSheBiaoTiHei, system-ui;
}
:deep(.el-input__wrapper) {
box-shadow: 0 0 0 1px #dcdfe6 inset !important;
}
:deep(.el-input__inner) {
color: #606266;
}
</style> </style>
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
<el-tab-pane :label="t('profile.info.resetPwd')" name="resetPwd"> <el-tab-pane :label="t('profile.info.resetPwd')" name="resetPwd">
<ResetPwd /> <ResetPwd />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="t('profile.info.userSocial')" name="userSocial"> <!-- <el-tab-pane :label="t('profile.info.userSocial')" name="userSocial">-->
<UserSocial v-model:activeName="activeName" /> <!-- <UserSocial v-model:activeName="activeName" />-->
</el-tab-pane> <!-- </el-tab-pane>-->
</el-tabs> </el-tabs>
</div> </div>
</el-card> </el-card>
......
...@@ -19,25 +19,25 @@ ...@@ -19,25 +19,25 @@
{{ t('profile.user.email') }} {{ t('profile.user.email') }}
<div class="pull-right">{{ userInfo?.email }}</div> <div class="pull-right">{{ userInfo?.email }}</div>
</li> </li>
<li class="list-group-item"> <!-- <li class="list-group-item">-->
<Icon class="mr-5px" icon="carbon:tree-view-alt" /> <!-- <Icon class="mr-5px" icon="carbon:tree-view-alt" />-->
{{ t('profile.user.dept') }} <!-- {{ t('profile.user.dept') }}-->
<div v-if="userInfo?.dept" class="pull-right">{{ userInfo?.dept.name }}</div> <!-- <div v-if="userInfo?.dept" class="pull-right">{{ userInfo?.dept.name }}</div>-->
</li> <!-- </li>-->
<li class="list-group-item"> <!-- <li class="list-group-item">-->
<Icon class="mr-5px" icon="ep:suitcase" /> <!-- <Icon class="mr-5px" icon="ep:suitcase" />-->
{{ t('profile.user.posts') }} <!-- {{ t('profile.user.posts') }}-->
<div v-if="userInfo?.posts" class="pull-right"> <!-- <div v-if="userInfo?.posts" class="pull-right">-->
{{ userInfo?.posts.map((post) => post.name).join(',') }} <!-- {{ userInfo?.posts.map((post) => post.name).join(',') }}-->
</div> <!-- </div>-->
</li> <!-- </li>-->
<li class="list-group-item"> <!-- <li class="list-group-item">-->
<Icon class="mr-5px" icon="icon-park-outline:peoples" /> <!-- <Icon class="mr-5px" icon="icon-park-outline:peoples" />-->
{{ t('profile.user.roles') }} <!-- {{ t('profile.user.roles') }}-->
<div v-if="userInfo?.roles" class="pull-right"> <!-- <div v-if="userInfo?.roles" class="pull-right">-->
{{ userInfo?.roles.map((role) => role.name).join(',') }} <!-- {{ userInfo?.roles.map((role) => role.name).join(',') }}-->
</div> <!-- </div>-->
</li> <!-- </li>-->
<li class="list-group-item"> <li class="list-group-item">
<Icon class="mr-5px" icon="ep:calendar" /> <Icon class="mr-5px" icon="ep:calendar" />
{{ t('profile.user.createTime') }} {{ t('profile.user.createTime') }}
...@@ -76,6 +76,7 @@ onMounted(async () => { ...@@ -76,6 +76,7 @@ onMounted(async () => {
position: relative; position: relative;
height: 120px; height: 120px;
text-align: center; text-align: center;
margin-bottom: 30px;
} }
.list-group-striped > .list-group-item { .list-group-striped > .list-group-item {
......
...@@ -7,31 +7,37 @@ ...@@ -7,31 +7,37 @@
label-width="100px" label-width="100px"
v-loading="formLoading" v-loading="formLoading"
> >
<!-- <el-form-item label="轮播图地址" prop="image">--> <!-- <el-form-item label="轮播图地址" prop="image">-->
<!-- <UploadImg v-model="formData.image" />--> <!-- <UploadImg v-model="formData.image" />-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<el-form-item label="轮播图地址" prop="images"> <el-form-item label="轮播图地址" prop="images">
<el-upload <div class="upload-box">
v-model:file-list="formData.images" <el-upload
:action="uploadUrl" v-model:file-list="formData.images"
:http-request="httpRequest" :action="uploadUrl"
list-type="picture-card" :http-request="httpRequest"
:on-preview="handlePictureCardPreview" list-type="picture-card"
:on-remove="handleRemove" :on-preview="handlePictureCardPreview"
:on-success="handleUploadSuccess" :on-remove="handleRemove"
:on-error="handleUploadError" :on-success="handleUploadSuccess"
multiple :on-error="handleUploadError"
> multiple
<i class="el-icon-plus"></i> >
</el-upload> <el-icon>
<!-- 添加预览对话框 --> <Plus />
<el-dialog v-model="previewVisible" append-to-body> </el-icon>
<img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" /> </el-upload>
</el-dialog> <!-- 添加预览对话框 -->
<!-- 添加提示信息 --> <el-dialog v-model="previewVisible" append-to-body>
<p class="upload-tips"> <img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" />
请上传 大小不超过 <span class="red-text">5MB</span> 格式为 <span class="red-text">png/jpg/jpeg</span> 的文件 </el-dialog>
</p> <!-- 添加提示信息 -->
<p class="upload-tips">
请上传 大小不超过 <span class="red-text">5MB</span> 格式为
<span class="red-text">png/jpg/jpeg</span>
的文件
</p>
</div>
</el-form-item> </el-form-item>
<el-form-item label="内容" prop="information"> <el-form-item label="内容" prop="information">
...@@ -49,11 +55,11 @@ ...@@ -49,11 +55,11 @@
<el-form-item label="排序值" prop="orderNum"> <el-form-item label="排序值" prop="orderNum">
<el-input v-model="formData.orderNum" placeholder="请输入排序值" /> <el-input v-model="formData.orderNum" placeholder="请输入排序值" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="状态" prop="showStatus">--> <!-- <el-form-item label="状态" prop="showStatus">-->
<!-- <el-radio-group v-model="formData.showStatus">--> <!-- <el-radio-group v-model="formData.showStatus">-->
<!-- <el-radio value="1">请选择字典生成</el-radio>--> <!-- <el-radio value="1">请选择字典生成</el-radio>-->
<!-- </el-radio-group>--> <!-- </el-radio-group>-->
<!-- </el-form-item>--> <!-- </el-form-item>-->
<el-form-item label="状态" prop="showStatus"> <el-form-item label="状态" prop="showStatus">
<el-radio-group v-model="formData.showStatus"> <el-radio-group v-model="formData.showStatus">
<el-radio <el-radio
...@@ -80,6 +86,7 @@ ...@@ -80,6 +86,7 @@
import { BannerInfoApi, BannerInfo } from '@/api/biz/bannerinfo' import { BannerInfoApi, BannerInfo } from '@/api/biz/bannerinfo'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { useUpload } from '@/components/UploadFile/src/useUpload' import { useUpload } from '@/components/UploadFile/src/useUpload'
import { Plus } from '@element-plus/icons-vue'
/** banner页管理 表单 */ /** banner页管理 表单 */
defineOptions({ name: 'BannerInfoForm' }) defineOptions({ name: 'BannerInfoForm' })
...@@ -113,7 +120,7 @@ const formRules = reactive({ ...@@ -113,7 +120,7 @@ const formRules = reactive({
information: [{ required: true, message: '内容不能为空', trigger: 'blur' }], information: [{ required: true, message: '内容不能为空', trigger: 'blur' }],
title: [{ required: true, message: '标题不能为空', trigger: 'blur' }], title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
showStatus: [{ required: true, message: '状态:0-已隐藏,1-已显示不能为空', trigger: 'blur' }], showStatus: [{ required: true, message: '状态:0-已隐藏,1-已显示不能为空', trigger: 'blur' }],
orderNum: [{ required: true, message: '排序值不能为空', trigger: 'blur' }], orderNum: [{ required: true, message: '排序值不能为空', trigger: 'blur' }]
}) })
const formRef = ref() // 表单 Ref const formRef = ref() // 表单 Ref
...@@ -135,12 +142,11 @@ const open = async (type: string, id?: number) => { ...@@ -135,12 +142,11 @@ const open = async (type: string, id?: number) => {
} }
// 将 images 字段转换为 file-list 需要的格式 // 将 images 字段转换为 file-list 需要的格式
if (data.images && Array.isArray(data.images)) { if (data.images && Array.isArray(data.images)) {
formData.value.images = data.images.map(url => ({ url, name: 'image.jpg' })) // 添加 name 属性 formData.value.images = data.images.map((url) => ({ url, name: 'image.jpg' })) // 添加 name 属性
} else { } else {
formData.value.images = [] formData.value.images = []
} }
formData.value = { ...data, images: formData.value.images } // 确保 image 是数组 formData.value = { ...data, images: formData.value.images } // 确保 image 是数组
} finally { } finally {
formLoading.value = false formLoading.value = false
} }
...@@ -158,22 +164,24 @@ const submitForm = async () => { ...@@ -158,22 +164,24 @@ const submitForm = async () => {
try { try {
// 确保只提取真实的 URL,而不是本地的 Blob URL // 确保只提取真实的 URL,而不是本地的 Blob URL
const imageUrls = formData.value.images const imageUrls = formData.value.images
.filter(item => item.url && !item.url.startsWith('blob:')) // 过滤掉 Blob URL .filter((item) => item.url && !item.url.startsWith('blob:')) // 过滤掉 Blob URL
.map(item => item.url); .map((item) => item.url)
// 如果还有 Blob URL,说明有文件还未上传完成 // 如果还有 Blob URL,说明有文件还未上传完成
const hasBlobUrls = formData.value.images.some(item => item.url && item.url.startsWith('blob:')); const hasBlobUrls = formData.value.images.some(
(item) => item.url && item.url.startsWith('blob:')
)
if (hasBlobUrls) { if (hasBlobUrls) {
message.warning('请等待图片上传完成后再提交'); message.warning('请等待图片上传完成后再提交')
formLoading.value = false; formLoading.value = false
return; return
} }
// 构造最终数据 // 构造最终数据
const data = { const data = {
...formData.value, ...formData.value,
images: imageUrls images: imageUrls
}; }
if (formType.value === 'bannerCreate') { if (formType.value === 'bannerCreate') {
await BannerInfoApi.createBannerInfo(data) await BannerInfoApi.createBannerInfo(data)
...@@ -224,24 +232,29 @@ const handleUploadSuccess = (response, file, fileList) => { ...@@ -224,24 +232,29 @@ const handleUploadSuccess = (response, file, fileList) => {
// 从响应中提取真实的URL并更新文件对象 // 从响应中提取真实的URL并更新文件对象
if (response && response.data) { if (response && response.data) {
// 根据 useUpload.ts 的实现,可能是 response.data.url 或直接是 response.data // 根据 useUpload.ts 的实现,可能是 response.data.url 或直接是 response.data
const realUrl = response.data.url || response.data; const realUrl = response.data.url || response.data
if (realUrl) { if (realUrl) {
file.url = realUrl; file.url = realUrl
} }
} }
// 更新 formData.images // 更新 formData.images
formData.value.images = fileList; formData.value.images = fileList
} }
// 上传失败处理函数 // 上传失败处理函数
const handleUploadError = (err, file, fileList) => { const handleUploadError = (err, file, fileList) => {
message.error('图片上传失败: ' + (err.message || '未知错误')) message.error('图片上传失败: ' + (err.message || '未知错误'))
} }
</script> </script>
<style scoped>.upload-tips { <style scoped>
.upload-box {
display: flex;
flex-direction: column;
}
.upload-tips {
font-size: 12px; font-size: 12px;
color: #999; color: #999;
margin-top: 10px; margin-top: 10px;
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px"
> >
<el-form-item label="内容" prop="information"> <el-form-item label="内容" prop="information">
<el-input <el-input
...@@ -26,27 +25,13 @@ ...@@ -26,27 +25,13 @@
class="!w-200px" class="!w-200px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="链接地址" prop="url"> <el-form-item label="状态" prop="showStatus">
<el-input <el-select
v-model="queryParams.url" v-model="queryParams.showStatus"
placeholder="请输入链接地址" placeholder="请选择状态"
clearable clearable
@keyup.enter="handleQuery"
class="!w-200px" class="!w-200px"
/> >
</el-form-item>
<!-- <el-form-item label="排序值" prop="orderNum">-->
<!-- <el-input-->
<!-- v-model="queryParams.orderNum"-->
<!-- placeholder="请输入排序值"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-160px"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item label="状态" prop="showStatus">
<el-select v-model="queryParams.showStatus" placeholder="请选择状态" clearable class="!w-200px">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.HOME_INFO_STATUS)" v-for="dict in getIntDictOptions(DICT_TYPE.HOME_INFO_STATUS)"
:key="dict.value" :key="dict.value"
...@@ -55,65 +40,14 @@ ...@@ -55,65 +40,14 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- <el-form-item label="状态" prop="showStatus">-->
<!-- <el-select-->
<!-- v-model="queryParams.showStatus"-->
<!-- placeholder="请选择状态:0-已隐藏,1-已显示"-->
<!-- clearable-->
<!-- class="!w-240px"-->
<!-- >-->
<!-- <el-option label="请选择字典生成" value="" />-->
<!-- </el-select>-->
<!-- </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-220px"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="备注" prop="remark">-->
<!-- <el-input-->
<!-- v-model="queryParams.remark"-->
<!-- placeholder="请输入备注"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-240px"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item> <el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> <el-button @click="handleQuery">
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> <Icon icon="ep:search" class="mr-5px" />
<el-button 搜索
type="primary"
plain
@click="openForm('bannerCreate')"
v-hasPermi="['biz:banner-info:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button> </el-button>
<el-button <el-button @click="resetQuery">
type="success" <Icon icon="ep:refresh" class="mr-5px" />
plain 重置
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['biz:banner-info:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
<el-button
type="danger"
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['biz:banner-info:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
...@@ -121,22 +55,47 @@ ...@@ -121,22 +55,47 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<div class="bt-b10">
<el-button
type="primary"
plain
@click="openForm('bannerCreate')"
v-hasPermi="['biz:banner-info:create']"
>
<Icon icon="ep:plus" class="mr-5px" />
新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['biz:banner-info:export']"
>
<Icon icon="ep:download" class="mr-5px" />
导出
</el-button>
<el-button
type="danger"
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['biz:banner-info:delete']"
>
<Icon icon="ep:delete" class="mr-5px" />
批量删除
</el-button>
</div>
<el-table <el-table
row-key="id" row-key="id"
v-loading="loading" v-loading="loading"
:data="list" :data="list"
:stripe="true" :stripe="true"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
@selection-change="handleRowCheckboxChange" @selection-change="handleRowCheckboxChange"
> >
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column label="排序值" align="center" prop="orderNum" /> <el-table-column label="排序值" align="center" prop="orderNum" />
<!-- <el-table-column label="轮播图地址" align="center" prop="image" />-->
<!-- <el-table-column label="轮播图地址" align="center" prop="images" width="100">-->
<!-- <template #default="scope">-->
<!-- <img :src="scope.row.images" alt="轮播图" class="h-36px" />-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="轮播图地址" align="center" prop="images" width="100"> <el-table-column label="轮播图地址" align="center" prop="images" width="100">
<template #default="scope"> <template #default="scope">
<!-- 只显示第一张图片 --> <!-- 只显示第一张图片 -->
...@@ -154,20 +113,11 @@ ...@@ -154,20 +113,11 @@
<el-table-column label="标题" align="center" prop="title" /> <el-table-column label="标题" align="center" prop="title" />
<el-table-column label="链接地址" align="center" prop="url" /> <el-table-column label="链接地址" align="center" prop="url" />
<el-table-column label="描述内容" align="center" prop="description" /> <el-table-column label="描述内容" align="center" prop="description" />
<!-- <el-table-column label="状态" align="center" prop="showStatus" />-->
<el-table-column label="状态" align="center" prop="showStatus"> <el-table-column label="状态" align="center" prop="showStatus">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.HOME_INFO_STATUS" :value="scope.row.showStatus" /> <dict-tag :type="DICT_TYPE.HOME_INFO_STATUS" :value="scope.row.showStatus" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" min-width="120px"> <el-table-column label="操作" align="center" min-width="120px">
<template #default="scope"> <template #default="scope">
...@@ -230,7 +180,7 @@ const queryParams = reactive({ ...@@ -230,7 +180,7 @@ const queryParams = reactive({
showStatus: undefined, showStatus: undefined,
createTime: [], createTime: [],
remark: undefined, remark: undefined,
url: undefined, url: undefined
}) })
const queryFormRef = ref() // 搜索的表单 const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中 const exportLoading = ref(false) // 导出的加载中
...@@ -283,15 +233,15 @@ const handleDeleteBatch = async () => { ...@@ -283,15 +233,15 @@ const handleDeleteBatch = async () => {
try { try {
// 删除的二次确认 // 删除的二次确认
await message.delConfirm() await message.delConfirm()
await BannerInfoApi.deleteBannerInfoList(checkedIds.value); await BannerInfoApi.deleteBannerInfoList(checkedIds.value)
message.success(t('common.delSuccess')) message.success(t('common.delSuccess'))
await getList(); await getList()
} catch {} } catch {}
} }
const checkedIds = ref<number[]>([]) const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (records: BannerInfo[]) => { const handleRowCheckboxChange = (records: BannerInfo[]) => {
checkedIds.value = records.map((item) => item.id); checkedIds.value = records.map((item) => item.id)
} }
/** 导出按钮操作 */ /** 导出按钮操作 */
...@@ -312,5 +262,10 @@ const handleExport = async () => { ...@@ -312,5 +262,10 @@ const handleExport = async () => {
/** 初始化 **/ /** 初始化 **/
onMounted(() => { onMounted(() => {
getList() getList()
console.log(
getIntDictOptions(DICT_TYPE.HOME_INFO_STATUS),
'getIntDictOptions(DICT_TYPE.HOME_INFO_STATUS)'
)
}) })
</script> </script>
...@@ -4,34 +4,37 @@ ...@@ -4,34 +4,37 @@
ref="formRef" ref="formRef"
:model="formData" :model="formData"
:rules="formRules" :rules="formRules"
label-width="100px" label-width="140px"
v-loading="formLoading" v-loading="formLoading"
> >
<!-- <el-form-item label="展示图地址" prop="images">-->
<!-- <UploadImg v-model="formData.images" />-->
<!-- </el-form-item>-->
<el-form-item label="展示图地址" prop="images"> <el-form-item label="展示图地址" prop="images">
<el-upload <div class="upload-box">
v-model:file-list="formData.images" <el-upload
:action="uploadUrl" v-model:file-list="formData.images"
:http-request="httpRequest" :action="uploadUrl"
list-type="picture-card" :http-request="httpRequest"
:on-preview="handlePictureCardPreview" list-type="picture-card"
:on-remove="handleRemove" :on-preview="handlePictureCardPreview"
:on-success="handleUploadSuccess" :on-remove="handleRemove"
:on-error="handleUploadError" :on-success="handleUploadSuccess"
multiple :on-error="handleUploadError"
> multiple
<i class="el-icon-plus"></i> >
</el-upload> <el-icon>
<!-- 添加预览对话框 --> <Plus />
<el-dialog v-model="previewVisible" append-to-body> </el-icon>
<img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" /> </el-upload>
</el-dialog> <!-- 添加预览对话框 -->
<!-- 添加提示信息 --> <el-dialog v-model="previewVisible" append-to-body>
<p class="upload-tips"> <img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" />
请上传 大小不超过 <span class="red-text">5MB</span> 格式为 <span class="red-text">png/jpg/jpeg</span> 的文件 </el-dialog>
</p> <!-- 添加提示信息 -->
<p class="upload-tips">
请上传 大小不超过 <span class="red-text">5MB</span> 格式为
<span class="red-text">png/jpg/jpeg</span>
的文件
</p>
</div>
</el-form-item> </el-form-item>
<el-form-item label="内容" prop="information"> <el-form-item label="内容" prop="information">
...@@ -46,14 +49,14 @@ ...@@ -46,14 +49,14 @@
<el-form-item label="描述内容" prop="description"> <el-form-item label="描述内容" prop="description">
<Editor v-model="formData.description" height="150px" /> <Editor v-model="formData.description" height="150px" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="计算资源应用类别" prop="category">-->
<!-- <el-select v-model="formData.category" placeholder="请选择计算资源应用类别">-->
<!-- <el-option label="请选择字典生成" value="" />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="计算资源应用类别" prop="category"> <el-form-item label="计算资源应用类别" prop="category">
<el-select v-model="formData.category" placeholder="请选择应用类别" clearable class="!w-160px"> <el-select
v-model="formData.category"
placeholder="请选择计算资源应用类别"
clearable
class="!w-160px"
>
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.HOME_INFO_COMPUTILITY_TYPE)" v-for="dict in getIntDictOptions(DICT_TYPE.HOME_INFO_COMPUTILITY_TYPE)"
:key="dict.value" :key="dict.value"
...@@ -63,12 +66,6 @@ ...@@ -63,12 +66,6 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- <el-form-item label="状态" prop="showStatus">-->
<!-- <el-radio-group v-model="formData.showStatus">-->
<!-- <el-radio value="1">请选择字典生成</el-radio>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<el-form-item label="状态" prop="showStatus"> <el-form-item label="状态" prop="showStatus">
<el-radio-group v-model="formData.showStatus"> <el-radio-group v-model="formData.showStatus">
<el-radio <el-radio
...@@ -96,6 +93,7 @@ import { ComputilityInformationApi, ComputilityInformation } from '@/api/biz/com ...@@ -96,6 +93,7 @@ import { ComputilityInformationApi, ComputilityInformation } from '@/api/biz/com
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { useUpload } from '@/components/UploadFile/src/useUpload' import { useUpload } from '@/components/UploadFile/src/useUpload'
import { Plus } from '@element-plus/icons-vue'
// 添加预览相关的响应式变量 // 添加预览相关的响应式变量
const previewVisible = ref(false) const previewVisible = ref(false)
...@@ -152,12 +150,11 @@ const open = async (type: string, id?: number) => { ...@@ -152,12 +150,11 @@ const open = async (type: string, id?: number) => {
// 将 images 字段转换为 file-list 需要的格式 // 将 images 字段转换为 file-list 需要的格式
if (data.images && Array.isArray(data.images)) { if (data.images && Array.isArray(data.images)) {
formData.value.images = data.images.map(url => ({ url, name: 'image.jpg' })) // 添加 name 属性 formData.value.images = data.images.map((url) => ({ url, name: 'image.jpg' })) // 添加 name 属性
} else { } else {
formData.value.images = [] formData.value.images = []
} }
formData.value = { ...data, images: formData.value.images } // 确保 image 是数组 formData.value = { ...data, images: formData.value.images } // 确保 image 是数组
} finally { } finally {
formLoading.value = false formLoading.value = false
} }
...@@ -173,25 +170,26 @@ const submitForm = async () => { ...@@ -173,25 +170,26 @@ const submitForm = async () => {
// 提交请求 // 提交请求
formLoading.value = true formLoading.value = true
try { try {
// 确保只提取真实的 URL,而不是本地的 Blob URL // 确保只提取真实的 URL,而不是本地的 Blob URL
const imageUrls = formData.value.images const imageUrls = formData.value.images
.filter(item => item.url && !item.url.startsWith('blob:')) // 过滤掉 Blob URL .filter((item) => item.url && !item.url.startsWith('blob:')) // 过滤掉 Blob URL
.map(item => item.url); .map((item) => item.url)
// 如果还有 Blob URL,说明有文件还未上传完成 // 如果还有 Blob URL,说明有文件还未上传完成
const hasBlobUrls = formData.value.images.some(item => item.url && item.url.startsWith('blob:')); const hasBlobUrls = formData.value.images.some(
(item) => item.url && item.url.startsWith('blob:')
)
if (hasBlobUrls) { if (hasBlobUrls) {
message.warning('请等待图片上传完成后再提交'); message.warning('请等待图片上传完成后再提交')
formLoading.value = false; formLoading.value = false
return; return
} }
// 构造最终数据 // 构造最终数据
const data = { const data = {
...formData.value, ...formData.value,
images: imageUrls images: imageUrls
}; }
if (formType.value === 'computilityCreate') { if (formType.value === 'computilityCreate') {
await ComputilityInformationApi.createComputilityInformation(data) await ComputilityInformationApi.createComputilityInformation(data)
...@@ -242,25 +240,24 @@ const handleUploadSuccess = (response, file, fileList) => { ...@@ -242,25 +240,24 @@ const handleUploadSuccess = (response, file, fileList) => {
// 从响应中提取真实的URL并更新文件对象 // 从响应中提取真实的URL并更新文件对象
if (response && response.data) { if (response && response.data) {
// 根据 useUpload.ts 的实现,可能是 response.data.url 或直接是 response.data // 根据 useUpload.ts 的实现,可能是 response.data.url 或直接是 response.data
const realUrl = response.data.url || response.data; const realUrl = response.data.url || response.data
if (realUrl) { if (realUrl) {
file.url = realUrl; file.url = realUrl
} }
} }
// 更新 formData.images // 更新 formData.images
formData.value.images = fileList; formData.value.images = fileList
} }
// 上传失败处理函数 // 上传失败处理函数
const handleUploadError = (err, file, fileList) => { const handleUploadError = (err, file, fileList) => {
message.error('图片上传失败: ' + (err.message || '未知错误')) message.error('图片上传失败: ' + (err.message || '未知错误'))
} }
</script> </script>
<style scoped>.upload-tips { <style scoped>
.upload-tips {
font-size: 12px; font-size: 12px;
color: #999; color: #999;
margin-top: 10px; margin-top: 10px;
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
:model="queryParams" :model="queryParams"
ref="queryFormRef" ref="queryFormRef"
:inline="true" :inline="true"
label-width="68px"
> >
<el-form-item label="内容" prop="information"> <el-form-item label="内容" prop="information">
<el-input <el-input
...@@ -17,7 +16,6 @@ ...@@ -17,7 +16,6 @@
class="!w-160px" class="!w-160px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="标题" prop="title"> <el-form-item label="标题" prop="title">
<el-input <el-input
v-model="queryParams.title" v-model="queryParams.title"
...@@ -27,28 +25,7 @@ ...@@ -27,28 +25,7 @@
class="!w-160px" class="!w-160px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="计算资源应用类别" prop="category">
<el-form-item label="链接地址" prop="url">
<el-input
v-model="queryParams.url"
placeholder="请输入链接地址"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="计算资源应用类别" prop="category">-->
<!-- <el-select-->
<!-- v-model="queryParams.category"-->
<!-- placeholder="请选择计算资源应用类别"-->
<!-- clearable-->
<!-- class="!w-240px"-->
<!-- >-->
<!-- <el-option label="请选择字典生成" value="" />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item label="应用类别" prop="category">
<el-select v-model="queryParams.category" placeholder="请选择计算资源应用类别" clearable class="!w-200px"> <el-select v-model="queryParams.category" placeholder="请选择计算资源应用类别" clearable class="!w-200px">
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.HOME_INFO_COMPUTILITY_TYPE)" v-for="dict in getIntDictOptions(DICT_TYPE.HOME_INFO_COMPUTILITY_TYPE)"
...@@ -60,7 +37,12 @@ ...@@ -60,7 +37,12 @@
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="showStatus"> <el-form-item label="状态" prop="showStatus">
<el-select v-model="queryParams.showStatus" placeholder="请选择状态" clearable class="!w-120px"> <el-select
v-model="queryParams.showStatus"
placeholder="请选择状态"
clearable
class="!w-120px"
>
<el-option <el-option
v-for="dict in getIntDictOptions(DICT_TYPE.HOME_INFO_STATUS)" v-for="dict in getIntDictOptions(DICT_TYPE.HOME_INFO_STATUS)"
:key="dict.value" :key="dict.value"
...@@ -69,55 +51,14 @@ ...@@ -69,55 +51,14 @@
/> />
</el-select> </el-select>
</el-form-item> </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-220px"-->
<!-- />-->
<!-- </el-form-item>-->
<!-- <el-form-item label="备注" prop="remark">-->
<!-- <el-input-->
<!-- v-model="queryParams.remark"-->
<!-- placeholder="请输入备注"-->
<!-- clearable-->
<!-- @keyup.enter="handleQuery"-->
<!-- class="!w-240px"-->
<!-- />-->
<!-- </el-form-item>-->
<el-form-item> <el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> <el-button @click="handleQuery">
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> <Icon icon="ep:search" class="mr-5px" />
<el-button 搜索
type="primary"
plain
@click="openForm('computilityCreate')"
v-hasPermi="['biz:computility-information:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['biz:computility-information:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button> </el-button>
<el-button <el-button @click="resetQuery">
type="danger" <Icon icon="ep:refresh" class="mr-5px" />
plain 重置
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['biz:computility-information:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
...@@ -125,21 +66,46 @@ ...@@ -125,21 +66,46 @@
<!-- 列表 --> <!-- 列表 -->
<ContentWrap> <ContentWrap>
<div class="bt-b10">
<el-button
type="primary"
plain
@click="openForm('computilityCreate')"
v-hasPermi="['biz:computility-information:create']"
>
<Icon icon="ep:plus" class="mr-5px" />
新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['biz:computility-information:export']"
>
<Icon icon="ep:download" class="mr-5px" />
导出
</el-button>
<el-button
type="danger"
plain
:disabled="isEmpty(checkedIds)"
@click="handleDeleteBatch"
v-hasPermi="['biz:computility-information:delete']"
>
<Icon icon="ep:delete" class="mr-5px" />
批量删除
</el-button>
</div>
<el-table <el-table
row-key="id" row-key="id"
v-loading="loading" v-loading="loading"
:data="list" :data="list"
:stripe="true" :stripe="true"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
@selection-change="handleRowCheckboxChange" @selection-change="handleRowCheckboxChange"
> >
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<!-- <el-table-column label="展示图地址" align="center" prop="image" />-->
<!-- <el-table-column label="展示图地址" align="center" prop="images" width="100">-->
<!-- <template #default="scope">-->
<!-- <img :src="scope.row.images" alt="资源展示图" class="h-36px" />-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="展示图地址" align="center" prop="images" width="100"> <el-table-column label="展示图地址" align="center" prop="images" width="100">
<template #default="scope"> <template #default="scope">
<!-- 只显示第一张图片 --> <!-- 只显示第一张图片 -->
...@@ -157,26 +123,16 @@ ...@@ -157,26 +123,16 @@
<el-table-column label="标题" align="center" prop="title" /> <el-table-column label="标题" align="center" prop="title" />
<el-table-column label="链接地址" align="center" prop="url" /> <el-table-column label="链接地址" align="center" prop="url" />
<el-table-column label="描述内容" align="center" prop="description" /> <el-table-column label="描述内容" align="center" prop="description" />
<!-- <el-table-column label="计算资源应用类别" align="center" prop="category" />-->
<el-table-column label="计算资源应用类别" align="center" prop="category"> <el-table-column label="计算资源应用类别" align="center" prop="category">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.HOME_INFO_COMPUTILITY_TYPE" :value="scope.row.category" /> <dict-tag :type="DICT_TYPE.HOME_INFO_COMPUTILITY_TYPE" :value="scope.row.category" />
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column label="状态" align="center" prop="showStatus" />-->
<el-table-column label="状态" align="center" prop="showStatus"> <el-table-column label="状态" align="center" prop="showStatus">
<template #default="scope"> <template #default="scope">
<dict-tag :type="DICT_TYPE.HOME_INFO_STATUS" :value="Number(scope.row.showStatus)" /> <dict-tag :type="DICT_TYPE.HOME_INFO_STATUS" :value="Number(scope.row.showStatus)" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="操作" align="center" min-width="120px"> <el-table-column label="操作" align="center" min-width="120px">
<template #default="scope"> <template #default="scope">
...@@ -237,7 +193,7 @@ const queryParams = reactive({ ...@@ -237,7 +193,7 @@ const queryParams = reactive({
showStatus: undefined, showStatus: undefined,
createTime: [], createTime: [],
remark: undefined, remark: undefined,
description: '', description: ''
}) })
const queryFormRef = ref() // 搜索的表单 const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中 const exportLoading = ref(false) // 导出的加载中
...@@ -290,15 +246,15 @@ const handleDeleteBatch = async () => { ...@@ -290,15 +246,15 @@ const handleDeleteBatch = async () => {
try { try {
// 删除的二次确认 // 删除的二次确认
await message.delConfirm() await message.delConfirm()
await ComputilityInformationApi.deleteComputilityInformationList(checkedIds.value); await ComputilityInformationApi.deleteComputilityInformationList(checkedIds.value)
message.success(t('common.delSuccess')) message.success(t('common.delSuccess'))
await getList(); await getList()
} catch {} } catch {}
} }
const checkedIds = ref<number[]>([]) const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (records: ComputilityInformation[]) => { const handleRowCheckboxChange = (records: ComputilityInformation[]) => {
checkedIds.value = records.map((item) => item.id); checkedIds.value = records.map((item) => item.id)
} }
/** 导出按钮操作 */ /** 导出按钮操作 */
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
:on-error="handleUploadError" :on-error="handleUploadError"
multiple multiple
> >
<i class="el-icon-plus"></i> <el-icon><Plus /></el-icon>
</el-upload> </el-upload>
<!-- 添加预览对话框 --> <!-- 添加预览对话框 -->
<el-dialog v-model="previewVisible" append-to-body> <el-dialog v-model="previewVisible" append-to-body>
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
:on-error="handleUploadError" :on-error="handleUploadError"
multiple multiple
> >
<i class="el-icon-plus"></i> <el-icon><Plus /></el-icon>
</el-upload> </el-upload>
<!-- 添加预览对话框 --> <!-- 添加预览对话框 -->
<el-dialog v-model="previewVisible" append-to-body> <el-dialog v-model="previewVisible" append-to-body>
...@@ -120,6 +120,7 @@ import { IndustryApplicationApi, IndustryApplication } from '@/api/biz/industrya ...@@ -120,6 +120,7 @@ import { IndustryApplicationApi, IndustryApplication } from '@/api/biz/industrya
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { useUpload } from '@/components/UploadFile/src/useUpload' import { useUpload } from '@/components/UploadFile/src/useUpload'
import {Plus} from "@element-plus/icons-vue";
// 添加预览相关的响应式变量 // 添加预览相关的响应式变量
const previewVisible = ref(false) const previewVisible = ref(false)
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
:on-error="handleUploadError" :on-error="handleUploadError"
multiple multiple
> >
<i class="el-icon-plus"></i> <el-icon><Plus /></el-icon>
</el-upload> </el-upload>
<!-- 添加预览对话框 --> <!-- 添加预览对话框 -->
<el-dialog v-model="previewVisible" append-to-body> <el-dialog v-model="previewVisible" append-to-body>
...@@ -90,6 +90,7 @@ ...@@ -90,6 +90,7 @@
import { InformationApi, Information } from '@/api/biz/information' import { InformationApi, Information } from '@/api/biz/information'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { useUpload } from '@/components/UploadFile/src/useUpload' import { useUpload } from '@/components/UploadFile/src/useUpload'
import {Plus} from "@element-plus/icons-vue";
// 添加预览相关的响应式变量 // 添加预览相关的响应式变量
const previewVisible = ref(false) const previewVisible = ref(false)
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
:on-error="handleUploadError" :on-error="handleUploadError"
multiple multiple
> >
<i class="el-icon-plus"></i> <el-icon><Plus /></el-icon>
</el-upload> </el-upload>
<!-- 添加预览对话框 --> <!-- 添加预览对话框 -->
<el-dialog v-model="previewVisible" append-to-body> <el-dialog v-model="previewVisible" append-to-body>
...@@ -71,6 +71,7 @@ import { PartnerApi, Partner } from '@/api/biz/partner' ...@@ -71,6 +71,7 @@ import { PartnerApi, Partner } from '@/api/biz/partner'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { useUpload } from '@/components/UploadFile/src/useUpload' import { useUpload } from '@/components/UploadFile/src/useUpload'
import {Plus} from "@element-plus/icons-vue";
// 添加预览相关的响应式变量 // 添加预览相关的响应式变量
const previewVisible = ref(false) const previewVisible = ref(false)
......
...@@ -29,11 +29,11 @@ ...@@ -29,11 +29,11 @@
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
<el-table-column align="center" label="商品条码" min-width="168"> <!-- <el-table-column align="center" label="商品条码" min-width="168">-->
<template #default="{ row }"> <!-- <template #default="{ row }">-->
<el-input v-model="row.barCode" class="w-100%" /> <!-- <el-input v-model="row.barCode" class="w-100%" />-->
</template> <!-- </template>-->
</el-table-column> <!-- </el-table-column>-->
<el-table-column align="center" label="销售价" min-width="168"> <el-table-column align="center" label="销售价" min-width="168">
<template #default="{ row }"> <template #default="{ row }">
<el-input-number <el-input-number
...@@ -75,30 +75,30 @@ ...@@ -75,30 +75,30 @@
<el-input-number v-model="row.stock" :min="0" class="w-100%" controls-position="right" /> <el-input-number v-model="row.stock" :min="0" class="w-100%" controls-position="right" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="重量(kg)" min-width="168"> <!-- <el-table-column align="center" label="重量(kg)" min-width="168">-->
<template #default="{ row }"> <!-- <template #default="{ row }">-->
<el-input-number <!-- <el-input-number-->
v-model="row.weight" <!-- v-model="row.weight"-->
:min="0" <!-- :min="0"-->
:precision="2" <!-- :precision="2"-->
:step="0.1" <!-- :step="0.1"-->
class="w-100%" <!-- class="w-100%"-->
controls-position="right" <!-- controls-position="right"-->
/> <!-- />-->
</template> <!-- </template>-->
</el-table-column> <!-- </el-table-column>-->
<el-table-column align="center" label="体积(m^3)" min-width="168"> <!-- <el-table-column align="center" label="体积(m^3)" min-width="168">-->
<template #default="{ row }"> <!-- <template #default="{ row }">-->
<el-input-number <!-- <el-input-number-->
v-model="row.volume" <!-- v-model="row.volume"-->
:min="0" <!-- :min="0"-->
:precision="2" <!-- :precision="2"-->
:step="0.1" <!-- :step="0.1"-->
class="w-100%" <!-- class="w-100%"-->
controls-position="right" <!-- controls-position="right"-->
/> <!-- />-->
</template> <!-- </template>-->
</el-table-column> <!-- </el-table-column>-->
<template v-if="formData!.subCommissionType"> <template v-if="formData!.subCommissionType">
<el-table-column align="center" label="一级返佣(元)" min-width="168"> <el-table-column align="center" label="一级返佣(元)" min-width="168">
<template #default="{ row }"> <template #default="{ row }">
...@@ -173,11 +173,11 @@ ...@@ -173,11 +173,11 @@
</template> </template>
</el-table-column> </el-table-column>
</template> </template>
<el-table-column align="center" label="商品条码" min-width="100"> <!-- <el-table-column align="center" label="商品条码" min-width="100">-->
<template #default="{ row }"> <!-- <template #default="{ row }">-->
{{ row.barCode }} <!-- {{ row.barCode }}-->
</template> <!-- </template>-->
</el-table-column> <!-- </el-table-column>-->
<el-table-column align="center" label="销售价(元)" min-width="80"> <el-table-column align="center" label="销售价(元)" min-width="80">
<template #default="{ row }"> <template #default="{ row }">
{{ row.price }} {{ row.price }}
...@@ -198,16 +198,16 @@ ...@@ -198,16 +198,16 @@
{{ row.stock }} {{ row.stock }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="重量(kg)" min-width="80"> <!-- <el-table-column align="center" label="重量(kg)" min-width="80">-->
<template #default="{ row }"> <!-- <template #default="{ row }">-->
{{ row.weight }} <!-- {{ row.weight }}-->
</template> <!-- </template>-->
</el-table-column> <!-- </el-table-column>-->
<el-table-column align="center" label="体积(m^3)" min-width="80"> <!-- <el-table-column align="center" label="体积(m^3)" min-width="80">-->
<template #default="{ row }"> <!-- <template #default="{ row }">-->
{{ row.volume }} <!-- {{ row.volume }}-->
</template> <!-- </template>-->
</el-table-column> <!-- </el-table-column>-->
<template v-if="formData!.subCommissionType"> <template v-if="formData!.subCommissionType">
<el-table-column align="center" label="一级返佣(元)" min-width="80"> <el-table-column align="center" label="一级返佣(元)" min-width="80">
<template #default="{ row }"> <template #default="{ row }">
......
...@@ -17,30 +17,6 @@ ...@@ -17,30 +17,6 @@
:propFormData="formData" :propFormData="formData"
/> />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="物流设置" name="delivery">
<DeliveryForm
ref="deliveryRef"
v-model:activeName="activeName"
:is-detail="isDetail"
:propFormData="formData"
/>
</el-tab-pane>
<el-tab-pane label="商品详情" name="description">
<DescriptionForm
ref="descriptionRef"
v-model:activeName="activeName"
:is-detail="isDetail"
:propFormData="formData"
/>
</el-tab-pane>
<el-tab-pane label="其它设置" name="other">
<OtherForm
ref="otherRef"
v-model:activeName="activeName"
:is-detail="isDetail"
:propFormData="formData"
/>
</el-tab-pane>
</el-tabs> </el-tabs>
<el-form> <el-form>
<el-form-item style="float: right"> <el-form-item style="float: right">
......
...@@ -181,7 +181,7 @@ ...@@ -181,7 +181,7 @@
/> />
<el-table-column align="center" fixed="right" label="操作" min-width="200"> <el-table-column align="center" fixed="right" label="操作" min-width="200">
<template #default="{ row }"> <template #default="{ row }">
<el-button link type="primary" @click="openDetail(row.id)"> 详情 </el-button> <el-button link type="primary" @click="openDetail(row.id)"> 详情</el-button>
<el-button <el-button
v-hasPermi="['product:spu:update']" v-hasPermi="['product:spu:update']"
link link
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment