diff --git a/src/api/sys/user.ts b/src/api/sys/user.ts index cb018b8e..12a22a67 100644 --- a/src/api/sys/user.ts +++ b/src/api/sys/user.ts @@ -28,3 +28,12 @@ export function forgetPasswordByPhone(obj) { data: obj, }) } +/** + * 修改密码 + */ +export function modifPassword(obj) { + return defHttp.post({ + url: `/user/updatePassword`, + params: obj, + }) +} diff --git a/src/assets/daxpay/allinPay.svg b/src/assets/daxpay/allinPay.svg new file mode 100644 index 00000000..7bdccf76 --- /dev/null +++ b/src/assets/daxpay/allinPay.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + diff --git a/src/assets/daxpay/hkrtPay.svg b/src/assets/daxpay/hkrtPay.svg new file mode 100644 index 00000000..3085d10f --- /dev/null +++ b/src/assets/daxpay/hkrtPay.svg @@ -0,0 +1,4568 @@ + + + + diff --git a/src/assets/images/addAppId.png b/src/assets/images/addAppId.png new file mode 100644 index 00000000..3bac5e25 Binary files /dev/null and b/src/assets/images/addAppId.png differ diff --git a/src/assets/payicon/index_order-1.png b/src/assets/payicon/index_order-1.png new file mode 100644 index 00000000..0d35466d Binary files /dev/null and b/src/assets/payicon/index_order-1.png differ diff --git a/src/assets/payicon/index_order-2.png b/src/assets/payicon/index_order-2.png new file mode 100644 index 00000000..2815381d Binary files /dev/null and b/src/assets/payicon/index_order-2.png differ diff --git a/src/assets/payicon/index_order-3.png b/src/assets/payicon/index_order-3.png new file mode 100644 index 00000000..87babd75 Binary files /dev/null and b/src/assets/payicon/index_order-3.png differ diff --git a/src/assets/payicon/index_order-4.png b/src/assets/payicon/index_order-4.png new file mode 100644 index 00000000..b31e5987 Binary files /dev/null and b/src/assets/payicon/index_order-4.png differ diff --git a/src/assets/payicon/shopLogo.png b/src/assets/payicon/shopLogo.png new file mode 100644 index 00000000..ddc2ec09 Binary files /dev/null and b/src/assets/payicon/shopLogo.png differ diff --git a/src/assets/style/common.css b/src/assets/style/common.css new file mode 100644 index 00000000..04ddb851 --- /dev/null +++ b/src/assets/style/common.css @@ -0,0 +1,78 @@ +.incomPart .ant-steps { + padding: 0 10%; +} +.incomPart .ant-steps .ant-steps-item { + height: 2.6042vw; + display: flex; + align-items: center; +} +.incomPart .ant-steps .ant-steps-item .ant-steps-item-icon { + width: 1.6667vw; + height: 1.6667vw; + font-size: 14px; + line-height: 1.5; + border-radius: 1.25vw; +} +.incomPart .ant-steps .ant-steps-item .ant-steps-item-title { + font-size: 14px; + line-height: 1.6667vw; +} +.incomPart .ant-steps .ant-steps-item.ant-steps-item-process .ant-steps-item-icon { + background-color: #1890ff; + border-color: #1890ff; +} +.incomPart .ant-steps .ant-steps-item.ant-steps-item-finish .ant-steps-item-icon .ant-steps-icon { + color: #1890ff; + border-color: #1890ff; +} +.stepPanel { + width: 100%; + margin-top: 1.5625vw; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.stepPanel .panelItem { + width: 100%; + margin-top: 1.5625vw; +} +.stepPanel .panelItem .lineBox { + height: 1.5625vw; + margin: 1.0417vw 0px; + border-top: 1px solid #f6f6f6; + position: relative; +} +.stepPanel .panelItem .lineBox h3 { + height: 100%; + color: #1890ff; + position: absolute; + top: -50%; + left: 10%; + letter-spacing: 2px; + padding: 0px 0.5208vw; + background-color: #ffffff; +} +.stepPanel .panelItem .panelItemDetail { + width: 100%; +} +.dialogRow { + max-height: 60vh; +} +.dialogRow .ant-row { + padding-left: 1.6667vw; + margin-bottom: 1.0417vw; +} +.dialogRow .ant-row .gutter-row .gutterItem { + display: flex; + gap: 0.5208vw; +} +.dialogRow .ant-row .gutter-row .gutterItem .leftTitle { + min-width: 7.8125vw; + font-size: 14px; + color: #596780; + font-weight: 600; +} +.dialogRow .ant-row .gutter-row .gutterItem .rightContent { + flex: 1; +} diff --git a/src/assets/style/common.less b/src/assets/style/common.less new file mode 100644 index 00000000..4c1dadf4 --- /dev/null +++ b/src/assets/style/common.less @@ -0,0 +1,99 @@ +// 进件部分的公共样式 +.incomPart { + .ant-steps { + padding: 0 10%; + .ant-steps-item { + height: 2.6042vw; + display: flex; + align-items: center; + .ant-steps-item-icon { + width: 1.6667vw; + height: 1.6667vw; + font-size: 14px; + line-height: 1.5; + border-radius: 1.25vw; + } + .ant-steps-item-title { + font-size: 14px; + line-height: 1.6667vw; + } + &.ant-steps-item-process { + .ant-steps-item-icon { + background-color: #1890ff; + border-color: #1890ff; + } + } + &.ant-steps-item-finish { + .ant-steps-item-icon { + .ant-steps-icon { + color: #1890ff; + border-color: #1890ff; + } + } + } + } + } +} +.stepPanel { + width: 100%; + margin-top: 1.5625vw; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + .panelItem { + width: 100%; + margin-top: 1.5625vw; + .lineBox { + height: 1.5625vw; + margin: 1.0417vw 0px; + border-top: 1px solid #f6f6f6; + position: relative; + h3 { + height: 100%; + color: #1890ff; + position: absolute; + top: -50%; + left: 10%; + letter-spacing: 2px; + padding: 0px 0.5208vw; + background-color: #ffffff; + } + } + .panelItemDetail { + width: 100%; + .readOcr { + display: flex; + gap: 8px; + align-items: center; + .readOcrBtn { + transform: translateY(28px) + } + } + } + } +} + +//查询表单信息公共样式 +.dialogRow { + max-height: 60vh; + .ant-row { + padding-left: 1.6667vw; + margin-bottom: 1.0417vw; + .gutter-row { + .gutterItem { + display: flex; + gap: 0.5208vw; + .leftTitle { + min-width: 80px; + font-size: 14px; + color: #596780; + font-weight: 600; + } + .rightContent { + flex: 1; + } + } + } + } +} diff --git a/src/components/Bootx/BUpload/BUploadPic.vue b/src/components/Bootx/BUpload/BUploadPic.vue index 160fd382..4529bbac 100644 --- a/src/components/Bootx/BUpload/BUploadPic.vue +++ b/src/components/Bootx/BUpload/BUploadPic.vue @@ -1,3 +1,4 @@ + @@ -75,35 +126,39 @@ width: 100px; height: 100px; } + .img-div { display: flex; - justify-content: center; align-items: center; + justify-content: center; width: 102px; height: 102px; - margin-inline-end: 8px; margin-bottom: 8px; + margin-inline-end: 8px; + transition: border-color 0.3s; + border: 1px dashed rgb(217 217 217 / 0%); + border-radius: 8px; + background-color: rgb(0 0 0 / 2%); text-align: center; vertical-align: top; - background-color: rgba(0, 0, 0, 0.02); - border: 1px dashed rgba(217, 217, 217, 0); - border-radius: 8px; cursor: pointer; - transition: border-color 0.3s; } + .ant-image-mask { - width: 100px; - height: 100px; - position: absolute; - inset: 0; display: flex; + position: absolute; align-items: center; justify-content: center; - color: #fff; - background: rgba(0, 0, 0, 0.5); - cursor: pointer; - opacity: 0; + width: 100px; + height: 100px; transition: opacity 0.3s; + opacity: 0; + background: rgb(0 0 0 / 50%); + color: #fff; + cursor: pointer; + inset: 0; + gap: 16px; + &:hover { opacity: 1; } diff --git a/src/components/registerGlobComp.ts b/src/components/registerGlobComp.ts index 45f46998..230a4b55 100644 --- a/src/components/registerGlobComp.ts +++ b/src/components/registerGlobComp.ts @@ -41,10 +41,10 @@ import { DatePicker, TimePicker, Descriptions, + Transfer, Space, Statistic, Cascader, - Transfer, } from 'ant-design-vue' export function registerGlobComp(app: App) { @@ -90,8 +90,8 @@ export function registerGlobComp(app: App) { app.use(Steps) app.use(Form) app.use(Spin) - app.use(Dropdown) app.use(Transfer) + app.use(Dropdown) app.use(Input) app.use(Statistic) } diff --git a/src/design/public.less b/src/design/public.less index 0323b846..63e6877d 100644 --- a/src/design/public.less +++ b/src/design/public.less @@ -12,12 +12,12 @@ height: 8px; } -// ::-webkit-scrollbar-track { -// background: transparent; -// } +::-webkit-scrollbar-track { + background: transparent; +} ::-webkit-scrollbar-track { - background-color: rgb(0 0 0 / 5%); + // background-color: rgb(0 0 0 / 5%); } ::-webkit-scrollbar-thumb { diff --git a/src/enums/daxpay/daxpayClientEnum.ts b/src/enums/daxpay/daxpayClientEnum.ts index 172c3c2b..eb0c6659 100644 --- a/src/enums/daxpay/daxpayClientEnum.ts +++ b/src/enums/daxpay/daxpayClientEnum.ts @@ -13,7 +13,7 @@ export enum DaxPayClientEnum { MERCHANT = 'dax-pay-merchant', /** - * 服务商端 + * 代理商端 */ - ISV = 'dax-pay-isv', + AGENT = 'dax-pay-agent', } diff --git a/src/enums/daxpay/daxpayEnum.ts b/src/enums/daxpay/daxpayEnum.ts index 47ec0719..7622ea6f 100644 --- a/src/enums/daxpay/daxpayEnum.ts +++ b/src/enums/daxpay/daxpayEnum.ts @@ -10,6 +10,7 @@ export enum ChannelEnum { LESHUA_PAY = 'leshua_pay', VBILL_PAY = 'vbill_pay', ADA_PAY = 'ada_pay', + HKRT_PAY = 'hkrt_pay', } /** @@ -92,14 +93,32 @@ export enum MerchantTypeEnum { COMMON = 'common', /** 特约商户 */ PARTNER = 'partner', - /** 代理商 */ - AGENT = 'agent', +} + +/** + * 服务商状态枚举 + */ +export enum IsvStatusEnum { + /** 停用 */ + DISABLED = 'disabled', + /** 启用 */ + ENABLED = 'enable', } /** * 商户状态枚举 */ export enum MerchantStatusEnum { + /** 禁用 */ + DISABLED = 'disabled', + /** 启用 */ + ENABLED = 'enable', +} + +/** + * 代理商状态枚举 + */ +export enum AgentStatusEnum { /** 启用 */ DISABLED = 'disabled', /** 禁用 */ @@ -199,3 +218,29 @@ export enum AllocReceiverTypeEnum { /** 账号 */ LOGIN_NAME = 'login_name', } + +/** + * 进件申请状态 + */ +export enum IsvApplyStatusEnum { + /** 草稿 */ + DRAFT = 'draft', + /** 预审 = 暂时不用) */ + PRE_TRIAL = 'pre_trial', + /** 预审拒绝 = 暂时不用) */ + PRE_TRIAL_REJECT = 'pre_trial_reject', + /** 申请中 */ + APPLY = 'apply', + /** 驳回 */ + REJECT = 'reject', + /** 待签署 */ + SIGN = 'sign', + /** 开通中 */ + OPENING = 'opening', + /** 通过 */ + PASS = 'pass', + /** 已生成进件商户 */ + GENERATED = 'generated', + /** 关闭 */ + CLOSED = 'closed', +} diff --git a/src/enums/pageEnum.ts b/src/enums/pageEnum.ts index 84efe272..b7549602 100644 --- a/src/enums/pageEnum.ts +++ b/src/enums/pageEnum.ts @@ -3,8 +3,12 @@ export enum PageEnum { BASE_LOGIN = '/login', // 首页 BASE_HOME = '/', - // 服务端登陆后主页 - ADMIN_HOME = '/dashboard', + // 运营端登陆后主页 + ADMIN_HOME = '/admin/dashboard', + // 商户端登录后首页 + MERCHANT_HOME = '/merchant/dashboard', + // 代理商端登录后首页 + AGENT_HOME = '/agent/dashboard', // 错误页 ERROR_PAGE = '/exception', } diff --git a/src/hooks/bootx/useFilePlatform.ts b/src/hooks/bootx/useFilePlatform.ts index 39c6fa15..1f97943a 100644 --- a/src/hooks/bootx/useFilePlatform.ts +++ b/src/hooks/bootx/useFilePlatform.ts @@ -14,22 +14,31 @@ async function getFilePlatforms(): Promise { return await platformStore.initFilePlatform() } } +/** + * 获取存储平台参数 + */ +async function getFilePlatform(platform): Promise { + const platforms = await getFilePlatforms() + return platforms.filter((o) => { + return platform ? platform === o.type : o.defaultPlatform + })?.[0] +} /** - * 获取地址, 如果不传输自动使用默认平台 - * @param fileUrl 文件保存的url地址 - * @param platform 存储平台类型编码 + * 获取默认上传平台 */ -function getFileUrl(fileUrl?: string, platform?: string) { - const platforms = platformStore.getFilePlatforms - const item = platforms.filter((o) => { - return platform ? platform === o.type : o.defaultPlatform - }) - if (item && item.length > 0) { - return item[0].url + fileUrl - } else { - return '' - } +async function getUploadPlatform(): Promise { + const uploadPlatform = platformStore.getUploadPlatform + return getFilePlatform(uploadPlatform) +} + +/** + * 获取文件预览地址 + * @param fileUrl 文件保存的名称 + */ +function getFileUrl(fileUrl?: string) { + fileUrl = fileUrl?.startsWith('/') ? fileUrl.slice(1) : fileUrl + return `${import.meta.env.VITE_GLOB_API_URL}/file/download/${fileUrl}` } /** @@ -40,5 +49,8 @@ export function useFilePlatform() { getFilePlatforms().then() return { getFileUrl, + getFilePlatform, + getUploadPlatform, } } +// platformStore.initUploadPlatform().then() diff --git a/src/hooks/bootx/useUpload.ts b/src/hooks/bootx/useUpload.ts index 45c050e9..d976c34c 100644 --- a/src/hooks/bootx/useUpload.ts +++ b/src/hooks/bootx/useUpload.ts @@ -5,7 +5,11 @@ import { getAppEnvConfig } from '@/utils/env' const useUserStore = useUserStoreWithOut() const { VITE_GLOB_API_URL, VITE_GLOB_API_URL_PREFIX } = getAppEnvConfig() -export function useUpload(uploadUrl: string) { +/** + * 使用hook, 传入的地址是本地上传地址, 基本上读取文件时会使用 + */ +export function useUpload(uploadUrl = '/') { + const { VITE_GLOB_APP_CLIENT } = getAppEnvConfig() /** * 从 localstorage 获取 token */ @@ -13,6 +17,7 @@ export function useUpload(uploadUrl: string) { const token = useUserStore.getToken return { AccessToken: token, + 'x-client-code': VITE_GLOB_APP_CLIENT, } }) /** @@ -21,9 +26,59 @@ export function useUpload(uploadUrl: string) { const uploadAction = computed(() => { return VITE_GLOB_API_URL + VITE_GLOB_API_URL_PREFIX + uploadUrl }) + /** + * 上传文件到OSS + * @param file + * @param ossUploadUrl + * @param uploadHeader + * @param method + */ + function uploadFileToOss( + file: Blob, + ossUploadUrl: string, + uploadHeader: any, + method: string = 'PUT', + ): Promise { + // 发送PUT请求上传文件 + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest() + //element-ui默认使用post提交,但是我们生成的url需要使用 put 提交 + //需要指定 put 直传,以及this.uploadUrl(后端返回的url) + xhr.open(method, ossUploadUrl, true) + //设置上传文件的类型 + xhr.onreadystatechange = () => { + if (xhr.readyState === 4) { + if (xhr.status === 200) { + resolve(xhr.response) + //进入到这里就表明上传成功了 + } else { + reject(xhr.statusText) + } + } + } + xhr.onerror = () => { + reject(xhr.statusText) + } + xhr.setRequestHeader('Content-Type', uploadHeader['Content-Type']) + + //发送 + xhr.send(file) //或者 file + }) + } + + /** + * 获取文件预览地址 + * @param fileUrl 文件保存的名称 + */ + function getFileUrl(fileUrl?: string) { + fileUrl = fileUrl?.startsWith('/') ? fileUrl.slice(1) : fileUrl + return `${import.meta.env.VITE_GLOB_API_URL}/file/download/${fileUrl}` + } return { tokenHeader, uploadAction, + getFileUrl, + uploadFileToOss, } } diff --git a/src/layouts/default/header/components/ModifyPasswordModel.vue b/src/layouts/default/header/components/ModifyPasswordModel.vue new file mode 100644 index 00000000..d6e105ec --- /dev/null +++ b/src/layouts/default/header/components/ModifyPasswordModel.vue @@ -0,0 +1,133 @@ + + + + diff --git a/src/layouts/default/header/components/user-dropdown/index.vue b/src/layouts/default/header/components/user-dropdown/index.vue index 28bbd13e..6d41933b 100644 --- a/src/layouts/default/header/components/user-dropdown/index.vue +++ b/src/layouts/default/header/components/user-dropdown/index.vue @@ -8,31 +8,33 @@ - + @@ -75,13 +85,13 @@ @prefix-cls: ~'@{namespace}-header-user-dropdown'; .@{prefix-cls} { + align-items: center; height: @header-height; padding: 0 0 0 10px; padding-right: 10px; overflow: hidden; font-size: 12px; cursor: pointer; - align-items: center; img { width: 24px; @@ -116,6 +126,7 @@ color: @header-light-desc-color; } } + &-dropdown-overlay { .ant-dropdown-menu-item { min-width: 160px; diff --git a/src/router/routes/index.ts b/src/router/routes/index.ts index c2a6e91e..fb841e4c 100644 --- a/src/router/routes/index.ts +++ b/src/router/routes/index.ts @@ -1,10 +1,10 @@ -import type {AppRouteModule, AppRouteRecordRaw} from '@/router/types' +import type { AppRouteModule, AppRouteRecordRaw } from '@/router/types' -import {PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE} from '@/router/routes/basic' +import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '@/router/routes/basic' -import {PageEnum} from '@/enums/pageEnum' -import {getAppEnvConfig} from '@/utils/env' -import {DaxPayClientEnum} from "@/enums/daxpay/daxpayClientEnum"; +import { PageEnum } from '@/enums/pageEnum' +import { getAppEnvConfig } from '@/utils/env' +import { DaxPayClientEnum } from '@/enums/daxpay/daxpayClientEnum' // import.meta.glob() 直接引入所有的模块 Vite 独有的功能 const modules = import.meta.glob('./modules/**/*.ts', { eager: true }) @@ -18,14 +18,23 @@ Object.keys(modules).forEach((key) => { routeModuleList.push(...modList) }) +const redirectPage = () => { + if (VITE_GLOB_APP_CLIENT === DaxPayClientEnum.ADMIN) { + return PageEnum.ADMIN_HOME + } + if (VITE_GLOB_APP_CLIENT === DaxPayClientEnum.AGENT) { + return PageEnum.AGENT_HOME + } + return PageEnum.MERCHANT_HOME +} + export const asyncRoutes = [PAGE_NOT_FOUND_ROUTE, ...routeModuleList] // 根路由 export const RootRoute: AppRouteRecordRaw = { path: '/', name: 'Root', - redirect: - VITE_GLOB_APP_CLIENT === DaxPayClientEnum.ADMIN ? PageEnum.ADMIN_HOME : PageEnum.MERCHANT_HOME, + redirect: redirectPage(), meta: { title: 'Root', }, diff --git a/src/router/routes/modules/dashboard.ts b/src/router/routes/modules/dashboard.ts index 62f0041e..3d08d703 100644 --- a/src/router/routes/modules/dashboard.ts +++ b/src/router/routes/modules/dashboard.ts @@ -13,7 +13,7 @@ const Dashboard: AppRouteModule = { }, children: [ { - path: '/dashboard', + path: '/admin/dashboard', name: 'AdminDashboard', component: () => import('@/views/daxpay/admin/dashboard/index.vue'), meta: { diff --git a/src/store/modules/dict.ts b/src/store/modules/dict.ts index 26fadf1e..cddb629e 100644 --- a/src/store/modules/dict.ts +++ b/src/store/modules/dict.ts @@ -1,7 +1,6 @@ import { defineStore } from 'pinia' import { findAllByEnable } from '@/views/baseapi/dict/DictItem.api' import { Dict } from '#/store' -import { store } from '@/store' interface DictState { dict: Dict[] diff --git a/src/store/modules/filePlatform.ts b/src/store/modules/filePlatform.ts index cb48b2da..6a1b7a5c 100644 --- a/src/store/modules/filePlatform.ts +++ b/src/store/modules/filePlatform.ts @@ -1,35 +1,52 @@ import { defineStore } from 'pinia' import { FilePlatform } from '#/store' -import { findAll } from '@/views/baseapi/file/platform/FilePlatform.api' +import { findAll, getDefaultUploadPlatform } from '@/views/baseapi/file/platform/FilePlatform.api' interface FilePlatformState { filePlatform: FilePlatform[] + uploadPlatform: string } export const useFilePlatformStore = defineStore({ id: 'app-file-platform', state: (): FilePlatformState => ({ filePlatform: [], + uploadPlatform: '', }), getters: { getFilePlatforms(): FilePlatform[] { return this.filePlatform }, + getUploadPlatform(): string { + return this.uploadPlatform + }, }, actions: { /** - * 初始化存储平台, 并列表 + * 初始化存储平台列表 */ async initFilePlatform() { const { data } = await findAll() + // 初始化列表 this.filePlatform = data.map((o) => { return { type: o.type, url: o.url, defaultPlatform: o.defaultPlatform, + frontendUpload: o.frontendUpload, } as FilePlatform }) console.log('初始化存储平台') return this.filePlatform }, + + /** + * 获取默认上传平台 + */ + async initUploadPlatform() { + const { data } = await getDefaultUploadPlatform() + this.uploadPlatform = data + console.log(`默认上传存储平台为: ${this.uploadPlatform}`) + return data + }, }, }) diff --git a/src/utils/env.ts b/src/utils/env.ts index a1081772..c45d6885 100644 --- a/src/utils/env.ts +++ b/src/utils/env.ts @@ -87,10 +87,10 @@ export function isAdmin() { } /** - * 是否为服务商端 + * 是否为代理商端 */ -export function isIsv() { - return import.meta.env.VITE_GLOB_APP_CLIENT === DaxPayClientEnum.ISV +export function isAgent() { + return import.meta.env.VITE_GLOB_APP_CLIENT === DaxPayClientEnum.AGENT } /** diff --git a/src/views/baseapi/dict/DictItemList.vue b/src/views/baseapi/dict/DictItemList.vue index dfe75066..9d40ff7c 100644 --- a/src/views/baseapi/dict/DictItemList.vue +++ b/src/views/baseapi/dict/DictItemList.vue @@ -33,7 +33,7 @@ - + - + - + + + + +