Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
eecfb90a
authored
Aug 19, 2024
by
芋道源码
Committed by
Gitee
Aug 19, 2024
Browse files
Options
Browse Files
Download
Plain Diff
!504 完善一些 MALL TODO
Merge pull request !504 from puhui999/dev-crm
parents
fc5e37dd
43ad93cd
Hide whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
579 additions
and
413 deletions
+579
-413
src/api/ai/mindmap/index.ts
+1
-1
src/components/DictTag/src/DictTag.vue
+2
-2
src/components/DiyEditor/components/mobile/PromotionCombination/index.vue
+12
-12
src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue
+12
-12
src/layout/components/TagsView/src/TagsView.vue
+32
-26
src/store/modules/app.ts
+1
-1
src/views/Login/SocialLogin.vue
+3
-3
src/views/Login/components/QrCodeForm.vue
+1
-1
src/views/ai/mindmap/index/components/Right.vue
+7
-3
src/views/ai/mindmap/index/index.vue
+2
-2
src/views/ai/mindmap/manager/index.vue
+32
-26
src/views/ai/write/index/components/Left.vue
+17
-17
src/views/mall/home/components/OperationDataCard.vue
+2
-2
src/views/mall/product/spu/components/SkuList.vue
+9
-9
src/views/mall/product/spu/form/ProductAttributes.vue
+5
-5
src/views/mall/product/spu/form/ProductPropertyAddForm.vue
+3
-3
src/views/mall/product/spu/form/SkuForm.vue
+1
-1
src/views/mall/trade/afterSale/index.vue
+1
-1
src/views/member/user/components/UserBalanceUpdateForm.vue
+144
-0
src/views/member/user/components/UserLevelUpdateForm.vue
+0
-0
src/views/member/user/components/UserPointUpdateForm.vue
+8
-7
src/views/member/user/components/balance-list.vue
+0
-14
src/views/member/user/detail/UserAccountInfo.vue
+11
-11
src/views/member/user/detail/UserAftersaleList.vue
+9
-8
src/views/member/user/detail/UserBalanceList.vue
+13
-13
src/views/member/user/detail/index.vue
+7
-7
src/views/member/user/index.vue
+8
-4
src/views/pay/app/components/channel/AlipayChannelForm.vue
+57
-54
src/views/pay/app/components/channel/MockChannelForm.vue
+3
-3
src/views/pay/app/components/channel/WalletChannelForm.vue
+3
-3
src/views/pay/app/components/channel/WeixinChannelForm.vue
+33
-33
src/views/pay/app/index.vue
+42
-42
src/views/pay/wallet/transaction/WalletTransactionList.vue
+24
-13
vite.config.ts
+74
-74
No files found.
src/api/ai/mindmap/index.ts
View file @
eecfb90a
import
{
getAccessToken
}
from
'@/utils/auth'
import
{
fetchEventSource
}
from
'@microsoft/fetch-event-source'
import
{
config
}
from
'@/config/axios/config'
import
request
from
'@/config/axios'
import
request
from
'@/config/axios'
// AI 思维导图 VO
// AI 思维导图 VO
export
interface
MindMapVO
{
...
...
src/components/DictTag/src/DictTag.vue
View file @
eecfb90a
<
script
lang=
"tsx"
>
import
{
defineComponent
,
PropType
,
computed
}
from
'vue'
import
{
computed
,
defineComponent
,
PropType
}
from
'vue'
import
{
isHexColor
}
from
'@/utils/color'
import
{
ElTag
}
from
'element-plus'
import
{
DictDataType
,
getDictOptions
}
from
'@/utils/dict'
import
{
isArray
,
is
String
,
isNumber
,
isBoolean
}
from
'@/utils/is'
import
{
isArray
,
is
Boolean
,
isNumber
,
isString
}
from
'@/utils/is'
export
default
defineComponent
({
name
:
'DictTag'
,
...
...
src/components/DiyEditor/components/mobile/PromotionCombination/index.vue
View file @
eecfb90a
<
template
>
<el-scrollbar
class=
"z-1 min-h-30px"
wrap-class=
"w-full"
ref=
"containerRef
"
>
<el-scrollbar
ref=
"containerRef"
class=
"z-1 min-h-30px"
wrap-class=
"w-full
"
>
<!-- 商品网格 -->
<div
class=
"grid overflow-x-auto"
:style=
"
{
gridGap: `${property.space}px`,
gridTemplateColumns,
width: scrollbarWidth
}"
class="grid overflow-x-auto"
>
<!-- 商品 -->
<div
class=
"relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
v-for=
"(spu, index) in spuList"
:key=
"index"
:style=
"
{
borderTopLeftRadius: `${property.borderRadiusTop}px`,
borderTopRightRadius: `${property.borderRadiusTop}px`,
borderBottomLeftRadius: `${property.borderRadiusBottom}px`,
borderBottomRightRadius: `${property.borderRadiusBottom}px`
}"
v-for="(spu, index) in spuList"
:key="index"
class="relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
>
<!-- 角标 -->
<div
v-if=
"property.badge.show"
class=
"absolute left-0 top-0 z-1 items-center justify-center"
>
<el-image
fit=
"cover"
:src=
"property.badge.imgUrl"
class=
"h-26px w-38px
"
/>
<el-image
:src=
"property.badge.imgUrl"
class=
"h-26px w-38px"
fit=
"cover
"
/>
</div>
<!-- 商品封面图 -->
<el-image
fit=
"cover"
:src=
"spu.picUrl"
:style=
"
{ width: imageSize, height: imageSize }
" />
<el-image
:src=
"spu.picUrl"
:style=
"
{ width: imageSize, height: imageSize }" fit="cover
" />
<div
:class=
"[
'flex flex-col gap-8px p-8px box-border',
...
...
@@ -42,8 +42,8 @@
<!-- 商品名称 -->
<div
v-if=
"property.fields.name.show"
class=
"truncate text-12px"
:style=
"
{ color: property.fields.name.color }"
class="truncate text-12px"
>
{{
spu
.
name
}}
</div>
...
...
@@ -51,8 +51,8 @@
<!-- 商品价格 -->
<span
v-if=
"property.fields.price.show"
class=
"text-12px"
:style=
"
{ color: property.fields.price.color }"
class="text-12px"
>
¥
{{
fenToYuan
(
spu
.
combinationPrice
||
spu
.
price
||
0
)
}}
</span>
...
...
@@ -62,11 +62,11 @@
</div>
</el-scrollbar>
</
template
>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
{
PromotionCombinationProperty
}
from
'./config'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
*
as
CombinationActivityApi
from
'@/api/mall/promotion/combination/combinationActivity'
import
{
Spu
}
from
'@/api/mall/product/spu'
import
*
as
CombinationActivityApi
from
'@/api/mall/promotion/combination/combinationActivity'
import
{
CombinationProductVO
}
from
'@/api/mall/promotion/combination/combinationActivity'
import
{
fenToYuan
}
from
'@/utils'
...
...
@@ -132,4 +132,4 @@ onMounted(() => {
})
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
<
style
lang=
"scss"
scoped
></
style
>
src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue
View file @
eecfb90a
<
template
>
<el-scrollbar
class=
"z-1 min-h-30px"
wrap-class=
"w-full"
ref=
"containerRef
"
>
<el-scrollbar
ref=
"containerRef"
class=
"z-1 min-h-30px"
wrap-class=
"w-full
"
>
<!-- 商品网格 -->
<div
class=
"grid overflow-x-auto"
:style=
"
{
gridGap: `${property.space}px`,
gridTemplateColumns,
width: scrollbarWidth
}"
class="grid overflow-x-auto"
>
<!-- 商品 -->
<div
class=
"relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
v-for=
"(spu, index) in spuList"
:key=
"index"
:style=
"
{
borderTopLeftRadius: `${property.borderRadiusTop}px`,
borderTopRightRadius: `${property.borderRadiusTop}px`,
borderBottomLeftRadius: `${property.borderRadiusBottom}px`,
borderBottomRightRadius: `${property.borderRadiusBottom}px`
}"
v-for="(spu, index) in spuList"
:key="index"
class="relative box-content flex flex-row flex-wrap overflow-hidden bg-white"
>
<!-- 角标 -->
<div
v-if=
"property.badge.show"
class=
"absolute left-0 top-0 z-1 items-center justify-center"
>
<el-image
fit=
"cover"
:src=
"property.badge.imgUrl"
class=
"h-26px w-38px
"
/>
<el-image
:src=
"property.badge.imgUrl"
class=
"h-26px w-38px"
fit=
"cover
"
/>
</div>
<!-- 商品封面图 -->
<el-image
fit=
"cover"
:src=
"spu.picUrl"
:style=
"
{ width: imageSize, height: imageSize }
" />
<el-image
:src=
"spu.picUrl"
:style=
"
{ width: imageSize, height: imageSize }" fit="cover
" />
<div
:class=
"[
'flex flex-col gap-8px p-8px box-border',
...
...
@@ -42,8 +42,8 @@
<!-- 商品名称 -->
<div
v-if=
"property.fields.name.show"
class=
"truncate text-12px"
:style=
"
{ color: property.fields.name.color }"
class="truncate text-12px"
>
{{
spu
.
name
}}
</div>
...
...
@@ -51,8 +51,8 @@
<!-- 商品价格 -->
<span
v-if=
"property.fields.price.show"
class=
"text-12px"
:style=
"
{ color: property.fields.price.color }"
class="text-12px"
>
¥
{{
fenToYuan
(
spu
.
seckillPrice
||
spu
.
price
||
0
)
}}
</span>
...
...
@@ -62,11 +62,11 @@
</div>
</el-scrollbar>
</
template
>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
{
PromotionSeckillProperty
}
from
'./config'
import
*
as
ProductSpuApi
from
'@/api/mall/product/spu'
import
*
as
SeckillActivityApi
from
'@/api/mall/promotion/seckill/seckillActivity'
import
{
Spu
}
from
'@/api/mall/product/spu'
import
*
as
SeckillActivityApi
from
'@/api/mall/promotion/seckill/seckillActivity'
import
{
SeckillProductVO
}
from
'@/api/mall/promotion/seckill/seckillActivity'
import
{
fenToYuan
}
from
'@/utils'
...
...
@@ -132,4 +132,4 @@ onMounted(() => {
})
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
<
style
lang=
"scss"
scoped
></
style
>
src/layout/components/TagsView/src/TagsView.vue
View file @
eecfb90a
<
script
lang=
"ts"
setup
>
import
{
onMounted
,
watch
,
computed
,
unref
,
ref
,
nextTick
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
import
{
computed
,
nextTick
,
onMounted
,
ref
,
unref
,
watch
}
from
'vue'
import
type
{
RouteLocationNormalizedLoaded
,
RouterLinkProps
}
from
'vue-router'
import
{
useRouter
}
from
'vue-router'
import
{
usePermissionStore
}
from
'@/store/modules/permission'
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
import
{
useAppStore
}
from
'@/store/modules/app'
...
...
@@ -273,16 +273,28 @@ watch(
@click="move(-200)"
>
<Icon
icon=
"ep:d-arrow-left"
color=
"var(--el-text-color-placeholder)"
:hover-color=
"isDark ? '#fff' : 'var(--el-color-black)'"
color=
"var(--el-text-color-placeholder)"
icon=
"ep:d-arrow-left"
/>
</span>
<div
class=
"flex-1 overflow-hidden"
>
<ElScrollbar
ref=
"scrollbarRef"
class=
"h-full"
@
scroll=
"scroll"
>
<div
class=
"h-full flex"
>
<ContextMenu
v-for=
"item in visitedViews"
:key=
"item.fullPath"
:ref=
"itemRefs.set"
:class=
"[
`$
{prefixCls}__item`,
tagsViewImmerse ? `${prefixCls}__item--immerse` : '',
tagsViewIcon ? `${prefixCls}__item--icon` : '',
tagsViewImmerse
&&
tagsViewIcon ? `${prefixCls}__item--immerse--icon` : '',
item?.meta?.affix ? `${prefixCls}__item--affix` : '',
{
'is-active': isActive(item)
}
]"
:schema="[
{
icon: 'ep:refresh',
...
...
@@ -340,26 +352,14 @@ watch(
}
}
]"
v-for="item in visitedViews"
:key="item.fullPath"
:tag-item="item"
:class="[
`${prefixCls}__item`,
tagsViewImmerse ? `${prefixCls}__item--immerse` : '',
tagsViewIcon ? `${prefixCls}__item--icon` : '',
tagsViewImmerse
&&
tagsViewIcon ? `${prefixCls}__item--immerse--icon` : '',
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 items-center justify-center whitespace-nowrap pl-15px $
{prefixCls}__item--label`"
@click="navigate"
>
<Icon
v-if=
"
...
...
@@ -376,9 +376,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>
...
...
@@ -394,9 +394,9 @@ watch(
@click="move(200)"
>
<Icon
icon=
"ep:d-arrow-right"
color=
"var(--el-text-color-placeholder)"
:hover-color=
"isDark ? '#fff' : 'var(--el-color-black)'"
color=
"var(--el-text-color-placeholder)"
icon=
"ep:d-arrow-right"
/>
</span>
<span
...
...
@@ -405,13 +405,12 @@ watch(
@click="refreshSelectedTag(selectedTag)"
>
<Icon
icon=
"ep:refresh-right"
color=
"var(--el-text-color-placeholder)"
:hover-color=
"isDark ? '#fff' : 'var(--el-color-black)'"
color=
"var(--el-text-color-placeholder)"
icon=
"ep:refresh-right"
/>
</span>
<ContextMenu
trigger=
"click"
:schema=
"[
{
icon: 'ep:refresh',
...
...
@@ -463,15 +462,16 @@ watch(
}
}
]"
trigger="click"
>
<span
:class=
"tagsViewImmerse ? '' : `$
{prefixCls}__tool`"
class="block h-[var(--tags-view-height)] w-[var(--tags-view-height)] flex cursor-pointer items-center justify-center"
>
<Icon
icon=
"ep:menu"
color=
"var(--el-text-color-placeholder)"
:hover-color=
"isDark ? '#fff' : 'var(--el-color-black)'"
color=
"var(--el-text-color-placeholder)"
icon=
"ep:menu"
/>
</span>
</ContextMenu>
...
...
@@ -531,6 +531,7 @@ $prefix-cls: #{$namespace}-tags-view;
display
:
none
;
transform
:
translate
(
0
,
-50%
);
}
&
:not
(.
#
{
$prefix-cls
}
__item--affix
)
:hover
{
.#{$prefix-cls
}
__item--close
{
display
:
block
;
...
...
@@ -552,6 +553,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
;
...
...
@@ -566,9 +568,11 @@ $prefix-cls: #{$namespace}-tags-view;
border
:
1px
solid
transparent
;
-webkit-mask-box-image
:
url("data:image/svg+xml,%3Csvg width='68' height='34' viewBox='0 0 68 34' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='m27,0c-7.99582,0 -11.95105,0.00205 -12,12l0,6c0,8.284 -0.48549,16.49691 -8.76949,16.49691l54.37857,-0.11145c-8.284,0 -8.60908,-8.10146 -8.60908,-16.38546l0,-6c0.11145,-12.08445 -4.38441,-12 -12,-12l-13,0z' fill='%23409eff'/%3E%3C/svg%3E")
12
27
15
;
.#{$prefix-cls
}
__item--label
{
padding-left
:
35px
;
}
.
#
{
$prefix-cls
}
__item--close
{
right
:
20px
;
}
...
...
@@ -582,6 +586,7 @@ $prefix-cls: #{$namespace}-tags-view;
&:hover
{
color
:
var
(
--el-color-white
);
background-color
:
var
(
--el-color-primary
);
.#{$prefix-cls
}
__item--close
{
:deep(span)
{
color
:
var
(
--el-color-white
)
!important
;
...
...
@@ -615,6 +620,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
;
...
...
src/store/modules/app.ts
View file @
eecfb90a
import
{
defineStore
}
from
'pinia'
import
{
store
}
from
'../index'
import
{
setCssVar
,
humpToUnderline
}
from
'@/utils'
import
{
humpToUnderline
,
setCssVar
}
from
'@/utils'
import
{
ElMessage
}
from
'element-plus'
import
{
CACHE_KEY
,
useCache
}
from
'@/hooks/web/useCache'
import
{
ElementPlusSize
}
from
'@/types/elementPlus'
...
...
src/views/Login/SocialLogin.vue
View file @
eecfb90a
...
...
@@ -114,9 +114,9 @@
</el-checkbox>
</el-col>
<el-col
:offset=
"6"
:span=
"12"
>
<el-link
style=
"float: right"
type=
"primary"
>
{{
t
(
'login.forgetPassword'
)
}}
</el-link>
<el-link
style=
"float: right"
type=
"primary"
>
{{
t
(
'login.forgetPassword'
)
}}
</el-link>
</el-col>
</el-row>
</el-form-item>
...
...
src/views/Login/components/QrCodeForm.vue
View file @
eecfb90a
<
template
>
<el-row
class=
"login-form"
v-show=
"getShow
"
style=
"margin-right: -10px; margin-left: -10px"
>
<el-row
v-show=
"getShow"
class=
"login-form
"
style=
"margin-right: -10px; margin-left: -10px"
>
<el-col
:span=
"24"
style=
"padding-right: 10px; padding-left: 10px"
>
<LoginFormTitle
style=
"width: 100%"
/>
</el-col>
...
...
src/views/ai/mindmap/index/components/Right.vue
View file @
eecfb90a
...
...
@@ -4,7 +4,7 @@
<h3
class=
"m-0 px-7 shrink-0 flex items-center justify-between"
>
<span>
思维导图预览
</span>
<!-- 展示在右上角 -->
<el-button
type=
"primary"
v-show=
"isEnd"
@
click=
"downloadImage"
size=
"small
"
>
<el-button
v-show=
"isEnd"
size=
"small"
type=
"primary"
@
click=
"downloadImage
"
>
<template
#
icon
>
<Icon
icon=
"ph:copy-bold"
/>
</
template
>
...
...
@@ -20,14 +20,14 @@
</div>
<div
ref=
"mindMapRef"
class=
"wh-full"
>
<svg
ref=
"svgRef"
class=
"w-full"
:style=
"{ height: `${contentAreaHeight}px` }
"
/>
<svg
ref=
"svgRef"
:style=
"{ height: `${contentAreaHeight}px` }"
class=
"w-full
"
/>
<div
ref=
"toolBarRef"
class=
"absolute bottom-[10px] right-5"
></div>
</div>
</div>
</el-card>
</template>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
{
Markmap
}
from
'markmap-view'
import
{
Transformer
}
from
'markmap-lib'
import
{
Toolbar
}
from
'markmap-toolbar'
...
...
@@ -137,6 +137,7 @@ defineExpose({
height
:
0
;
}
}
.my-card
{
display
:
flex
;
flex-direction
:
column
;
...
...
@@ -149,13 +150,16 @@ defineExpose({
@extend
.hide-scroll-bar;
}
}
//
markmap
的
tool
样式覆盖
:deep
(
.markmap
)
{
width
:
100%
;
}
:deep
(
.mm-toolbar-brand
)
{
display
:
none
;
}
:deep
(
.mm-toolbar
)
{
display
:
flex
;
flex-direction
:
row
;
...
...
src/views/ai/mindmap/index/index.vue
View file @
eecfb90a
...
...
@@ -3,9 +3,9 @@
<!--表单区域-->
<Left
ref=
"leftRef"
:is-generating=
"isGenerating"
@
submit=
"submit"
@
direct-generate=
"directGenerate"
:is-generating=
"isGenerating"
/>
<!--右边生成思维导图区域-->
<Right
...
...
@@ -18,7 +18,7 @@
</div>
</
template
>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
Left
from
'./components/Left.vue'
import
Right
from
'./components/Right.vue'
import
{
AiMindMapApi
,
AiMindMapGenerateReqVO
}
from
'@/api/ai/mindmap'
...
...
src/views/ai/mindmap/manager/index.vue
View file @
eecfb90a
...
...
@@ -2,18 +2,18 @@
<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=
"userId"
>
<el-select
v-model=
"queryParams.userId"
class=
"!w-240px"
clearable
placeholder=
"请输入用户编号"
class=
"!w-240px"
>
<el-option
v-for=
"item in userList"
...
...
@@ -26,58 +26,64 @@
<el-form-item
label=
"提示词"
prop=
"prompt"
>
<el-input
v-model=
"queryParams.prompt"
placeholder=
"请输入提示词
"
class=
"!w-240px
"
clearable
placeholder=
"请输入提示词"
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</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"
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>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:s
tripe=
"true"
:show-overflow-tooltip
=
"true"
>
<el-table-column
label=
"编号"
align=
"center"
prop=
"id"
width=
"180"
fixed=
"left
"
/>
<el-table-column
label=
"用户"
align=
"center
"
prop=
"userId"
width=
"180"
>
<el-table
v-loading=
"loading"
:data=
"list"
:s
how-overflow-tooltip=
"true"
:stripe
=
"true"
>
<el-table-column
align=
"center"
fixed=
"left"
label=
"编号"
prop=
"id"
width=
"180
"
/>
<el-table-column
align=
"center"
label=
"用户
"
prop=
"userId"
width=
"180"
>
<template
#
default=
"scope"
>
<span>
{{
userList
.
find
((
item
)
=>
item
.
id
===
scope
.
row
.
userId
)?.
nickname
}}
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"提示词"
align=
"center
"
prop=
"prompt"
width=
"180"
/>
<el-table-column
label=
"思维导图"
align=
"center"
prop=
"generatedContent"
min-width=
"300
"
/>
<el-table-column
label=
"模型"
align=
"center
"
prop=
"model"
width=
"180"
/>
<el-table-column
align=
"center"
label=
"提示词
"
prop=
"prompt"
width=
"180"
/>
<el-table-column
align=
"center"
label=
"思维导图"
min-width=
"300"
prop=
"generatedContent
"
/>
<el-table-column
align=
"center"
label=
"模型
"
prop=
"model"
width=
"180"
/>
<el-table-column
label=
"创建时间
"
:formatter=
"dateFormatter
"
align=
"center"
label=
"创建时间"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
<el-table-column
label=
"错误信息"
align=
"center
"
prop=
"errorMessage"
/>
<el-table-column
label=
"操作"
align=
"center"
width=
"120"
fixed=
"right
"
>
<el-table-column
align=
"center"
label=
"错误信息
"
prop=
"errorMessage"
/>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
width=
"120
"
>
<
template
#
default=
"scope"
>
<el-button
link
type=
"primary"
@
click=
"openPreview(scope.row)"
>
预览
</el-button>
<el-button
link
type=
"primary"
@
click=
"openPreview(scope.row)"
>
预览
</el-button>
<el-button
v-hasPermi=
"['ai:mind-map:delete']"
link
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['ai:mind-map:delete']"
>
删除
</el-button>
...
...
@@ -86,9 +92,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>
...
...
@@ -105,7 +111,7 @@
</el-drawer>
</template>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
{
AiMindMapApi
,
MindMapVO
}
from
'@/api/ai/mindmap'
import
*
as
UserApi
from
'@/api/system/user'
...
...
src/views/ai/write/index/components/Left.vue
View file @
eecfb90a
...
...
@@ -2,8 +2,8 @@
<!-- 定义 tab 组件:撰写/回复等 -->
<DefineTab
v-slot=
"
{ active, text, itemClick }">
<span
class=
"inline-block w-1/2 rounded-full cursor-pointer text-center leading-[30px] relative z-1 text-[5C6370] hover:text-black"
:class=
"active ? 'text-black shadow-md' : 'hover:bg-[#DDDFE3]'"
class=
"inline-block w-1/2 rounded-full cursor-pointer text-center leading-[30px] relative z-1 text-[5C6370] hover:text-black"
@
click=
"itemClick"
>
{{
text
}}
...
...
@@ -14,9 +14,9 @@
<h3
class=
"mt-5 mb-3 flex items-center justify-between text-[14px]"
>
<span>
{{
label
}}
</span>
<span
@
click=
"hintClick"
v-if=
"hint"
class=
"flex items-center text-[12px] text-[#846af7] cursor-pointer select-none"
@
click=
"hintClick"
>
<Icon
icon=
"ep:question-filled"
/>
{{
hint
}}
...
...
@@ -29,17 +29,17 @@
<div
class=
"w-full pt-2 bg-[#f5f7f9] flex justify-center"
>
<div
class=
"w-[303px] rounded-full bg-[#DDDFE3] p-1 z-10"
>
<div
class=
"flex items-center relative after:content-[''] after:block after:bg-white after:h-[30px] after:w-1/2 after:absolute after:top-0 after:left-0 after:transition-transform after:rounded-full"
:class=
"
selectedTab === AiWriteTypeEnum.REPLY && 'after:transform after:translate-x-[100%]'
"
class=
"flex items-center relative after:content-[''] after:block after:bg-white after:h-[30px] after:w-1/2 after:absolute after:top-0 after:left-0 after:transition-transform after:rounded-full"
>
<ReuseTab
v-for=
"tab in tabs"
:key=
"tab.value"
:text=
"tab.text"
:active=
"tab.value === selectedTab"
:itemClick=
"() => switchTab(tab.value)"
:text=
"tab.text"
/>
</div>
</div>
...
...
@@ -49,36 +49,36 @@
>
<div>
<template
v-if=
"selectedTab === 1"
>
<ReuseLabel
label=
"写作内容"
hint=
"示例"
:hint-click=
"() => example('write')
"
/>
<ReuseLabel
:hint-click=
"() => example('write')"
hint=
"示例"
label=
"写作内容
"
/>
<el-input
type=
"textarea"
:rows=
"5"
:maxlength=
"500"
v-model=
"formData.prompt"
:maxlength=
"500"
:rows=
"5"
placeholder=
"请输入写作内容"
showWordLimit
type=
"textarea"
/>
</
template
>
<
template
v-else
>
<ReuseLabel
label=
"原文"
hint=
"示例"
:hint-click=
"() => example('reply')
"
/>
<ReuseLabel
:hint-click=
"() => example('reply')"
hint=
"示例"
label=
"原文
"
/>
<el-input
type=
"textarea"
:rows=
"5"
:maxlength=
"500"
v-model=
"formData.originalContent"
:maxlength=
"500"
:rows=
"5"
placeholder=
"请输入原文"
showWordLimit
type=
"textarea"
/>
<ReuseLabel
label=
"回复内容"
/>
<el-input
type=
"textarea"
:rows=
"5"
:maxlength=
"500"
v-model=
"formData.prompt"
:maxlength=
"500"
:rows=
"5"
placeholder=
"请输入回复内容"
showWordLimit
type=
"textarea"
/>
</
template
>
...
...
@@ -93,14 +93,14 @@
<div
class=
"flex items-center justify-center mt-3"
>
<el-button
:disabled=
"isWriting"
@
click=
"reset"
>
重置
</el-button>
<el-button
:loading=
"isWriting"
@
click=
"submit"
color=
"#846af7
"
>
生成
</el-button>
<el-button
:loading=
"isWriting"
color=
"#846af7"
@
click=
"submit
"
>
生成
</el-button>
</div>
</div>
</div>
</div>
</template>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
{
createReusableTemplate
}
from
'@vueuse/core'
import
{
ref
}
from
'vue'
import
Tag
from
'./Tag.vue'
...
...
src/views/mall/home/components/OperationDataCard.vue
View file @
eecfb90a
...
...
@@ -11,9 +11,9 @@
@
click=
"handleClick(item.routerName)"
>
<CountTo
:prefix=
"item.prefix"
:end-val=
"item.value"
:decimals=
"item.decimals"
:end-val=
"item.value"
:prefix=
"item.prefix"
class=
"text-3xl"
/>
<span
class=
"text-center"
>
{{ item.name }}
</span>
...
...
src/views/mall/product/spu/components/SkuList.vue
View file @
eecfb90a
...
...
@@ -180,17 +180,17 @@
</el-table-column>
<el-table-column
align=
"center"
label=
"销售价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
price
}}
{{
formatToFraction
(
row
.
price
)
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"市场价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
marketPrice
}}
{{
formatToFraction
(
row
.
marketPrice
)
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"成本价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
costPrice
}}
{{
formatToFraction
(
row
.
costPrice
)
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"库存"
min-width=
"80"
>
...
...
@@ -211,12 +211,12 @@
<
template
v-if=
"formData!.subCommissionType"
>
<el-table-column
align=
"center"
label=
"一级返佣(元)"
min-width=
"80"
>
<template
#
default=
"
{ row }">
{{
row
.
firstBrokeragePrice
}}
{{
formatToFraction
(
row
.
firstBrokeragePrice
)
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"二级返佣(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
secondBrokeragePrice
}}
{{
formatToFraction
(
row
.
secondBrokeragePrice
)
}}
</
template
>
</el-table-column>
</template>
...
...
@@ -260,17 +260,17 @@
</el-table-column>
<el-table-column
align=
"center"
label=
"销售价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
price
}}
{{
formatToFraction
(
row
.
price
)
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"市场价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
marketPrice
}}
{{
formatToFraction
(
row
.
marketPrice
)
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"成本价(元)"
min-width=
"80"
>
<
template
#
default=
"{ row }"
>
{{
row
.
costPrice
}}
{{
formatToFraction
(
row
.
costPrice
)
}}
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"库存"
min-width=
"80"
>
...
...
@@ -284,7 +284,7 @@
</template>
<
script
lang=
"ts"
setup
>
import
{
PropType
,
Ref
}
from
'vue'
import
{
copyValueToTarget
}
from
'@/utils'
import
{
copyValueToTarget
,
formatToFraction
}
from
'@/utils'
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
UploadImg
}
from
'@/components/UploadFile'
import
type
{
Property
,
Sku
,
Spu
}
from
'@/api/mall/product/spu'
...
...
src/views/mall/product/spu/form/ProductAttributes.vue
View file @
eecfb90a
...
...
@@ -19,19 +19,19 @@
{{
value
.
name
}}
</el-tag>
<el-select
v-show=
"inputVisible(index)"
:id=
"`input$
{index}`"
:ref="setInputRef"
v-show="inputVisible(index)"
v-model="inputValue"
filterable
:reserve-keyword="false"
allow-create
class="!w-30"
default-first-option
:reserve-keyword="false"
filterable
size="small"
class="!w-30"
@blur="handleInputConfirm(index, item.id)"
@keyup.enter="handleInputConfirm(index, item.id)"
@change="handleInputConfirm(index, item.id)"
@keyup.enter="handleInputConfirm(index, item.id)"
>
<el-option
v-for=
"item2 in attributeOptions"
...
...
src/views/mall/product/spu/form/ProductPropertyAddForm.vue
View file @
eecfb90a
...
...
@@ -12,12 +12,12 @@
<el-form-item
label=
"属性名称"
prop=
"name"
>
<el-select
v-model=
"formData.name"
filterable
:reserve-keyword=
"false"
allow-create
class=
"!w-360px"
default-first-option
:reserve-keyword=
"false"
filterable
placeholder=
"请选择属性名称。如果不存在,可手动输入选择"
class=
"!w-360px"
>
<el-option
v-for=
"item in attributeOptions"
...
...
src/views/mall/product/spu/form/SkuForm.vue
View file @
eecfb90a
...
...
@@ -2,11 +2,11 @@
<
template
>
<el-form
ref=
"formRef"
v-loading=
"formLoading"
:disabled=
"isDetail"
:model=
"formData"
:rules=
"rules"
label-width=
"120px"
v-loading=
"formLoading"
>
<el-form-item
label=
"分销类型"
props=
"subCommissionType"
>
<el-radio-group
...
...
src/views/mall/trade/afterSale/index.vue
View file @
eecfb90a
...
...
@@ -135,7 +135,7 @@
</div>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"订单金额"
prop=
"refundPrice"
min-width=
"120
"
>
<el-table-column
align=
"center"
label=
"订单金额"
min-width=
"120"
prop=
"refundPrice
"
>
<
template
#
default=
"scope"
>
<span>
{{
fenToYuan
(
scope
.
row
.
refundPrice
)
}}
元
</span>
</
template
>
...
...
src/views/member/user/components/UserBalanceUpdateForm.vue
0 → 100644
View file @
eecfb90a
<
template
>
<Dialog
v-model=
"dialogVisible"
title=
"修改用户余额"
width=
"600"
>
<el-form
ref=
"formRef"
v-loading=
"formLoading"
:model=
"formData"
:rules=
"formRules"
label-width=
"130px"
>
<el-form-item
label=
"用户编号"
prop=
"id"
>
<el-input
v-model=
"formData.id"
class=
"!w-240px"
disabled
/>
</el-form-item>
<el-form-item
label=
"用户昵称"
prop=
"nickname"
>
<el-input
v-model=
"formData.nickname"
class=
"!w-240px"
disabled
/>
</el-form-item>
<el-form-item
label=
"变动前余额(元)"
prop=
"balance"
>
<el-input-number
v-model=
"formData.balance"
class=
"!w-240px"
disabled
/>
</el-form-item>
<el-form-item
label=
"变动类型"
prop=
"changeType"
>
<el-radio-group
v-model=
"formData.changeType"
>
<el-radio
:label=
"1"
>
增加
</el-radio>
<el-radio
:label=
"-1"
>
减少
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"变动余额(元)"
prop=
"changeBalance"
>
<el-input-number
v-model=
"formData.changeBalance"
:min=
"0"
:precision=
"2"
:step=
"0.1"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"变动后余额(元)"
>
<el-input-number
v-model=
"balanceResult"
class=
"!w-240px"
disabled
/>
</el-form-item>
</el-form>
<template
#
footer
>
<el-button
:disabled=
"formLoading"
type=
"primary"
@
click=
"submitForm"
>
确 定
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
lang=
"ts"
setup
>
import
*
as
UserApi
from
'@/api/member/user'
import
*
as
WalletApi
from
'@/api/pay/wallet/balance'
import
{
convertToInteger
,
formatToFraction
}
from
'@/utils'
/** 修改用户余额表单 */
defineOptions
({
name
:
'UpdateBalanceForm'
})
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formData
=
ref
({
id
:
undefined
,
nickname
:
undefined
,
balance
:
'0'
,
changeBalance
:
0
,
changeType
:
1
})
const
formRules
=
reactive
({
changeBalance
:
[{
required
:
true
,
message
:
'变动余额不能为空'
,
trigger
:
'blur'
}]
})
const
formRef
=
ref
()
// 表单 Ref
/** 打开弹窗 */
const
open
=
async
(
id
?:
number
)
=>
{
dialogVisible
.
value
=
true
resetForm
()
// 修改时,设置数据
if
(
id
)
{
formLoading
.
value
=
true
try
{
const
user
=
await
UserApi
.
getUser
(
id
)
const
wallet
=
await
WalletApi
.
getWallet
({
userId
:
user
.
id
||
0
})
formData
.
value
.
id
=
user
.
id
formData
.
value
.
nickname
=
user
.
nickname
formData
.
value
.
balance
=
formatToFraction
(
wallet
.
balance
)
formData
.
value
.
changeType
=
1
// 默认增加余额
formData
.
value
.
changeBalance
=
0
// 变动余额默认0
}
finally
{
formLoading
.
value
=
false
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
// 校验表单
if
(
!
formRef
)
return
const
valid
=
await
formRef
.
value
.
validate
()
if
(
!
valid
)
return
if
(
formData
.
value
.
changeBalance
<=
0
)
{
message
.
error
(
'变动余额不能为零'
)
return
}
if
(
convertToInteger
(
balanceResult
.
value
)
<
0
)
{
message
.
error
(
'变动后的余额不能小于 0'
)
return
}
// 提交请求
formLoading
.
value
=
true
try
{
await
UserApi
.
updateUserBalance
({
id
:
formData
.
value
.
id
,
balance
:
convertToInteger
(
formData
.
value
.
changeBalance
)
*
formData
.
value
.
changeType
})
message
.
success
(
t
(
'common.updateSuccess'
))
dialogVisible
.
value
=
false
// 发送操作成功的事件
emit
(
'success'
)
}
finally
{
formLoading
.
value
=
false
}
}
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
value
=
{
id
:
undefined
,
nickname
:
undefined
,
balance
:
'0'
,
changeBalance
:
0
,
changeType
:
1
}
formRef
.
value
?.
resetFields
()
}
/** 变动后的余额 */
const
balanceResult
=
computed
(()
=>
formatToFraction
(
convertToInteger
(
formData
.
value
.
balance
)
+
convertToInteger
(
formData
.
value
.
changeBalance
)
*
formData
.
value
.
changeType
)
)
</
script
>
src/views/member/user/UserLevelUpdateForm.vue
→
src/views/member/user/
components/
UserLevelUpdateForm.vue
View file @
eecfb90a
File moved
src/views/member/user/UserPointUpdateForm.vue
→
src/views/member/user/
components/
UserPointUpdateForm.vue
View file @
eecfb90a
<
template
>
<Dialog
title=
"修改用户积分"
v-model=
"dialogVisible
"
width=
"600"
>
<Dialog
v-model=
"dialogVisible"
title=
"修改用户积分
"
width=
"600"
>
<el-form
ref=
"formRef"
v-loading=
"formLoading"
:model=
"formData"
:rules=
"formRules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label=
"用户编号"
prop=
"id"
>
<el-input
v-model=
"formData.id"
class=
"!w-240px"
disabled
/>
...
...
@@ -23,19 +23,19 @@
</el-radio-group>
</el-form-item>
<el-form-item
label=
"变动积分"
prop=
"changePoint"
>
<el-input-number
v-model=
"formData.changePoint"
class=
"!w-240px"
:min=
"0"
:precision=
"0
"
/>
<el-input-number
v-model=
"formData.changePoint"
:min=
"0"
:precision=
"0"
class=
"!w-240px
"
/>
</el-form-item>
<el-form-item
label=
"变动后积分"
>
<el-input-number
v-model=
"pointResult"
class=
"!w-240px"
disabled
/>
</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"
setup
>
import
*
as
UserApi
from
'@/api/member/user'
/** 修改用户积分表单 */
...
...
@@ -115,8 +115,9 @@ const resetForm = () => {
formData
.
value
=
{
id
:
undefined
,
nickname
:
undefined
,
levelId
:
undefined
,
reason
:
undefined
point
:
0
,
changePoint
:
0
,
changeType
:
1
}
formRef
.
value
?.
resetFields
()
}
...
...
src/views/member/user/components/balance-list.vue
deleted
100644 → 0
View file @
fc5e37dd
<
script
lang=
"ts"
>
import
{
defineComponent
}
from
'vue'
export
default
defineComponent
({
name
:
'BalanceList'
})
</
script
>
<!-- TODO @芋艿:未来实现,等周建的 -->
<
template
>
<div>
余额列表
</div>
</
template
>
<
style
scoped
lang=
"scss"
></
style
>
src/views/member/user/detail/UserAccountInfo.vue
View file @
eecfb90a
...
...
@@ -2,57 +2,57 @@
<el-descriptions
:column=
"2"
>
<el-descriptions-item>
<template
#
label
>
<descriptions-item-label
label=
" 等级 "
icon=
"svg-icon:member_level
"
/>
<descriptions-item-label
icon=
"svg-icon:member_level"
label=
" 等级
"
/>
</
template
>
{{ user.levelName || '无' }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<descriptions-item-label
label=
" 成长值 "
icon=
"ep:suitcase
"
/>
<descriptions-item-label
icon=
"ep:suitcase"
label=
" 成长值
"
/>
</
template
>
{{ user.experience || 0 }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<descriptions-item-label
label=
" 当前积分 "
icon=
"ep:coin
"
/>
<descriptions-item-label
icon=
"ep:coin"
label=
" 当前积分
"
/>
</
template
>
{{ user.point || 0 }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<descriptions-item-label
label=
" 总积分 "
icon=
"ep:coin
"
/>
<descriptions-item-label
icon=
"ep:coin"
label=
" 总积分
"
/>
</
template
>
{{ user.totalPoint || 0 }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<descriptions-item-label
label=
" 当前余额 "
icon=
"svg-icon:member_balance
"
/>
<descriptions-item-label
icon=
"svg-icon:member_balance"
label=
" 当前余额
"
/>
</
template
>
{{ fenToYuan(wallet.balance || 0) }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<descriptions-item-label
label=
" 支出金额 "
icon=
"svg-icon:member_expenditure_balance
"
/>
<descriptions-item-label
icon=
"svg-icon:member_expenditure_balance"
label=
" 支出金额
"
/>
</
template
>
{{ fenToYuan(wallet.totalExpense || 0) }}
</el-descriptions-item>
<el-descriptions-item>
<
template
#
label
>
<descriptions-item-label
label=
" 充值金额 "
icon=
"svg-icon:member_recharge_balance
"
/>
<descriptions-item-label
icon=
"svg-icon:member_recharge_balance"
label=
" 充值金额
"
/>
</
template
>
{{ fenToYuan(wallet.totalRecharge || 0) }}
</el-descriptions-item>
</el-descriptions>
</template>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
{
DescriptionsItemLabel
}
from
'@/components/Descriptions'
import
*
as
UserApi
from
'@/api/member/user'
import
*
as
WalletApi
from
'@/api/pay/wallet/balance'
import
{
UserTypeEnum
}
from
'@/utils/constants'
import
{
fenToYuan
}
from
'@/utils'
const
props
=
defineProps
<
{
user
:
UserApi
.
UserVO
;
wallet
:
WalletApi
.
WalletVO
}
>
()
// 用户信息
defineProps
<
{
user
:
UserApi
.
UserVO
;
wallet
:
WalletApi
.
WalletVO
}
>
()
// 用户信息
</
script
>
<
style
scoped
lang=
"scss"
>
<
style
lang=
"scss"
scoped
>
.cell-item
{
display
:
inline
;
}
...
...
src/views/member/user/detail/UserAftersaleList.vue
View file @
eecfb90a
...
...
@@ -133,7 +133,7 @@
</div>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
label=
"订单金额"
prop=
"refundPrice"
min-width=
"120
"
>
<el-table-column
align=
"center"
label=
"订单金额"
min-width=
"120"
prop=
"refundPrice
"
>
<
template
#
default=
"scope"
>
<span>
{{
fenToYuan
(
scope
.
row
.
refundPrice
)
}}
元
</span>
</
template
>
...
...
@@ -153,7 +153,7 @@
<dict-tag
:type=
"DICT_TYPE.TRADE_AFTER_SALE_WAY"
:value=
"scope.row.way"
/>
</
template
>
</el-table-column>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
width=
"1
6
0"
>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
width=
"1
2
0"
>
<
template
#
default=
"{ row }"
>
<el-button
link
type=
"primary"
@
click=
"openAfterSaleDetail(row.id)"
>
处理退款
</el-button>
</
template
>
...
...
@@ -180,7 +180,7 @@ import { fenToYuan } from '@/utils'
defineOptions
({
name
:
'UserAfterSaleList'
})
const
{
push
}
=
useRouter
()
// 路由跳转
const
{
userId
}
=
defineProps
<
{
const
props
=
defineProps
<
{
userId
:
number
}
>
()
const
loading
=
ref
(
true
)
// 列表的加载中
...
...
@@ -197,14 +197,14 @@ const queryFormRef = ref() // 搜索的表单
const
queryParams
=
ref
({
pageNo
:
1
,
pageSize
:
10
,
userId
,
no
:
null
,
status
:
'0'
,
orderNo
:
null
,
spuName
:
null
,
createTime
:
[],
way
:
null
,
type
:
null
type
:
null
,
userId
:
null
})
/** 查询列表 */
...
...
@@ -217,7 +217,9 @@ const getList = async () => {
delete
data
.
status
}
// 执行查询
// TODO @芋艿:接口需要通过userId进行筛选返回值
if
(
props
.
userId
)
{
data
.
userId
=
props
.
userId
as
any
}
const
res
=
await
AfterSaleApi
.
getAfterSalePage
(
data
)
list
.
value
=
res
.
list
as
AfterSaleApi
.
TradeAfterSaleVO
[]
total
.
value
=
res
.
total
...
...
@@ -235,13 +237,12 @@ const handleQuery = async () => {
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
?.
resetFields
()
queryParams
.
value
.
userId
=
userId
handleQuery
()
}
/** tab 切换 */
const
tabClick
=
async
(
tab
:
TabsPaneContext
)
=>
{
queryParams
.
value
.
status
=
tab
.
paneName
queryParams
.
value
.
status
=
tab
.
paneName
as
any
await
getList
()
}
...
...
src/views/member/user/detail/UserBalanceList.vue
View file @
eecfb90a
<
template
>
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:s
tripe=
"true"
:show-overflow-tooltip
=
"true"
>
<el-table-column
label=
"编号"
align=
"center
"
prop=
"id"
/>
<el-table-column
label=
"钱包编号"
align=
"center
"
prop=
"walletId"
/>
<el-table-column
label=
"关联业务标题"
align=
"center
"
prop=
"title"
/>
<el-table-column
label=
"交易金额"
align=
"center
"
prop=
"price"
>
<el-table
v-loading=
"loading"
:data=
"list"
:s
how-overflow-tooltip=
"true"
:stripe
=
"true"
>
<el-table-column
align=
"center"
label=
"编号
"
prop=
"id"
/>
<el-table-column
align=
"center"
label=
"钱包编号
"
prop=
"walletId"
/>
<el-table-column
align=
"center"
label=
"关联业务标题
"
prop=
"title"
/>
<el-table-column
align=
"center"
label=
"交易金额
"
prop=
"price"
>
<template
#
default=
"
{ row }">
{{
fenToYuan
(
row
.
price
)
}}
元
</
template
>
</el-table-column>
<el-table-column
label=
"钱包余额"
align=
"center
"
prop=
"balance"
>
<el-table-column
align=
"center"
label=
"钱包余额
"
prop=
"balance"
>
<
template
#
default=
"{ row }"
>
{{
fenToYuan
(
row
.
balance
)
}}
元
</
template
>
</el-table-column>
<el-table-column
label=
"交易时间
"
:formatter=
"dateFormatter
"
align=
"center"
label=
"交易时间"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
</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>
...
...
@@ -32,8 +32,9 @@
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
*
as
WalletTransactionApi
from
'@/api/pay/wallet/transaction'
import
{
fenToYuan
}
from
'@/utils'
defineOptions
({
name
:
'UserBalanceList'
})
const
{
walletId
}:
{
walletId
:
number
}
=
defineProps
({
const
props
=
defineProps
({
walletId
:
{
type
:
Number
,
required
:
false
...
...
@@ -52,7 +53,7 @@ const list = ref([]) // 列表的数据
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
queryParams
.
walletId
=
walletId
queryParams
.
walletId
=
props
.
walletId
as
any
const
data
=
await
WalletTransactionApi
.
getWalletTransactionPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
...
...
@@ -65,4 +66,3 @@ onMounted(() => {
getList
()
})
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
src/views/member/user/detail/index.vue
View file @
eecfb90a
...
...
@@ -7,7 +7,7 @@
<template
#
header
>
<div
class=
"card-header"
>
<CardTitle
title=
"基本信息"
/>
<el-button
type=
"primary"
size=
"small"
text
@
click=
"openForm('update')"
>
<el-button
size=
"small"
text
type=
"primary"
@
click=
"openForm('update')"
>
编辑
</el-button>
</div>
...
...
@@ -16,16 +16,16 @@
</el-col>
<!-- 右上角:账户信息 -->
<el-col
:span=
"10"
class=
"detail-info-item"
>
<el-card
shadow=
"never"
class=
"h-full
"
>
<el-card
class=
"h-full"
shadow=
"never
"
>
<
template
#
header
>
<CardTitle
title=
"账户信息"
/>
</
template
>
<UserAccountInfo
:user=
"user"
:wallet=
"wallet"
/>
<UserAccountInfo
:user=
"user"
:wallet=
"wallet"
/>
</el-card>
</el-col>
<!-- 下边:账户明细 -->
<!-- TODO 芋艿:【订单管理】【售后管理】【收藏记录】-->
<el-card
header=
"账户明细"
s
tyle=
"width: 100%; margin-top: 20px"
shadow=
"never
"
>
<el-card
header=
"账户明细"
s
hadow=
"never"
style=
"width: 100%; margin-top: 20px
"
>
<
template
#
header
>
<CardTitle
title=
"账户明细"
/>
</
template
>
...
...
@@ -39,7 +39,6 @@
<el-tab-pane
label=
"成长值"
lazy
>
<UserExperienceRecordList
:user-id=
"id"
/>
</el-tab-pane>
<!-- TODO @jason:增加一个余额变化; -->
<el-tab-pane
label=
"余额"
lazy
>
<UserBalanceList
:wallet-id=
"wallet.id"
/>
</el-tab-pane>
...
...
@@ -69,7 +68,7 @@
<!-- 表单弹窗:添加/修改 -->
<UserForm
ref=
"formRef"
@
success=
"getUserData(id)"
/>
</template>
<
script
setup
lang=
"ts"
>
<
script
lang=
"ts"
setup
>
import
*
as
WalletApi
from
'@/api/pay/wallet/balance'
import
*
as
UserApi
from
'@/api/member/user'
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
...
...
@@ -85,6 +84,7 @@ import UserPointList from './UserPointList.vue'
import
UserSignList
from
'./UserSignList.vue'
import
UserFavoriteList
from
'./UserFavoriteList.vue'
import
UserAfterSaleList
from
'./UserAftersaleList.vue'
import
UserBalanceList
from
'./UserBalanceList.vue'
import
{
CardTitle
}
from
'@/components/Card/index'
import
{
ElMessage
}
from
'element-plus'
...
...
@@ -142,7 +142,7 @@ onMounted(() => {
getUserWallet
()
})
</
script
>
<
style
scoped
lang=
"css"
>
<
style
lang=
"css"
scoped
>
.detail-info-item
:first-child
{
padding-left
:
0
!important
;
}
...
...
src/views/member/user/index.vue
View file @
eecfb90a
...
...
@@ -172,7 +172,7 @@
v-if=
"checkPermi(['member:user:update-balance'])"
command=
"handleUpdateBlance"
>
修改余额
(WIP)
修改余额
</el-dropdown-item>
</el-dropdown-menu>
</
template
>
...
...
@@ -196,6 +196,8 @@
<UserLevelUpdateForm
ref=
"updateLevelFormRef"
@
success=
"getList"
/>
<!-- 修改用户积分弹窗 -->
<UserPointUpdateForm
ref=
"updatePointFormRef"
@
success=
"getList"
/>
<!-- 修改用户余额弹窗 -->
<UserBalanceUpdateForm
ref=
"UpdateBalanceFormRef"
@
success=
"getList"
/>
<!-- 发送优惠券弹窗 -->
<CouponSendForm
ref=
"couponSendFormRef"
/>
</template>
...
...
@@ -207,8 +209,9 @@ import UserForm from './UserForm.vue'
import
MemberTagSelect
from
'@/views/member/tag/components/MemberTagSelect.vue'
import
MemberLevelSelect
from
'@/views/member/level/components/MemberLevelSelect.vue'
import
MemberGroupSelect
from
'@/views/member/group/components/MemberGroupSelect.vue'
import
UserLevelUpdateForm
from
'./UserLevelUpdateForm.vue'
import
UserPointUpdateForm
from
'./UserPointUpdateForm.vue'
import
UserLevelUpdateForm
from
'./components/UserLevelUpdateForm.vue'
import
UserPointUpdateForm
from
'./components/UserPointUpdateForm.vue'
import
UserBalanceUpdateForm
from
'./components/UserBalanceUpdateForm.vue'
import
{
CouponSendForm
}
from
'@/views/mall/promotion/coupon/components'
import
{
checkPermi
}
from
'@/utils/permission'
...
...
@@ -233,6 +236,7 @@ const queryParams = reactive({
const
queryFormRef
=
ref
()
// 搜索的表单
const
updateLevelFormRef
=
ref
()
// 修改会员等级表单
const
updatePointFormRef
=
ref
()
// 修改会员积分表单
const
UpdateBalanceFormRef
=
ref
()
// 修改用户余额表单
const
selectedIds
=
ref
<
number
[]
>
([])
// 表格的选中 ID 数组
/** 查询列表 */
...
...
@@ -299,7 +303,7 @@ const handleCommand = (command: string, row: UserApi.UserVO) => {
updatePointFormRef
.
value
.
open
(
row
.
id
)
break
case
'handleUpdateBlance'
:
// todo @jason:增加一个【修改余额】
UpdateBalanceFormRef
.
value
.
open
(
row
.
id
)
break
default
:
break
...
...
src/views/pay/app/components/channel/AlipayChannelForm.vue
View file @
eecfb90a
<
template
>
<div>
<Dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
@
closed=
"close"
width=
"830px
"
>
<Dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"830px"
@
closed=
"close
"
>
<el-form
ref=
"formRef"
v-loading=
"formLoading"
:model=
"formData"
:rules=
"formRules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label
-width=
"180px"
label=
"渠道费率
"
prop=
"feeRate"
>
<el-input
v-model=
"formData.feeRate"
placeholder=
"请输入渠道费率"
clearable
>
<el-form-item
label
=
"渠道费率"
label-width=
"180px
"
prop=
"feeRate"
>
<el-input
v-model=
"formData.feeRate"
clearable
placeholder=
"请输入渠道费率"
>
<template
#
append
>
%
</
template
>
</el-input>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"开放平台 APPID
"
prop=
"config.appId"
>
<el-input
v-model=
"formData.config.appId"
placeholder=
"请输入开放平台 APPID"
clearable
/>
<el-form-item
label
=
"开放平台 APPID"
label-width=
"180px
"
prop=
"config.appId"
>
<el-input
v-model=
"formData.config.appId"
clearable
placeholder=
"请输入开放平台 APPID"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"渠道状态
"
prop=
"status"
>
<el-form-item
label
=
"渠道状态"
label-width=
"180px
"
prop=
"status"
>
<el-radio-group
v-model=
"formData.status"
>
<el-radio
v-for=
"dict in getDictOptions(DICT_TYPE.COMMON_STATUS)"
...
...
@@ -27,7 +27,7 @@
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"网关地址
"
prop=
"config.serverUrl"
>
<el-form-item
label
=
"网关地址"
label-width=
"180px
"
prop=
"config.serverUrl"
>
<el-radio-group
v-model=
"formData.config.serverUrl"
>
<el-radio
label=
"https://openapi.alipay.com/gateway.do"
>
线上环境
</el-radio>
<el-radio
label=
"https://openapi-sandbox.dl.alipaydev.com/gateway.do"
>
...
...
@@ -35,145 +35,148 @@
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"算法类型
"
prop=
"config.signType"
>
<el-form-item
label
=
"算法类型"
label-width=
"180px
"
prop=
"config.signType"
>
<el-radio-group
v-model=
"formData.config.signType"
>
<el-radio
key=
"RSA2"
label=
"RSA2"
>
RSA2
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"公钥类型
"
prop=
"config.mode"
>
<el-form-item
label
=
"公钥类型"
label-width=
"180px
"
prop=
"config.mode"
>
<el-radio-group
v-model=
"formData.config.mode"
>
<el-radio
key=
"公钥模式"
:label=
"1"
>
公钥模式
</el-radio>
<el-radio
key=
"证书模式"
:label=
"2"
>
证书模式
</el-radio>
</el-radio-group>
</el-form-item>
<div
v-if=
"formData.config.mode === 1"
>
<el-form-item
label
-width=
"180px"
label=
"应用私钥
"
prop=
"config.privateKey"
>
<el-form-item
label
=
"应用私钥"
label-width=
"180px
"
prop=
"config.privateKey"
>
<el-input
type=
"textarea"
:autosize=
"{ minRows: 8, maxRows: 8 }"
v-model=
"formData.config.privateKey"
placeholder=
"请输入应用私钥"
clearable
:autosize=
"{ minRows: 8, maxRows: 8 }"
:style=
"{ width: '100%' }"
clearable
placeholder=
"请输入应用私钥"
type=
"textarea"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"支付宝公钥
"
prop=
"config.alipayPublicKey"
>
<el-form-item
label
=
"支付宝公钥"
label-width=
"180px
"
prop=
"config.alipayPublicKey"
>
<el-input
type=
"textarea"
:autosize=
"{ minRows: 8, maxRows: 8 }"
v-model=
"formData.config.alipayPublicKey"
placeholder=
"请输入支付宝公钥"
clearable
:autosize=
"{ minRows: 8, maxRows: 8 }"
:style=
"{ width: '100%' }"
clearable
placeholder=
"请输入支付宝公钥"
type=
"textarea"
/>
</el-form-item>
</div>
<div
v-if=
"formData.config.mode === 2"
>
<el-form-item
label
-width=
"180px"
label=
"应用私钥
"
prop=
"config.privateKey"
>
<el-form-item
label
=
"应用私钥"
label-width=
"180px
"
prop=
"config.privateKey"
>
<el-input
type=
"textarea"
:autosize=
"{ minRows: 8, maxRows: 8 }"
v-model=
"formData.config.privateKey"
placeholder=
"请输入应用私钥"
clearable
:autosize=
"{ minRows: 8, maxRows: 8 }"
:style=
"{ width: '100%' }"
clearable
placeholder=
"请输入应用私钥"
type=
"textarea"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"商户公钥应用证书
"
prop=
"config.appCertContent"
>
<el-form-item
label
=
"商户公钥应用证书"
label-width=
"180px
"
prop=
"config.appCertContent"
>
<el-input
v-model=
"formData.config.appCertContent"
type=
"textarea"
placeholder=
"请上传商户公钥应用证书"
readonly
:autosize=
"{ minRows: 8, maxRows: 8 }"
:style=
"{ width: '100%' }"
placeholder=
"请上传商户公钥应用证书"
readonly
type=
"textarea"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"
"
>
<el-form-item
label
=
""
label-width=
"180px
"
>
<el-upload
action=
""
ref=
"privateKeyContentFile"
:limit=
"1"
:accept=
"fileAccept"
:http-request=
"appCertUpload"
:before-upload=
"fileBeforeUpload"
:http-request=
"appCertUpload"
:limit=
"1"
action=
""
>
<el-button
type=
"primary"
>
<Icon
icon=
"ep:upload"
class=
"mr-5px"
/>
点击上传
<Icon
class=
"mr-5px"
icon=
"ep:upload"
/>
点击上传
</el-button>
</el-upload>
</el-form-item>
<el-form-item
label-width=
"180px"
label=
"支付宝公钥证书"
label-width=
"180px"
prop=
"config.alipayPublicCertContent"
>
<el-input
v-model=
"formData.config.alipayPublicCertContent"
type=
"textarea"
placeholder=
"请上传支付宝公钥证书"
readonly
:autosize=
"{ minRows: 8, maxRows: 8 }"
:style=
"{ width: '100%' }"
placeholder=
"请上传支付宝公钥证书"
readonly
type=
"textarea"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"
"
>
<el-form-item
label
=
""
label-width=
"180px
"
>
<el-upload
ref=
"privateCertContentFile"
action=
""
:limit=
"1"
:accept=
"fileAccept"
:before-upload=
"fileBeforeUpload"
:http-request=
"alipayPublicCertUpload"
:limit=
"1"
action=
""
>
<el-button
type=
"primary"
>
<Icon
icon=
"ep:upload"
class=
"mr-5px"
/>
点击上传
<Icon
class=
"mr-5px"
icon=
"ep:upload"
/>
点击上传
</el-button>
</el-upload>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"根证书
"
prop=
"config.rootCertContent"
>
<el-form-item
label
=
"根证书"
label-width=
"180px
"
prop=
"config.rootCertContent"
>
<el-input
v-model=
"formData.config.rootCertContent"
type=
"textarea"
placeholder=
"请上传根证书"
readonly
:autosize=
"{ minRows: 8, maxRows: 8 }"
:style=
"{ width: '100%' }"
placeholder=
"请上传根证书"
readonly
type=
"textarea"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"
"
>
<el-form-item
label
=
""
label-width=
"180px
"
>
<el-upload
ref=
"privateCertContentFile"
:limit=
"1"
:accept=
"fileAccept"
action=
""
:before-upload=
"fileBeforeUpload"
:http-request=
"rootCertUpload"
:limit=
"1"
action=
""
>
<el-button
type=
"primary"
>
<Icon
icon=
"ep:upload"
class=
"mr-5px"
/>
点击上传
<Icon
class=
"mr-5px"
icon=
"ep:upload"
/>
点击上传
</el-button>
</el-upload>
</el-form-item>
</div>
<el-form-item
label
-width=
"180px"
label=
"接口内容加密方式
"
prop=
"config.encryptType"
>
<el-form-item
label
=
"接口内容加密方式"
label-width=
"180px
"
prop=
"config.encryptType"
>
<el-radio-group
v-model=
"formData.config.encryptType"
>
<el-radio
key=
"NONE"
label=
""
>
无加密
</el-radio>
<el-radio
key=
"AES"
label=
"AES"
>
AES
</el-radio>
</el-radio-group>
</el-form-item>
<div
v-if=
"formData.config.encryptType === 'AES'"
>
<el-form-item
label
-width=
"180px"
label=
"接口内容加密密钥
"
prop=
"config.encryptKey"
>
<el-form-item
label
=
"接口内容加密密钥"
label-width=
"180px
"
prop=
"config.encryptKey"
>
<el-input
v-model=
"formData.config.encryptKey"
placeholder=
"请输入接口内容加密密钥"
clearable
placeholder=
"请输入接口内容加密密钥"
/>
</el-form-item>
</div>
<el-form-item
label
-width=
"180px"
label=
"备注
"
prop=
"remark"
>
<el-form-item
label
=
"备注"
label-width=
"180px
"
prop=
"remark"
>
<el-input
v-model=
"formData.remark"
:style=
"{ width: '100%' }"
/>
</el-form-item>
</el-form>
...
...
src/views/pay/app/components/channel/MockChannelForm.vue
View file @
eecfb90a
...
...
@@ -3,12 +3,12 @@
<Dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"800px"
>
<el-form
ref=
"formRef"
v-loading=
"formLoading"
:model=
"formData"
:rules=
"formRules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label
-width=
"180px"
label=
"渠道状态
"
prop=
"status"
>
<el-form-item
label
=
"渠道状态"
label-width=
"180px
"
prop=
"status"
>
<el-radio-group
v-model=
"formData.status"
>
<el-radio
v-for=
"dict in getDictOptions(DICT_TYPE.COMMON_STATUS)"
...
...
@@ -19,7 +19,7 @@
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"备注
"
prop=
"remark"
>
<el-form-item
label
=
"备注"
label-width=
"180px
"
prop=
"remark"
>
<el-input
v-model=
"formData.remark"
:style=
"
{ width: '100%' }" />
</el-form-item>
</el-form>
...
...
src/views/pay/app/components/channel/WalletChannelForm.vue
View file @
eecfb90a
...
...
@@ -3,12 +3,12 @@
<Dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"800px"
>
<el-form
ref=
"formRef"
v-loading=
"formLoading"
:model=
"formData"
:rules=
"formRules"
label-width=
"100px"
v-loading=
"formLoading"
>
<el-form-item
label
-width=
"180px"
label=
"渠道状态
"
prop=
"status"
>
<el-form-item
label
=
"渠道状态"
label-width=
"180px
"
prop=
"status"
>
<el-radio-group
v-model=
"formData.status"
>
<el-radio
v-for=
"dict in getDictOptions(DICT_TYPE.COMMON_STATUS)"
...
...
@@ -19,7 +19,7 @@
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"备注
"
prop=
"remark"
>
<el-form-item
label
=
"备注"
label-width=
"180px
"
prop=
"remark"
>
<el-input
v-model=
"formData.remark"
:style=
"
{ width: '100%' }" />
</el-form-item>
</el-form>
...
...
src/views/pay/app/components/channel/WeixinChannelForm.vue
View file @
eecfb90a
...
...
@@ -3,33 +3,33 @@
<Dialog
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"800px"
>
<el-form
ref=
"formRef"
v-loading=
"formLoading"
:model=
"formData"
:rules=
"formRules"
label-width=
"120px"
v-loading=
"formLoading"
>
<el-form-item
label
-width=
"180px"
label=
"渠道费率
"
prop=
"feeRate"
>
<el-form-item
label
=
"渠道费率"
label-width=
"180px
"
prop=
"feeRate"
>
<el-input
v-model=
"formData.feeRate"
placeholder=
"请输入渠道费率"
clearable
:style=
"
{ width: '100%' }"
clearable
placeholder="请输入渠道费率"
>
<template
#
append
>
%
</
template
>
</el-input>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"微信 APPID
"
prop=
"config.appId"
>
<el-form-item
label
=
"微信 APPID"
label-width=
"180px
"
prop=
"config.appId"
>
<el-input
v-model=
"formData.config.appId"
placeholder=
"请输入微信 APPID"
clearable
:style=
"{ width: '100%' }"
clearable
placeholder=
"请输入微信 APPID"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"商户号
"
prop=
"config.mchId"
>
<el-form-item
label
=
"商户号"
label-width=
"180px
"
prop=
"config.mchId"
>
<el-input
v-model=
"formData.config.mchId"
:style=
"{ width: '100%' }"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"渠道状态
"
prop=
"status"
>
<el-form-item
label
=
"渠道状态"
label-width=
"180px
"
prop=
"status"
>
<el-radio-group
v-model=
"formData.status"
>
<el-radio
v-for=
"dict in getDictOptions(DICT_TYPE.COMMON_STATUS)"
...
...
@@ -40,91 +40,91 @@
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"API 版本
"
prop=
"config.apiVersion"
>
<el-form-item
label
=
"API 版本"
label-width=
"180px
"
prop=
"config.apiVersion"
>
<el-radio-group
v-model=
"formData.config.apiVersion"
>
<el-radio
label=
"v2"
>
v2
</el-radio>
<el-radio
label=
"v3"
>
v3
</el-radio>
</el-radio-group>
</el-form-item>
<div
v-if=
"formData.config.apiVersion === 'v2'"
>
<el-form-item
label
-width=
"180px"
label=
"商户密钥
"
prop=
"config.mchKey"
>
<el-input
v-model=
"formData.config.mchKey"
placeholder=
"请输入商户密钥"
clearable
/>
<el-form-item
label
=
"商户密钥"
label-width=
"180px
"
prop=
"config.mchKey"
>
<el-input
v-model=
"formData.config.mchKey"
clearable
placeholder=
"请输入商户密钥"
/>
</el-form-item>
<el-form-item
label-width=
"180px"
label=
"apiclient_cert.p12 证书"
label-width=
"180px"
prop=
"config.keyContent"
>
<el-input
v-model=
"formData.config.keyContent"
type=
"textarea"
placeholder=
"请上传 apiclient_cert.p12 证书"
readonly
:autosize=
"{ minRows: 8, maxRows: 8 }"
:style=
"{ width: '100%' }"
placeholder=
"请上传 apiclient_cert.p12 证书"
readonly
type=
"textarea"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"
"
>
<el-form-item
label
=
""
label-width=
"180px
"
>
<el-upload
:before-upload=
"p12FileBeforeUpload"
:http-request=
"keyContentUpload"
:limit=
"1"
accept=
".p12"
action=
""
:before-upload=
"p12FileBeforeUpload"
:http-request=
"keyContentUpload"
>
<el-button
type=
"primary"
>
<Icon
icon=
"ep:upload"
class=
"mr-5px
"
/>
<Icon
class=
"mr-5px"
icon=
"ep:upload
"
/>
点击上传
</el-button>
</el-upload>
</el-form-item>
</div>
<div
v-if=
"formData.config.apiVersion === 'v3'"
>
<el-form-item
label
-width=
"180px"
label=
"API V3 密钥
"
prop=
"config.apiV3Key"
>
<el-form-item
label
=
"API V3 密钥"
label-width=
"180px
"
prop=
"config.apiV3Key"
>
<el-input
v-model=
"formData.config.apiV3Key"
placeholder=
"请输入 API V3 密钥"
clearable
placeholder=
"请输入 API V3 密钥"
/>
</el-form-item>
<el-form-item
label-width=
"180px"
label=
"apiclient_key.pem 证书"
label-width=
"180px"
prop=
"config.privateKeyContent"
>
<el-input
v-model=
"formData.config.privateKeyContent"
type=
"textarea"
placeholder=
"请上传 apiclient_key.pem 证书"
readonly
:autosize=
"{ minRows: 8, maxRows: 8 }"
:style=
"{ width: '100%' }"
placeholder=
"请上传 apiclient_key.pem 证书"
readonly
type=
"textarea"
/>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"
"
prop=
"privateKeyContentFile"
>
<el-form-item
label
=
""
label-width=
"180px
"
prop=
"privateKeyContentFile"
>
<el-upload
ref=
"privateKeyContentFile"
:before-upload=
"pemFileBeforeUpload"
:http-request=
"privateKeyContentUpload"
:limit=
"1"
accept=
".pem"
action=
""
:before-upload=
"pemFileBeforeUpload"
:http-request=
"privateKeyContentUpload"
>
<el-button
type=
"primary"
>
<Icon
icon=
"ep:upload"
class=
"mr-5px
"
/>
<Icon
class=
"mr-5px"
icon=
"ep:upload
"
/>
点击上传
</el-button>
</el-upload>
</el-form-item>
<el-form-item
label
-width=
"180px"
label=
"证书序列号
"
prop=
"config.certSerialNo"
>
<el-form-item
label
=
"证书序列号"
label-width=
"180px
"
prop=
"config.certSerialNo"
>
<el-input
v-model=
"formData.config.certSerialNo"
placeholder=
"请输入证书序列号"
clearable
placeholder=
"请输入证书序列号"
/>
</el-form-item>
</div>
<el-form-item
label
-width=
"180px"
label=
"备注
"
prop=
"remark"
>
<el-form-item
label
=
"备注"
label-width=
"180px
"
prop=
"remark"
>
<el-input
v-model=
"formData.remark"
:style=
"{ width: '100%' }"
/>
</el-form-item>
</el-form>
...
...
src/views/pay/app/index.vue
View file @
eecfb90a
...
...
@@ -3,27 +3,27 @@
<!-- 搜索 -->
<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=
"请输入应用名
"
class=
"!w-240px
"
clearable
placeholder=
"请输入应用名"
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
label=
"开启状态"
prop=
"status"
>
<el-select
v-model=
"queryParams.status"
placeholder=
"请选择开启状态"
clearable
class=
"!w-240px"
clearable
placeholder=
"请选择开启状态"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
...
...
@@ -36,25 +36,25 @@
<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
"
/>
<Icon
class=
"mr-5px"
icon=
"ep:search
"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
>
<Icon
icon=
"ep:refresh"
class=
"mr-5px
"
/>
<Icon
class=
"mr-5px"
icon=
"ep:refresh
"
/>
重置
</el-button>
<el-button
type=
"primary"
plain
@
click=
"openForm('create')"
v-hasPermi=
"['pay:app:create']
"
>
<Icon
icon=
"ep:plus"
class=
"mr-5px
"
/>
<el-button
v-hasPermi=
"['pay:app:create']"
plain
type=
"primary"
@
click=
"openForm('create')
"
>
<Icon
class=
"mr-5px"
icon=
"ep:plus
"
/>
新增
</el-button>
</el-form-item>
...
...
@@ -64,9 +64,9 @@
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
>
<el-table-column
label=
"应用标识"
align=
"center
"
prop=
"appKey"
/>
<el-table-column
label=
"应用名"
align=
"center"
prop=
"name"
min-width=
"90
"
/>
<el-table-column
label=
"开启状态"
align=
"center
"
prop=
"status"
>
<el-table-column
align=
"center"
label=
"应用标识
"
prop=
"appKey"
/>
<el-table-column
align=
"center"
label=
"应用名"
min-width=
"90"
prop=
"name
"
/>
<el-table-column
align=
"center"
label=
"开启状态
"
prop=
"status"
>
<template
#
default=
"scope"
>
<el-switch
v-model=
"scope.row.status"
...
...
@@ -76,28 +76,28 @@
/>
</
template
>
</el-table-column>
<el-table-column
label=
"支付宝配置"
align=
"center
"
>
<el-table-column
align=
"center"
label=
"支付宝配置
"
>
<el-table-column
:label=
"channel.name.replace('支付宝', '')"
align=
"center"
v-for=
"channel in alipayChannels"
:key=
"channel.code"
:label=
"channel.name.replace('支付宝', '')"
align=
"center"
>
<
template
#
default=
"scope"
>
<el-button
type=
"success"
v-if=
"isChannelExists(scope.row.channelCodes, channel.code)"
@
click=
"openChannelForm(scope.row, channel.code)"
circle
size=
"small"
type=
"success"
@
click=
"openChannelForm(scope.row, channel.code)"
>
<Icon
icon=
"ep:check"
/>
</el-button>
<el-button
v-else
type=
"danger"
circle
size=
"small"
type=
"danger"
@
click=
"openChannelForm(scope.row, channel.code)"
>
<Icon
icon=
"ep:close"
/>
...
...
@@ -105,28 +105,28 @@
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"微信配置"
align=
"center
"
>
<el-table-column
align=
"center"
label=
"微信配置
"
>
<el-table-column
:label=
"channel.name.replace('微信', '')"
align=
"center"
v-for=
"channel in wxChannels"
:key=
"channel.code"
:label=
"channel.name.replace('微信', '')"
align=
"center"
>
<
template
#
default=
"scope"
>
<el-button
type=
"success"
v-if=
"isChannelExists(scope.row.channelCodes, channel.code)"
@
click=
"openChannelForm(scope.row, channel.code)"
circle
size=
"small"
type=
"success"
@
click=
"openChannelForm(scope.row, channel.code)"
>
<Icon
icon=
"ep:check"
/>
</el-button>
<el-button
v-else
type=
"danger"
circle
size=
"small"
type=
"danger"
@
click=
"openChannelForm(scope.row, channel.code)"
>
<Icon
icon=
"ep:close"
/>
...
...
@@ -134,23 +134,23 @@
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"钱包支付配置"
align=
"center
"
>
<el-table-column
align=
"center"
label=
"钱包支付配置
"
>
<el-table-column
:label=
"PayChannelEnum.WALLET.name"
align=
"center"
>
<
template
#
default=
"scope"
>
<el-button
type=
"success
"
v-if=
"isChannelExists(scope.row.channelCodes, PayChannelEnum.WALLET.code)
"
circle
size=
"small"
v-if=
"isChannelExists(scope.row.channelCodes, PayChannelEnum.WALLET.code)
"
type=
"success
"
@
click=
"openChannelForm(scope.row, PayChannelEnum.WALLET.code)"
>
<Icon
icon=
"ep:check"
/>
</el-button>
<el-button
v-else
type=
"danger"
circle
size=
"small"
type=
"danger"
@
click=
"openChannelForm(scope.row, PayChannelEnum.WALLET.code)"
>
<Icon
icon=
"ep:close"
/>
...
...
@@ -158,23 +158,23 @@
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"模拟支付配置"
align=
"center
"
>
<el-table-column
align=
"center"
label=
"模拟支付配置
"
>
<el-table-column
:label=
"PayChannelEnum.MOCK.name"
align=
"center"
>
<
template
#
default=
"scope"
>
<el-button
type=
"success
"
v-if=
"isChannelExists(scope.row.channelCodes, PayChannelEnum.MOCK.code)
"
circle
size=
"small"
v-if=
"isChannelExists(scope.row.channelCodes, PayChannelEnum.MOCK.code)
"
type=
"success
"
@
click=
"openChannelForm(scope.row, PayChannelEnum.MOCK.code)"
>
<Icon
icon=
"ep:check"
/>
</el-button>
<el-button
v-else
type=
"danger"
circle
size=
"small"
type=
"danger"
@
click=
"openChannelForm(scope.row, PayChannelEnum.MOCK.code)"
>
<Icon
icon=
"ep:close"
/>
...
...
@@ -182,21 +182,21 @@
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
min-width=
"110"
fixed=
"right
"
>
<el-table-column
align=
"center"
fixed=
"right"
label=
"操作"
min-width=
"110
"
>
<
template
#
default=
"scope"
>
<el-button
v-hasPermi=
"['pay:app:update']"
link
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['pay:app:update']"
>
编辑
</el-button>
<el-button
v-hasPermi=
"['pay:app:delete']"
link
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['pay:app:delete']"
>
删除
</el-button>
...
...
@@ -205,9 +205,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>
...
...
src/views/pay/wallet/transaction/WalletTransactionList.vue
View file @
eecfb90a
<
template
>
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
:s
tripe=
"true"
:show-overflow-tooltip
=
"true"
>
<el-table-column
label=
"编号"
align=
"center
"
prop=
"id"
/>
<el-table-column
label=
"钱包编号"
align=
"center
"
prop=
"walletId"
/>
<el-table-column
label=
"关联业务标题"
align=
"center
"
prop=
"title"
/>
<el-table-column
label=
"交易金额"
align=
"center
"
prop=
"price"
>
<el-table
v-loading=
"loading"
:data=
"list"
:s
how-overflow-tooltip=
"true"
:stripe
=
"true"
>
<el-table-column
align=
"center"
label=
"编号
"
prop=
"id"
/>
<el-table-column
align=
"center"
label=
"钱包编号
"
prop=
"walletId"
/>
<el-table-column
align=
"center"
label=
"关联业务标题
"
prop=
"title"
/>
<el-table-column
align=
"center"
label=
"交易金额
"
prop=
"price"
>
<template
#
default=
"
{ row }">
{{
fenToYuan
(
row
.
price
)
}}
元
</
template
>
</el-table-column>
<el-table-column
label=
"钱包余额"
align=
"center
"
prop=
"balance"
>
<el-table-column
align=
"center"
label=
"钱包余额
"
prop=
"balance"
>
<
template
#
default=
"{ row }"
>
{{
fenToYuan
(
row
.
balance
)
}}
元
</
template
>
</el-table-column>
<el-table-column
label=
"交易时间
"
:formatter=
"dateFormatter
"
align=
"center"
label=
"交易时间"
prop=
"createTime"
:formatter=
"dateFormatter"
width=
"180px"
/>
</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>
...
...
@@ -31,12 +31,18 @@
<
script
lang=
"ts"
setup
>
import
{
dateFormatter
}
from
'@/utils/formatTime'
import
*
as
WalletTransactionApi
from
'@/api/pay/wallet/transaction'
import
*
as
WalletApi
from
'@/api/pay/wallet/balance'
import
{
fenToYuan
}
from
'@/utils'
defineOptions
({
name
:
'WalletTransactionList'
})
const
{
walletId
}:
{
walletId
:
number
}
=
defineProps
({
const
props
=
defineProps
({
walletId
:
{
type
:
Number
,
required
:
false
},
userId
:
{
type
:
Number
,
required
:
false
}
})
...
...
@@ -52,7 +58,12 @@ const list = ref([]) // 列表的数据
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
queryParams
.
walletId
=
walletId
if
(
props
.
userId
)
{
const
wallet
=
await
WalletApi
.
getWallet
({
userId
:
props
.
userId
})
queryParams
.
walletId
=
wallet
.
id
as
any
}
else
{
queryParams
.
walletId
=
props
.
walletId
as
any
}
const
data
=
await
WalletTransactionApi
.
getWalletTransactionPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
...
...
@@ -65,4 +76,4 @@ onMounted(() => {
getList
()
})
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
<
style
lang=
"scss"
scoped
></
style
>
vite.config.ts
View file @
eecfb90a
import
{
resolve
}
from
'path'
import
{
loadEnv
}
from
'vite'
import
type
{
UserConfig
,
ConfigEnv
}
from
'vite'
import
{
createVitePlugins
}
from
'./build/vite'
import
{
include
,
exclude
}
from
"./build/vite/optimize"
import
{
resolve
}
from
'path'
import
type
{
ConfigEnv
,
UserConfig
}
from
'vite'
import
{
loadEnv
}
from
'vite'
import
{
createVitePlugins
}
from
'./build/vite'
import
{
exclude
,
include
}
from
"./build/vite/optimize"
// 当前执行node命令时文件夹的地址(工作目录)
const
root
=
process
.
cwd
()
// 路径查找
function
pathResolve
(
dir
:
string
)
{
return
resolve
(
root
,
'.'
,
dir
)
return
resolve
(
root
,
'.'
,
dir
)
}
// https://vitejs.dev/config/
export
default
({
command
,
mode
}:
ConfigEnv
):
UserConfig
=>
{
let
env
=
{}
as
any
const
isBuild
=
command
===
'build'
if
(
!
isBuild
)
{
env
=
loadEnv
((
process
.
argv
[
3
]
===
'--mode'
?
process
.
argv
[
4
]
:
process
.
argv
[
3
]),
root
)
}
else
{
env
=
loadEnv
(
mode
,
root
)
}
return
{
base
:
env
.
VITE_BASE_PATH
,
root
:
root
,
// 服务端渲染
server
:
{
port
:
env
.
VITE_PORT
,
// 端口号
host
:
"0.0.0.0"
,
open
:
env
.
VITE_OPEN
===
'true'
,
// 本地跨域代理. 目前注释的原因:暂时没有用途,server 端已经支持跨域
// proxy: {
// ['/admin-api']: {
// target: env.VITE_BASE_URL,
// ws: false,
// changeOrigin: true,
// rewrite: (path) => path.replace(new RegExp(`^/admin-api`), ''),
// },
// },
},
// 项目使用的vite插件。 单独提取到build/vite/plugin中管理
plugins
:
createVitePlugins
(),
css
:
{
preprocessorOptions
:
{
scss
:
{
additionalData
:
'@import "./src/styles/variables.scss";'
,
javascriptEnabled
:
true
}
}
},
resolve
:
{
extensions
:
[
'.mjs'
,
'.js'
,
'.ts'
,
'.jsx'
,
'.tsx'
,
'.json'
,
'.scss'
,
'.css'
],
alias
:
[
{
find
:
'vue-i18n'
,
replacement
:
'vue-i18n/dist/vue-i18n.cjs.js'
export
default
({
command
,
mode
}:
ConfigEnv
):
UserConfig
=>
{
let
env
=
{}
as
any
const
isBuild
=
command
===
'build'
if
(
!
isBuild
)
{
env
=
loadEnv
((
process
.
argv
[
3
]
===
'--mode'
?
process
.
argv
[
4
]
:
process
.
argv
[
3
]),
root
)
}
else
{
env
=
loadEnv
(
mode
,
root
)
}
return
{
base
:
env
.
VITE_BASE_PATH
,
root
:
root
,
// 服务端渲染
server
:
{
port
:
env
.
VITE_PORT
,
// 端口号
host
:
"0.0.0.0"
,
open
:
env
.
VITE_OPEN
===
'true'
,
// 本地跨域代理. 目前注释的原因:暂时没有用途,server 端已经支持跨域
// proxy: {
// ['/admin-api']: {
// target: env.VITE_BASE_URL,
// ws: false,
// changeOrigin: true,
// rewrite: (path) => path.replace(new RegExp(`^/admin-api`), ''),
// },
// },
},
{
find
:
/
\@\/
/
,
replacement
:
`
${
pathResolve
(
'src'
)}
/`
}
]
},
build
:
{
minify
:
'terser'
,
outDir
:
env
.
VITE_OUT_DIR
||
'dist'
,
sourcemap
:
env
.
VITE_SOURCEMAP
===
'true'
?
'inline'
:
false
,
// brotliSize: false,
terserOptions
:
{
compress
:
{
drop_debugger
:
env
.
VITE_DROP_DEBUGGER
===
'true'
,
drop_console
:
env
.
VITE_DROP_CONSOLE
===
'true'
}
},
rollupOptions
:
{
output
:
{
manualChunks
:
{
echarts
:
[
'echarts'
]
// 将 echarts 单独打包,参考 https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues/IAB1SX 讨论
}
// 项目使用的vite插件。 单独提取到build/vite/plugin中管理
plugins
:
createVitePlugins
(),
css
:
{
preprocessorOptions
:
{
scss
:
{
additionalData
:
'@import "./src/styles/variables.scss";'
,
javascriptEnabled
:
true
}
}
},
},
},
optimizeDeps
:
{
include
,
exclude
}
}
resolve
:
{
extensions
:
[
'.mjs'
,
'.js'
,
'.ts'
,
'.jsx'
,
'.tsx'
,
'.json'
,
'.scss'
,
'.css'
],
alias
:
[
{
find
:
'vue-i18n'
,
replacement
:
'vue-i18n/dist/vue-i18n.cjs.js'
},
{
find
:
/
\@\/
/
,
replacement
:
`
${
pathResolve
(
'src'
)}
/`
}
]
},
build
:
{
minify
:
'terser'
,
outDir
:
env
.
VITE_OUT_DIR
||
'dist'
,
sourcemap
:
env
.
VITE_SOURCEMAP
===
'true'
?
'inline'
:
false
,
// brotliSize: false,
terserOptions
:
{
compress
:
{
drop_debugger
:
env
.
VITE_DROP_DEBUGGER
===
'true'
,
drop_console
:
env
.
VITE_DROP_CONSOLE
===
'true'
}
},
rollupOptions
:
{
output
:
{
manualChunks
:
{
echarts
:
[
'echarts'
]
// 将 echarts 单独打包,参考 https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues/IAB1SX 讨论
}
},
},
},
optimizeDeps
:
{
include
,
exclude
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment