Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
quantum-blocks
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ui
quantum-blocks
Commits
e79407ce
Commit
e79407ce
authored
Feb 05, 2021
by
郝聪敏
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feature: v2.0提交
parent
21769f8c
Changes
56
Hide whitespace changes
Inline
Side-by-side
Showing
56 changed files
with
2770 additions
and
264 deletions
+2770
-264
operation.api.ts
app/web/api/operation.api.ts
+47
-0
dev.config.ts
app/web/config/dev.config.ts
+1
-1
test.config.ts
app/web/config/test.config.ts
+1
-1
index.vue
app/web/lib/Advertisement/index.vue
+44
-0
coupon-bg@2x.png
app/web/lib/Coupon/images/coupon-bg@2x.png
+0
-0
index.vue
app/web/lib/Coupon/index.vue
+232
-0
shopping-cart@2x.png
app/web/lib/Goods/images/shopping-cart@2x.png
+0
-0
special-recommend.png
app/web/lib/Goods/images/special-recommend.png
+0
-0
index.vue
app/web/lib/Goods/index.vue
+229
-0
index.vue
app/web/lib/GoodsTabs/index.vue
+90
-0
index.vue
app/web/lib/GuideCube/index.vue
+132
-0
index.vue
app/web/lib/Marquee/index.vue
+74
-0
index.vue
app/web/lib/Placeholder/index.vue
+22
-0
config.ts
app/web/lib/config.ts
+384
-48
index.ts
app/web/page/activity/component/FreedomContainer/index.ts
+4
-20
index.ts
app/web/page/activity/view/activity/index.ts
+9
-5
index.vue
app/web/page/activity/view/activity/index.vue
+3
-2
index.ts
app/web/page/editor/component/DynamicComponent/index.ts
+15
-18
index.vue
app/web/page/editor/component/DynamicComponent/index.vue
+1
-1
index.vue
...r/component/DynamicForm/component/ColorSelector/index.vue
+11
-3
index.vue
.../component/DynamicForm/component/ColumnSelector/index.vue
+39
-0
index.ts
.../component/DynamicForm/component/ComponentSelect/index.ts
+39
-0
index.vue
...component/DynamicForm/component/ComponentSelect/index.vue
+18
-0
coupon.column.ts
...cForm/component/CouponTableModal/columns/coupon.column.ts
+151
-0
index.ts
...component/DynamicForm/component/CouponTableModal/index.ts
+38
-0
index.vue
...omponent/DynamicForm/component/CouponTableModal/index.vue
+5
-0
index.vue
...editor/component/DynamicForm/component/FormList/index.vue
+117
-0
goods.column.ts
...micForm/component/GoodsTableModal/columns/goods.column.ts
+148
-0
goodsGroup.column.ts
...rm/component/GoodsTableModal/columns/goodsGroup.column.ts
+47
-0
index.ts
.../component/DynamicForm/component/GoodsTableModal/index.ts
+72
-0
index.vue
...component/DynamicForm/component/GoodsTableModal/index.vue
+5
-0
index.ts
...ditor/component/DynamicForm/component/TableModal/index.ts
+96
-0
index.vue
...itor/component/DynamicForm/component/TableModal/index.vue
+83
-0
index.vue
...e/editor/component/DynamicForm/component/Upload/index.vue
+1
-0
dynamicForm.mixin.ts
...mponent/DynamicForm/component/mixins/dynamicForm.mixin.ts
+26
-0
index.ts
app/web/page/editor/component/DynamicForm/index.ts
+92
-45
index.vue
app/web/page/editor/component/DynamicForm/index.vue
+36
-16
index.ts
app/web/page/editor/component/DynamicPageForm/index.ts
+49
-0
index.vue
app/web/page/editor/component/DynamicPageForm/index.vue
+66
-0
index.ts
app/web/page/editor/component/FreedomContainer/index.ts
+43
-25
index.vue
app/web/page/editor/component/FreedomContainer/index.vue
+2
-2
index.vue
app/web/page/editor/component/QgTable/index.vue
+55
-12
contextMenu.mixin.ts
app/web/page/editor/mixins/contextMenu.mixin.ts
+12
-2
goodsTabs.mixin.ts
app/web/page/editor/mixins/goodsTabs.mixin.ts
+59
-0
index.ts
app/web/page/editor/view/dashboard/index.ts
+48
-26
index.vue
app/web/page/editor/view/dashboard/index.vue
+22
-9
transformStyle.mixin.ts
app/web/page/mixins/transformStyle.mixin.ts
+25
-0
index.ts
app/web/page/store/modules/editor/index.ts
+14
-13
state.ts
app/web/page/store/modules/editor/state.ts
+5
-0
type.ts
app/web/page/store/modules/editor/type.ts
+2
-2
eventBus.service.ts
app/web/service/eventBus.service.ts
+2
-0
http.service.ts
app/web/service/http.service.ts
+11
-1
qg.service.ts
app/web/service/qg.service.ts
+12
-5
utils.service.ts
app/web/service/utils.service.ts
+25
-0
package.json
package.json
+3
-1
webpack.config.js
webpack.config.js
+3
-6
No files found.
app/web/api/operation.api.ts
0 → 100644
View file @
e79407ce
import
http
from
'
../service/http.service
'
;
import
config
from
'
../config
'
;
export
default
{
getPageList
(
params
)
{
return
http
.
get
(
'
editor/get/list
'
,
{
params
});
},
getPageById
(
params
)
{
return
http
.
get
(
`editor/get/
${
params
.
pageId
}
`
);
},
delPageById
(
pageId
)
{
return
http
.
delete
(
`editor/
${
pageId
}
`
);
},
updatePage
(
params
)
{
return
http
.
post
(
`editor/update`
,
params
);
},
savePage
(
params
)
{
return
http
.
post
(
`editor/save`
,
params
);
},
getTemplateList
()
{
return
http
.
get
(
'
editor/get/template
'
);
},
// 商品列表-查询
skuInfo
(
params
)
{
return
http
.
post
(
`
${
config
.
opapiHost
}
/kdspOp/api/kdsp/activity/activity-goods/sku-info/list`
,
params
,
{
accessToken
:
true
});
},
// 获取商品类目
categoryQuery
()
{
return
http
.
get
(
`
${
config
.
opapiHost
}
/kdspOp/api/kdsp/op/rear-category/query/all`
,
{
accessToken
:
true
});
},
// 优惠券搜索列表
couponList
(
params
)
{
return
http
.
post
(
`
${
config
.
opapiHost
}
/kdspOp/api/kdsp/op/coupon/list`
,
params
,
{
accessToken
:
true
});
},
// 商品管理-商品专题列表_分页
specialPage
(
params
)
{
return
http
.
post
(
`
${
config
.
opapiHost
}
/kdspOp/api/kdsp/activity/activity-goods/special/list-page`
,
params
,
{
accessToken
:
true
});
},
};
\ No newline at end of file
app/web/config/dev.config.ts
View file @
e79407ce
...
@@ -4,6 +4,6 @@ export default {
...
@@ -4,6 +4,6 @@ export default {
apiHost
:
`http://localhost:7001/`
,
apiHost
:
`http://localhost:7001/`
,
qiniuHost
:
`https://appsync.lkbang.net/`
,
qiniuHost
:
`https://appsync.lkbang.net/`
,
shenceUrl
:
`
${
protocol
}
//bn.xyqb.com/sa?project=default`
,
shenceUrl
:
`
${
protocol
}
//bn.xyqb.com/sa?project=default`
,
opapiHost
:
`
${
protocol
}
//opapi.q-gp.com
`
,
opapiHost
:
`
https://opapi-vcc2.liangkebang.net
`
,
qiniuUpHost
:
`
${
protocol
}
//up-z0.qiniup.com`
,
qiniuUpHost
:
`
${
protocol
}
//up-z0.qiniup.com`
,
};
};
app/web/config/test.config.ts
View file @
e79407ce
...
@@ -2,8 +2,8 @@ const protocol = EASY_ENV_IS_BROWSER ? window.location.protocol : 'https';
...
@@ -2,8 +2,8 @@ const protocol = EASY_ENV_IS_BROWSER ? window.location.protocol : 'https';
export
default
{
export
default
{
apiHost
:
`https://quantum-fe.liangkebang.net/`
,
apiHost
:
`https://quantum-fe.liangkebang.net/`
,
opApiHost
:
'
https://opapi-fe.liangkebang.net
'
,
qiniuHost
:
`https://appsync.lkbang.net/`
,
qiniuHost
:
`https://appsync.lkbang.net/`
,
shenceUrl
:
`
${
protocol
}
//bn.xyqb.com/sa?project=production`
,
shenceUrl
:
`
${
protocol
}
//bn.xyqb.com/sa?project=production`
,
opapiHost
:
`
${
protocol
}
//opapi.q-gp.com`
,
qiniuUpHost
:
`
${
protocol
}
//up-z0.qiniup.com`
,
qiniuUpHost
:
`
${
protocol
}
//up-z0.qiniup.com`
,
};
};
app/web/lib/Advertisement/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"ad"
:class=
"['ad',
{ 'ad_one': column === 1, 'ad_two': column === 2, 'ad_three': column === 3 }]" :id="id">
<a
:href=
"item.link"
v-for=
"(item, index) in list"
:key=
"index"
>
<cr-image
:src=
"item.img"
height=
"2.61rem"
width=
"100%"
></cr-image>
</a>
</div>
</
template
>
<
script
>
export
default
{
props
:
{
column
:
{
type
:
Number
,
default
:
2
},
list
:
{
type
:
Array
,
default
:
()
=>
([])
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.image-width(@width) {
a {
width: @width;
}
}
.ad {
display: flex;
justify-content: space-between;
margin: 0 12px;
&_one {
.image-width(100%);
}
&_two {
.image-width(49%);
}
&_three {
.image-width(32%);
}
}
</
style
>
\ No newline at end of file
app/web/lib/Coupon/images/coupon-bg@2x.png
0 → 100644
View file @
e79407ce
30.7 KB
app/web/lib/Coupon/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"goods"
v-if=
"column === 1"
>
<div
class=
"goods-item_one"
:style=
"style"
:key=
"goods.id"
v-for=
"goods in couponList"
>
<div
class=
"Gi_one-left"
>
<p>
¥
<span>
{{
goods
.
couponAmt
||
0
}}
</span></p>
<p>
{{
`满${goods.couponAmt || 0
}
元减${goods.limitAmt || 0
}
元`
}}
<
/p
>
<
/div
>
<
div
class
=
"
Gi_one-middle
"
>
<
p
>
{{
goods
.
name
}}
<
/p
>
<
p
>
2020.8
.
4
-
2020.9
.
4
<
/p
>
<
/div
>
<
cr
-
button
class
=
"
Gi_one-right
"
type
=
"
primary
"
>
点击领取
<
/cr-button
>
<
div
class
=
"
goods-item-mask
"
>
<
p
>
已抢空
<
/p
>
<
/div
>
<
/div
>
<
/div
>
<
div
v
-
else
:
class
=
"
['goods', {'goods_two': column === 2, 'goods_multiple': column === 3
}
]
"
>
<
div
class
=
"
goods-item
"
:
style
=
"
style
"
:
key
=
"
goods.id
"
v
-
for
=
"
goods in couponList
"
>
<
p
class
=
"
goods-item-title
"
>
{{
goods
.
name
}}
<
/p
>
<
p
class
=
"
goods-item-amount
"
>
¥
<
span
>
{{
goods
.
couponAmt
||
0
}}
<
/span></
p
>
<
p
class
=
"
goods-item-condition
"
>
{{
`满${goods.couponAmt || 0
}
元减${goods.limitAmt || 0
}
元`
}}
<
/p
>
<
cr
-
button
shape
=
"
circle
"
type
=
"
primary
"
>
点击领取
<
/cr-button
>
<
div
class
=
"
goods-item-mask
"
>
<
p
>
已抢空
<
/p
>
<
/div
>
<
/div
>
<
/div
>
<
/template
>
<
script
>
import
operationApi
from
'
@api/operation.api
'
;
export
default
{
inject
:
[
'
editor
'
],
props
:
{
couponsList
:
Array
,
couponsNumber
:
Number
,
column
:
{
type
:
Number
,
default
:
3
}
,
bgImage
:
String
,
bgColor
:
{
type
:
String
,
default
:
'
#fff
'
}
}
,
data
()
{
return
{
list
:
[]
}
}
,
computed
:
{
couponList
()
{
if
(
this
.
editor
)
this
.
$nextTick
(()
=>
this
.
editor
.
adjustHeight
());
return
this
.
list
.
slice
(
0
,
this
.
couponsNumber
);
}
,
style
()
{
return
{
background
:
`url(${this.bgImage
}
) no-repeat 0 0 / cover`
,
backgroundColor
:
this
.
bgColor
}
}
}
,
watch
:
{
couponsList
:
{
handler
:
async
function
(
newVal
)
{
for
(
let
i
=
0
;
i
<
newVal
.
length
;
i
++
)
{
const
res
=
await
operationApi
.
couponList
({
couponId
:
newVal
[
i
]
}
);
const
couponInfoList
=
res
.
couponInfoList
;
if
(
couponInfoList
&&
couponInfoList
.
length
)
this
.
list
.
push
(
couponInfoList
[
0
]);
}
console
.
log
(
'
watch
'
,
this
.
list
);
}
,
immediate
:
true
}
}
}
<
/script
>
<
style
lang
=
"
less
"
scoped
>
::
-
webkit
-
scrollbar
{
display
:
none
;
/* Chrome Safari */
}
.
goods
{
width
:
100
%
;
padding
:
0
12
px
;
&-
item
{
position
:
relative
;
padding
:
4
px
8
px
;
display
:
inline
-
flex
;
flex
-
direction
:
column
;
justify
-
content
:
space
-
around
;
align
-
items
:
center
;
height
:
88
px
;
text
-
align
:
center
;
background
:
url
(
'
./images/coupon-bg@2x.png
'
)
no
-
repeat
0
0
/
cover
;
font
-
size
:
12
px
;
line
-
height
:
18
px
;
&
:
last
-
child
{
margin
-
right
:
0
;
}
&-
title
{
color
:
#
EC1500
;
}
&-
amount
{
color
:
#
EC1500
;
span
{
font
-
size
:
20
px
;
line
-
height
:
26
px
;
font
-
weight
:
600
;
}
}
&-
condition
{
color
:
#
999999
;
}
&-
mask
{
position
:
absolute
;
width
:
100
%
;
height
:
100
%
;
background
:
#
fff
;
opacity
:
0.7
;
p
{
position
:
absolute
;
top
:
50
%
;
left
:
50
%
;
transform
:
translate
(
-
50
%
,
-
50
%
);
width
:
66
px
;
height
:
66
px
;
line
-
height
:
66
px
;
text
-
align
:
center
;
border
-
radius
:
50
%
;
background
-
color
:
#
000
;
color
:
#
fff
;
font
-
weight
:
600
;
}
}
}
&
_multiple
{
overflow
-
x
:
auto
;
white
-
space
:
nowrap
;
padding
:
0
4
px
;
.
goods
-
item
{
width
:
114
px
;
margin
-
right
:
4
px
;
}
}
&
_two
{
display
:
flex
;
flex
-
wrap
:
wrap
;
justify
-
content
:
space
-
between
;
.
goods
-
item
{
margin
-
bottom
:
8
px
;
width
:
170
px
;
&
_empty
{
padding
:
0
;
margin
:
0
;
height
:
0
;
}
}
}
&-
item_one
{
position
:
relative
;
margin
-
bottom
:
8
px
;
display
:
flex
;
justify
-
content
:
space
-
between
;
align
-
items
:
center
;
font
-
size
:
12
px
;
.
Gi_one
-
left
{
position
:
relative
;
padding
:
8
px
0
;
display
:
flex
;
flex
-
direction
:
column
;
justify
-
content
:
space
-
around
;
width
:
90
px
;
&
:
after
{
content
:
""
;
position
:
absolute
;
right
:
0
;
height
:
100
%
;
border
-
style
:
dashed
;
border
-
width
:
0
1
px
0
0
;
border
-
color
:
#
EC3333
;
transform
:
scaleX
(.
5
);
}
p
{
line
-
height
:
18
px
;
color
:
#
EC3333
;
span
{
font
-
size
:
20
px
;
line
-
height
:
26
px
;
font
-
weight
:
600
;
}
}
}
.
Gi_one
-
middle
{
flex
:
1
;
padding
:
8
px
0
;
margin
-
left
:
8
px
;
text
-
align
:
left
;
p
{
&
:
first
-
child
{
font
-
size
:
14
px
;
line
-
height
:
20
px
;
font
-
weight
:
600
;
}
&
:
last
-
child
{
line
-
height
:
24
px
;
}
}
}
.
Gi_one
-
right
{
width
:
56
px
;
height
:
80
px
!
important
;
}
}
// 组件库替换变量处理
/deep/
.
cr
-
button
--
primary
{
height
:
20
px
;
line
-
height
:
20
px
;
border
:
0
;
font
-
size
:
12
px
;
background
:
linear
-
gradient
(
269
deg
,
#
ff5d00
12
%
,
#
ff1900
86
%
);
}
}
<
/style>
\ No newline at end of file
app/web/lib/Goods/images/shopping-cart@2x.png
0 → 100644
View file @
e79407ce
951 Bytes
app/web/lib/Goods/images/special-recommend.png
0 → 100644
View file @
e79407ce
243 KB
app/web/lib/Goods/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"container"
>
<cr-image
width=
"100%"
height=
"2.4rem"
:src=
"specialRecommend"
@
click=
"go()"
v-if=
"showSpecial"
></cr-image>
<div
class=
"goods"
v-if=
"column === 1"
>
<div
class=
"goods-item goods-item_one"
v-for=
"goods in goodsList"
:key=
"goods.id"
>
<cr-image
width=
"100%"
height=
"3.15rem"
class=
"goods-item-img"
fit=
"contain"
src=
"https://img14.360buyimg.com/n0/jfs/t1/141986/32/5318/98164/5f3236baE713fd239/5f2746db41f3e9c0.jpg"
></cr-image>
<div
class=
"goods-item_one-right"
>
<p
class=
"goods-item-title"
>
商品名称商品名称商品名称商品商品名称商品商品名称商品名称商品名称商品商品名称商品商品名称商品名称商品名称商品商品名称商品
</p>
<div
class=
"goods-item-bottom"
>
<div
class=
"Gi-bottom-left"
>
<p>
¥320.00
</p>
<p>
¥999.00
</p>
</div>
<cr-button
shape=
"circle"
type=
"primary"
>
立即购买
</cr-button>
</div>
</div>
</div>
</div>
<div
class=
"goods"
v-else
>
<div
:class=
"['goods-item',
{'goods-item_three': column === 3, 'goods-item_two': column === 2}]" v-for="goods in goodsList" :key="goods.id">
<cr-image
width=
"100%"
height=
"3.15rem"
class=
"goods-item-img"
fit=
"contain"
src=
"https://img14.360buyimg.com/n0/jfs/t1/141986/32/5318/98164/5f3236baE713fd239/5f2746db41f3e9c0.jpg"
></cr-image>
<p
class=
"goods-item-title"
>
商品名称商品名称商品名称商品商品名称商品
</p>
<div
class=
"goods-item-bottom"
>
<div
class=
"Gi-bottom-left"
>
<p>
¥320.00
</p>
<p>
¥999.00
</p>
</div>
<div
class=
"Gi-bottom-right"
>
<cr-image
width=
"0.45rem"
height=
"0.45rem"
:src=
"shoppingCart"
></cr-image>
</div>
</div>
</div>
<div
class=
"goods-item goods-item_three goods-item_empty"
v-if=
"showEmpty"
></div>
</div>
</div>
</
template
>
<
script
>
import
shoppingCart
from
'
./images/shopping-cart@2x.png
'
;
import
specialRecommend
from
'
./images/special-recommend.png
'
;
import
operationApi
from
'
@api/operation.api
'
;
export
default
{
inject
:
[
'
editor
'
],
props
:
{
goods
:
{
type
:
Object
,
default
:
()
=>
({
type
:
'
goodsGroup
'
,
ids
:
[]
})
},
goodsNumber
:
Number
,
column
:
{
type
:
Number
,
default
:
2
},
showSpecial
:
{
type
:
Boolean
,
default
:
true
},
specialUrl
:
String
,
specialLink
:
String
,
},
data
()
{
return
{
list
:
[],
shoppingCart
,
specialRecommend
}
},
computed
:
{
goodsList
()
{
if
(
this
.
editor
)
this
.
$nextTick
(()
=>
this
.
editor
.
adjustHeight
());
return
this
.
list
.
slice
(
0
,
this
.
goodsNumber
);
},
showEmpty
()
{
return
this
.
column
===
3
&&
this
.
goodsNumber
%
3
===
2
;
}
},
watch
:
{
goods
:
{
handler
:
async
function
(
newVal
)
{
if
(
newVal
.
type
===
'
goodsGroup
'
&&
newVal
.
ids
.
length
)
{
const
{
records
}
=
await
operationApi
.
skuInfo
({
brandId
:
newVal
.
ids
[
0
]
});
if
(
records
&&
records
.
length
)
this
.
list
=
records
;
}
console
.
log
(
'
watch
'
,
this
.
list
);
},
immediate
:
true
}
},
methods
:
{
go
()
{
if
(
this
.
specialLink
)
{
window
.
location
.
href
=
this
.
specialLink
;
}
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.container {
margin: 0 12px;
.goods {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 4px;
font-size: 0;
&-item {
border-radius: 8px;
background: #fff;
margin-bottom: 4px;
overflow: hidden;
&-title {
font-size: 13px;
line-height: 18px;
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text-align: left;
}
&-bottom {
display: flex;
justify-content: space-between;
align-items: center;
.Gi-bottom-left {
p {
text-align: left;
&:first-child {
font-size: 15px;
color: #EC3333;
}
&:last-child {
font-size: 13px;
color: #999999;
text-decoration:line-through;
}
}
}
.Gi-bottom-right {
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
background: #FFF3F3;
border-radius: 50%;
/deep/ .cr-image {
width: 18px !important;
height: 18px !important;
}
}
}
&_one {
display: flex;
width: 100%;
.goods-item-img {
width: 112px !important;
height: 109px !important;
}
&-right {
padding: 6px 8px;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.Gi-bottom-left {
margin-right: 10px;
flex: 1;
display: flex;
justify-content: space-around;
align-items: flex-end;
}
// 组件库替换变量处理
/deep/ .cr-button--primary {
height: 24px;
line-height: 24px;
border: 0;
background: linear-gradient(269deg, #ff5d00 12%, #ff1900 86%);
}
}
}
&_two {
width: 49%;
.goods-item-img {
width: 100% !important;
height: 180px !important;
}
.goods-item-title {
margin: 8px 8px;
}
.goods-item-bottom {
margin: 0 8px 6px;
}
}
&_three {
width: 32%;
.goods-item-img {
width: 100% !important;
height: 117px !important;
}
.goods-item-title {
margin: 8px 4px;
}
.goods-item-bottom {
margin: 0 4px 6px;
.goods-item-bottom {
}
}
}
&_empty {
height: 0;
}
}
}
}
</
style
>
\ No newline at end of file
app/web/lib/GoodsTabs/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"tabs"
>
<cr-tabs
@
change=
"tabsChange"
animated
:underline-color=
"underlineColor"
:title-active-color=
"activeColor"
:title-inactive-color=
"inactiveColor"
>
<cr-tab
v-for=
"(tab, index) in tabs"
:key=
"index"
:name=
"index"
:title=
"tab.tabTitle"
>
<component
:is=
"tab.name"
v-bind=
"tab.props"
:style=
"transformStyle(tab.commonStyle)"
></component>
</cr-tab>
</cr-tabs>
</div>
</
template
>
<
script
>
import
Goods
from
'
../Goods/index.vue
'
;
import
Coupon
from
'
../Coupon/index.vue
'
;
export
default
{
name
:
'
goods-tabs
'
,
components
:
{
Goods
,
Coupon
},
props
:
{
list
:
{
type
:
Array
,
default
:
()
=>
[]
},
childItem
:
{
type
:
Object
,
default
:
()
=>
({
child
:
[]
})
},
activeColor
:
{
type
:
String
,
default
:
'
#323233
'
},
inactiveColor
:
{
type
:
String
,
default
:
'
#646566
'
},
underlineColor
:
{
type
:
String
,
default
:
'
#1989fa
'
}
},
data
()
{
return
{
}
},
computed
:
{
tabs
()
{
const
list
=
this
.
list
.
map
(
tab
=>
{
const
rs
=
{
...
tab
};
this
.
childItem
?.
child
.
forEach
(
ele
=>
{
if
(
tab
.
componentId
===
ele
.
id
)
Object
.
assign
(
rs
,
tab
,
ele
);
})
return
rs
;
});
console
.
log
(
'
tabs
'
,
this
.
childItem
.
child
,
list
);
return
list
;
}
},
methods
:
{
tabsChange
(
name
)
{
console
.
log
(
'
change
'
,
name
);
},
transformStyle
(
styleObj
=
{})
{
// console.log('transformStyle', styleObj);
const
style
=
{};
for
(
const
key
of
Object
.
keys
(
styleObj
))
{
style
[
key
]
=
styleObj
[
key
];
if
(
key
===
'
backgroundImage
'
)
{
style
.
background
=
`url(
${
style
.
backgroundImage
}
) no-repeat 0 0 / cover`
;
}
}
return
style
;
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
/deep/ .cr-tabs__nav {
background-color: transparent;
}
/deep/ .cr-swipe-item {
&:nth-child(odd) {
background-color: #66c6f2;
}
&:nth-child(2n) {
background-color: #39a9ed;
}
height: 500px;
}
</
style
>
\ No newline at end of file
app/web/lib/GuideCube/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"guide-cube"
>
<swiper
v-if=
"showSwiper"
class=
"guide-cube-swiper"
ref=
"mySwiper"
:options=
"swiperOptions"
>
<swiper-slide
:style=
"style"
:class=
"
{'swiper-slide_two': slidesPerColumn === 2, 'swiper-slide_one': slidesPerColumn === 1 }" :key="index" v-for="(item, index) in list" @click="go(item.link)">
<cr-image
width=
""
height=
""
:src=
"item.img"
fit=
"cover"
:show-loading=
"false"
></cr-image>
</swiper-slide>
</swiper>
</div>
</
template
>
<
script
>
import
{
swiper
,
swiperSlide
}
from
'
vue-awesome-swiper
'
;
import
'
swiper/dist/css/swiper.css
'
;
export
default
{
inject
:
[
'
editor
'
],
components
:
{
swiper
,
swiperSlide
,
},
props
:
{
list
:
{
type
:
Array
,
default
:
()
=>
([])
},
slidesPerColumn
:
{
type
:
Number
,
default
:
1
},
loop
:
Boolean
,
autoplay
:
Boolean
},
data
()
{
const
vm
=
this
;
return
{
showSwiper
:
true
,
style
:
{},
swiperOptions
:
{
loop
:
this
.
loop
,
slidesPerView
:
4
,
slidesPerColumn
:
this
.
slidesPerColumn
,
spaceBetween
:
8
,
observer
:
true
,
observeParents
:
true
,
watchSlidesProgress
:
true
,
autoplay
:
this
.
autoplay
,
on
:
{
progress
:
function
()
{
// console.log('memorys', vm.memorys);
const
slidesLength
=
this
.
slides
.
length
;
for
(
let
i
=
0
;
i
<
this
.
slides
.
length
;
i
++
)
{
const
slide
=
this
.
slides
.
eq
(
i
);
let
scale
=
Math
.
abs
(
this
.
slides
[
i
].
progress
%
1
).
toFixed
(
10
)
*
0.2
;
// 记录初始状态,用来复位
if
(
i
===
0
)
this
.
slides
[
0
].
scale
=
scale
;
if
(
!
this
.
slides
[
0
].
scale
)
{
vm
.
memorys
[
i
]
=
vm
.
memorys
[
i
]
?
0
:
1
;
scale
=
0.2
;
}
// 差别对待不同索引
if
(
vm
.
memorys
[
i
])
{
scale
=
1
-
scale
;
}
else
{
scale
=
0.8
+
scale
;
}
slide
.
transform
(
`scale3d(
${
scale
}
,
${
scale
}
, 1)`
);
}
},
},
}
}
},
computed
:
{
swiper
()
{
return
this
.
$refs
.
mySwiper
.
swiper
},
memorys
()
{
const
length
=
this
.
list
.
length
;
const
baseNumber
=
this
.
slidesPerColumn
===
1
?
2
:
4
;
return
new
Array
(
length
).
fill
(
0
).
map
((
v
,
i
)
=>
[
0
,
3
].
includes
(
i
%
baseNumber
)
?
1
:
0
);
}
},
watch
:
{
slidesPerColumn
(
newVal
)
{
this
.
refreshSwiper
(
'
slidesPerColumn
'
,
newVal
);
},
autoplay
(
newVal
)
{
this
.
refreshSwiper
(
'
autoplay
'
,
newVal
);
},
loop
(
newVal
)
{
this
.
refreshSwiper
(
'
loop
'
,
newVal
);
},
},
mounted
()
{
this
.
style
=
{
transition
:
'
all .4s cubic-bezier(.4, 0, .2, 1)
'
}
},
methods
:
{
go
(
url
)
{
window
.
location
.
href
=
url
;
},
refreshSwiper
(
key
,
val
)
{
this
.
swiperOptions
[
key
]
=
val
;
this
.
showSwiper
=
false
;
this
.
$nextTick
(()
=>
this
.
showSwiper
=
true
);
if
(
this
.
editor
)
setTimeout
(()
=>
this
.
editor
.
adjustHeight
(),
0
);
}
},
}
</
script
>
<
style
lang=
"less"
scoped
>
.guide-cube {
padding: 12px;
&-swiper {
width: 100%;
.swiper-slide {
display: flex;
justify-content: center;
align-items: center;
width: 81px;
height: 81px;
/deep/ .cr-image {
width: 100%;
height: 100%;
border-radius: 8px;
overflow: hidden;
}
}
}
}
</
style
>
\ No newline at end of file
app/web/lib/Marquee/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"marquee"
>
<swiper
class=
"marquee-swiper"
ref=
"mySwiper"
:options=
"swiperOptions"
>
<swiper-slide
:key=
"index"
v-for=
"(item, index) in list"
>
<span
:style=
"styles"
>
{{
item
.
text
}}
</span>
</swiper-slide>
</swiper>
</div>
</
template
>
<
script
>
import
{
swiper
,
swiperSlide
}
from
'
vue-awesome-swiper
'
;
import
'
swiper/dist/css/swiper.css
'
;
export
default
{
inject
:
[
'
editor
'
],
components
:
{
swiper
,
swiperSlide
,
},
props
:
{
list
:
{
type
:
Array
,
default
:
()
=>
([])
},
fontColor
:
{
type
:
String
,
default
:
'
#666666
'
}
},
data
()
{
return
{
swiperOptions
:
{
// loop: true,
observer
:
true
,
observeParents
:
true
,
direction
:
'
vertical
'
,
allowTouchMove
:
false
,
autoplay
:
true
}
}
},
computed
:
{
swiper
()
{
return
this
.
$refs
.
mySwiper
.
swiper
},
styles
()
{
return
{
color
:
this
.
fontColor
}
}
},
}
</
script
>
<
style
lang=
"less"
scoped
>
.marquee {
width: 100%;
height: 30px;
border-radius: 8px;
background-color: #D8D8D8;
.swiper-container {
height: 100%;
.swiper-slide {
display: flex;
justify-content: center;
align-items: center;
span {
font-size: 14px;
line-height: 20px;
color: #666666;
}
}
}
}
</
style
>
\ No newline at end of file
app/web/lib/Placeholder/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"placeholder"
:style=
"style"
></div>
</
template
>
<
script
>
export
default
{
props
:
{
height
:
Number
,
},
computed
:
{
style
()
{
return
{
height
:
`
${
this
.
height
}
px`
}
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.placeholder {
min-height: 10px;
}
</
style
>
\ No newline at end of file
app/web/lib/config.ts
View file @
e79407ce
// export const basicComponents = require('@qg/cherry-ui/md/index.json');
// export const basicComponents = require('@qg/cherry-ui/md/index.json');
//
export const kaLoginForm = require('@qg/citrus-ui/md/index.json');
export
const
kaLoginForm
=
require
(
'
@qg/citrus-ui/md/index.json
'
);
export
const
basicComponents
=
[
export
const
basicComponents
=
[
{
{
eleName
:
'
freedom-container
'
,
eleName
:
'
freedom-container
'
,
title
:
'
自由容器
'
,
title
:
'
自由容器
'
,
h
:
300
,
config
:
[
config
:
[
{
// {
key
:
'
backgroundImage
'
,
// key: 'backgroundImage',
name
:
'
背景图片
'
,
// name: '背景图片',
type
:
'
Upload
'
// type: 'Upload'
},
// },
// {
// key: 'backgroundColor',
// name: '背景颜色',
// type: 'ColorSelector'
// },
],
],
value
:
{
value
:
{
backgroundImage
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
;
// backgroundImage: 'http://activitystatic.q-gp.com/landing-bg.png';
// backgroundColor: '#fff'
},
},
commonStyle
:
{}
commonStyle
:
{}
},
},
{
{
h
:
44
,
eleName
:
'
cr-button
'
,
eleName
:
'
cr-button
'
,
title
:
'
Button 按钮
'
,
title
:
'
Button 按钮
'
,
config
:
[
config
:
[
...
@@ -144,7 +148,6 @@ export const basicComponents = [
...
@@ -144,7 +148,6 @@ export const basicComponents = [
{
{
eleName
:
'
cr-image
'
,
eleName
:
'
cr-image
'
,
title
:
'
图片
'
,
title
:
'
图片
'
,
h
:
140
,
config
:
[
config
:
[
{
{
key
:
'
width
'
,
key
:
'
width
'
,
...
@@ -173,7 +176,6 @@ export const basicComponents = [
...
@@ -173,7 +176,6 @@ export const basicComponents = [
{
{
eleName
:
'
cr-nav-bar
'
,
eleName
:
'
cr-nav-bar
'
,
title
:
'
NavBar 导航栏
'
,
title
:
'
NavBar 导航栏
'
,
h
:
48
,
config
:
[
config
:
[
{
{
key
:
'
title
'
,
key
:
'
title
'
,
...
@@ -254,66 +256,400 @@ export const basicComponents = [
...
@@ -254,66 +256,400 @@ export const basicComponents = [
];
];
export
const
businessComponents
=
[
export
const
businessComponents
=
[
kaLoginForm
,
// {
// eleName: 'cs-ka-login-form',
// title: 'KA登陆表单',
// h: 224,
// config: [
// {
// key: 'btnTxt',
// name: '按钮文案',
// type: 'text'
// },
// {
// key: 'btnColor',
// name: '按钮颜色',
// type: 'ColorSelector'
// },
// {
// key: 'btnImage',
// name: '按钮图片',
// type: 'Upload'
// },
// {
// key: 'vcBgColor',
// name: '验证码背景色(可点击态)',
// type: 'ColorSelector'
// },
// {
// key: 'registerFrom',
// name: '渠道号',
// type: 'text'
// },
// ],
// value: {
// btnTxt: '',
// btnColor: '#ee0a24',
// btnImage: 'http://activitystatic.q-gp.com/landing-submit.png',
// registerFrom: '',
// vcBgColor: '#97d5ff'
// },
// commonStyle: {}
// },
{
{
eleName
:
'
login-form
'
,
eleName
:
'
download-guide
'
,
title
:
'
KA登陆表单
'
,
title
:
'
下载引导
'
,
h
:
224
,
h
:
40
,
config
:
[
config
:
[
{
{
key
:
'
btnTxt
'
,
key
:
'
href
'
,
name
:
'
按钮文案
'
,
name
:
'
跳转链接
'
,
type
:
'
text
'
type
:
'
text
'
},
},
{
{
key
:
'
btnColor
'
,
key
:
'
leftImg
'
,
name
:
'
按钮颜色
'
,
name
:
'
logo
'
,
type
:
'
ColorSelector
'
},
{
key
:
'
btnImage
'
,
name
:
'
按钮图片
'
,
type
:
'
Upload
'
type
:
'
Upload
'
},
}
],
value
:
{
href
:
'
https://s.xyqb.com/4
'
,
leftImg
:
'
http://activitystatic.q-gp.com/xyqb%402x.png
'
},
commonStyle
:
{}
},
{
eleName
:
'
goods-tabs
'
,
title
:
'
商品导航
'
,
config
:
[
{
{
key
:
'
vcBgColor
'
,
title
:
'
标签录入
'
,
name
:
'
验证码背景色(可点击态)
'
,
children
:
[
type
:
'
ColorSelector
'
{
key
:
'
list
'
,
name
:
'
添加菜单
'
,
type
:
'
FormList
'
,
formControl
:
[
{
key
:
'
tabTitle
'
,
name
:
'
名称
'
,
type
:
'
text
'
},
{
key
:
'
componentId
'
,
name
:
'
组件
'
,
type
:
'
ComponentSelect
'
,
// componentSelect
}
]
}
]
},
},
{
{
key
:
'
registerFrom
'
,
title
:
'
标签样式
'
,
name
:
'
渠道号
'
,
children
:
[
type
:
'
text
'
{
key
:
'
activeColor
'
,
name
:
'
选中态文字颜色
'
,
type
:
'
ColorSelector
'
},
{
key
:
'
inactiveColor
'
,
name
:
'
默认态文字颜色
'
,
type
:
'
ColorSelector
'
},
{
key
:
'
underlineColor
'
,
name
:
'
下划线颜色
'
,
type
:
'
ColorSelector
'
},
]
}
],
value
:
{
list
:
[{
tabTitle
:
'
tab1
'
,
componentId
:
'
1
'
},
{
tabTitle
:
'
tab2
'
,
componentId
:
'
2
'
}],
activeColor
:
'
#323233
'
,
inactiveColor
:
'
#646566
'
,
underlineColor
:
'
#1989fa
'
,
},
commonStyle
:
{}
},
{
eleName
:
'
Goods
'
,
title
:
'
商品
'
,
config
:
[
{
title
:
'
商品录入
'
,
children
:
[{
key
:
'
column
'
,
name
:
'
商品列数
'
,
type
:
'
ColumnSelector
'
},
{
key
:
'
goods
'
,
name
:
'
选择商品
'
,
type
:
'
GoodsTableModal
'
,
formControl
:
[
{
key
:
'
goodsNumber
'
,
name
:
'
商品数量
'
,
type
:
'
number
'
}
]
}]
},
},
{
title
:
'
专题推荐
'
,
children
:
[
{
key
:
'
showSpecial
'
,
name
:
'
显示专题
'
,
type
:
'
checkbox
'
},
{
key
:
'
specialUrl
'
,
name
:
'
专题图片
'
,
type
:
'
Upload
'
},
{
key
:
'
specialLink
'
,
name
:
'
专题链接
'
,
type
:
'
text
'
},
]
}
],
],
value
:
{
value
:
{
btnTxt
:
''
,
goods
:
{
btnColor
:
'
#ee0a24
'
,
type
:
'
goodsGroup
'
,
btnImage
:
'
http://activitystatic.q-gp.com/landing-submit.png
'
,
ids
:
[]
registerFrom
:
''
,
},
vcBgColor
:
'
#97d5ff
'
goodsNumber
:
3
,
column
:
2
,
showSpecial
:
true
,
specialUrl
:
''
,
specialLink
:
''
},
},
commonStyle
:
{}
commonStyle
:
{}
},
},
{
{
eleName
:
'
download-guide
'
,
eleName
:
'
Coupon
'
,
title
:
'
下载引导
'
,
title
:
'
优惠券
'
,
h
:
40
,
config
:
[
config
:
[
{
{
key
:
'
href
'
,
title
:
'
优惠券录入
'
,
name
:
'
跳转链接
'
,
children
:
[
type
:
'
text
'
{
key
:
'
column
'
,
name
:
'
优惠券列数
'
,
type
:
'
ColumnSelector
'
},
{
key
:
'
couponsList
'
,
name
:
'
选择优惠券
'
,
type
:
'
CouponTableModal
'
,
formControl
:
[
{
key
:
'
couponsNumber
'
,
name
:
'
优惠券数量
'
,
type
:
'
number
'
}
]
},
],
},
},
{
{
key
:
'
leftImg
'
,
title
:
'
优惠券样式
'
,
name
:
'
logo
'
,
children
:
[
type
:
'
Upload
'
{
key
:
'
bgImage
'
,
name
:
'
优惠券背景图片
'
,
type
:
'
Upload
'
},
{
key
:
'
bgColor
'
,
name
:
'
优惠券背景颜色
'
,
type
:
'
ColorSelector
'
},
]
}
}
],
],
value
:
{
value
:
{
href
:
'
https://s.xyqb.com/4
'
,
couponsList
:
[
153
,
152
,
151
,
150
,
149
],
leftImg
:
'
http://activitystatic.q-gp.com/xyqb%402x.png
'
couponsNumber
:
3
,
column
:
3
,
bgColor
:
'
#fff
'
,
bgImage
:
''
,
},
},
commonStyle
:
{}
commonStyle
:
{}
}
},
];
{
eleName
:
'
Advertisement
'
,
title
:
'
广告
'
,
config
:
[
{
key
:
'
column
'
,
name
:
'
广告列数
'
,
type
:
'
ColumnSelector
'
},
{
key
:
'
list
'
,
name
:
'
添加广告
'
,
type
:
'
FormList
'
,
formControl
:
[
{
key
:
'
img
'
,
name
:
'
图片
'
,
type
:
'
Upload
'
},
{
key
:
'
link
'
,
name
:
'
链接
'
,
type
:
'
text
'
,
// componentSelect
}
]
}
],
value
:
{
list
:
[{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
}],
column
:
2
}
},
{
eleName
:
'
Placeholder
'
,
title
:
'
楼层间隔
'
,
config
:
[
{
key
:
'
height
'
,
name
:
'
间隔高度
'
,
type
:
'
Slider
'
},
],
value
:
{
height
:
10
}
},
{
eleName
:
'
GuideCube
'
,
title
:
'
导购魔方
'
,
config
:
[
{
key
:
'
slidesPerColumn
'
,
name
:
'
行数
'
,
type
:
'
InputNumber
'
},
{
key
:
'
loop
'
,
name
:
'
循环
'
,
type
:
'
checkbox
'
},
{
key
:
'
autoplay
'
,
name
:
'
自动播放
'
,
type
:
'
checkbox
'
},
{
key
:
'
list
'
,
name
:
'
添加导购
'
,
type
:
'
FormList
'
,
formControl
:
[
{
key
:
'
img
'
,
name
:
'
图片
'
,
type
:
'
Upload
'
},
{
key
:
'
link
'
,
name
:
'
链接
'
,
type
:
'
text
'
,
// componentSelect
}
]
}
],
value
:
{
list
:
[{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
},
{
img
:
'
http://activitystatic.q-gp.com/landing-bg.png
'
,
link
:
'
http://activitystatic.q-gp.com
'
}],
slidesPerColumn
:
1
,
loop
:
false
,
autoplay
:
false
}
},
{
eleName
:
'
Marquee
'
,
title
:
'
跑马灯
'
,
config
:
[
{
key
:
'
fontColor
'
,
name
:
'
字体颜色
'
,
type
:
'
ColorSelector
'
,
},
{
key
:
'
list
'
,
name
:
'
添加数据
'
,
type
:
'
FormList
'
,
formControl
:
[
{
key
:
'
text
'
,
name
:
'
文案
'
,
type
:
'
text
'
},
]
}
],
value
:
{
fontColor
:
'
#666666
'
,
list
:
[{
text
:
'
请输入文案
'
},
{
text
:
'
请输入文案
'
}]
}
},
];
\ No newline at end of file
app/web/page/activity/component/FreedomContainer/index.ts
View file @
e79407ce
import
{
cloneDeep
}
from
'
lodash
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
{
Component
,
Prop
,
Vue
}
from
'
vue-property-decorator
'
;
import
{
Component
,
Prop
,
Vue
,
Mixins
}
from
'
vue-property-decorator
'
;
import
{
Action
,
Mutation
,
State
,
Getter
}
from
'
vuex-class
'
;
import
{
Action
,
Mutation
,
State
,
Getter
}
from
'
vuex-class
'
;
import
LoginForm
from
'
@/lib/Form/index.vue
'
;
import
TransformStyleMixin
from
'
@/page/mixins/transformStyle.mixin
'
;
import
{
ContextMenu
}
from
'
@editor/mixins/contextMenu.mixin
'
;
import
{
resizeDiv
}
from
'
@/service/utils.service
'
;
import
{
resizeDiv
}
from
'
@/service/utils.service
'
;
@
Component
({
components
:
{
LoginForm
},
name
:
'
FreedomContainer
'
})
@
Component
({
name
:
'
FreedomContainer
'
})
export
default
class
FreedomContainer
extends
Vue
{
export
default
class
FreedomContainer
extends
Mixins
(
TransformStyleMixin
)
{
@
Getter
(
'
pageData
'
)
pageData
;
@
Getter
(
'
pageData
'
)
pageData
;
@
State
(
state
=>
state
.
editor
.
curChildIndex
)
curChildIndex
;
@
State
(
state
=>
state
.
editor
.
curChildIndex
)
curChildIndex
;
@
Mutation
(
'
UPDATE_PAGE_INFO
'
)
updatePageInfo
;
@
Mutation
(
'
UPDATE_PAGE_INFO
'
)
updatePageInfo
;
...
@@ -14,21 +13,6 @@ export default class FreedomContainer extends Vue {
...
@@ -14,21 +13,6 @@ export default class FreedomContainer extends Vue {
@
Prop
({
type
:
Object
,
default
:
()
=>
({
child
:
[]
})})
childItem
;
@
Prop
({
type
:
Object
,
default
:
()
=>
({
child
:
[]
})})
childItem
;
@
Prop
(
String
)
backgroundImage
;
@
Prop
(
String
)
backgroundImage
;
transformStyle
(
styleObj
)
{
const
style
=
{};
for
(
const
key
of
Object
.
keys
(
styleObj
))
{
if
(
typeof
styleObj
[
key
]
===
'
number
'
)
{
style
[
key
]
=
`
${(
styleObj
[
key
]
/
37.5
).
toFixed
(
3
)}
rem`
;
}
else
{
style
[
key
]
=
styleObj
[
key
].
includes
(
'
px
'
)
?
`
${(
+
(
styleObj
[
key
].
slice
(
0
,
-
2
))
/
37.5
).
toFixed
(
3
)}
rem`
:
styleObj
[
key
];
}
if
(
key
===
'
backgroundImage
'
)
{
style
.
backgroundImage
=
`url(
${
style
.
backgroundImage
}
)`
;
}
}
return
style
;
}
mounted
()
{
mounted
()
{
// 根据背景图设置元素高度
// 根据背景图设置元素高度
const
index
=
this
.
pageData
?.
elements
?.
findIndex
(
v
=>
v
.
point
?.
responsive
);
const
index
=
this
.
pageData
?.
elements
?.
findIndex
(
v
=>
v
.
point
?.
responsive
);
...
...
app/web/page/activity/view/activity/index.ts
View file @
e79407ce
import
{
kebabCase
}
from
'
lodash
'
;
import
{
kebabCase
}
from
'
lodash
'
;
import
{
Vue
,
Component
,
Watch
}
from
'
vue-property-decorator
'
;
import
{
Vue
,
Component
,
Watch
,
Provide
,
Mixins
}
from
'
vue-property-decorator
'
;
import
eleConfig
from
'
../../../editor/utils/config
'
;
import
eleConfig
from
'
../../../editor/utils/config
'
;
import
FreedomContainer
from
'
../../component/FreedomContainer/index.vue
'
;
import
FreedomContainer
from
'
../../component/FreedomContainer/index.vue
'
;
import
GridLayout
from
'
../../component/VueGridLayout/GridLayout.vue
'
;
import
GridLayout
from
'
../../component/VueGridLayout/GridLayout.vue
'
;
import
GridItem
from
'
../../component/VueGridLayout/GridItem.vue
'
;
import
GridItem
from
'
../../component/VueGridLayout/GridItem.vue
'
;
import
LoginForm
from
'
@/lib/Form/index.vue
'
;
//
import LoginForm from '@/lib/Form/index.vue';
import
DownloadGuide
from
'
@/lib/DownloadGuide/index.vue
'
;
import
DownloadGuide
from
'
@/lib/DownloadGuide/index.vue
'
;
import
{
Getter
,
State
,
Mutation
}
from
'
vuex-class
'
;
import
{
Getter
,
State
,
Mutation
}
from
'
vuex-class
'
;
import
GuideCube
from
'
@/lib/GuideCube/index.vue
'
;
import
GoodsTabs
from
'
@/lib/GoodsTabs/index.vue
'
;
import
TransformStyleMixin
from
'
@/page/mixins/transformStyle.mixin
'
;
@
Component
({
components
:
{
FreedomContainer
,
GridLayout
,
GridItem
,
LoginForm
,
DownloadGuid
e
},
name
:
'
Activity
'
})
@
Component
({
components
:
{
FreedomContainer
,
GridLayout
,
GridItem
,
DownloadGuide
,
GoodsTabs
,
GuideCub
e
},
name
:
'
Activity
'
})
export
default
class
Activity
extends
Vue
{
export
default
class
Activity
extends
Mixins
(
TransformStyleMixin
)
{
@
Getter
(
'
pageData
'
)
pageData
;
@
Getter
(
'
pageData
'
)
pageData
;
@
State
(
state
=>
state
.
editor
.
pageInfo
.
pageName
)
pageName
;
@
State
(
state
=>
state
.
editor
.
pageInfo
.
pageName
)
pageName
;
@
State
(
state
=>
state
.
editor
.
gridLayout
.
rowHeight
)
rowHeight
;
@
State
(
state
=>
state
.
editor
.
gridLayout
.
rowHeight
)
rowHeight
;
@
Mutation
(
'
DEL_ELEMENTS
'
)
delPageInfo
;
@
Provide
(
'
editor
'
);
isLayoutComReady
=
false
;
isLayoutComReady
=
false
;
...
...
app/web/page/activity/view/activity/index.vue
View file @
e79407ce
<
template
>
<
template
>
<div
class=
"activity"
>
<div
class=
"activity"
:style=
"transformStyle(pageData.commonStyle)"
>
<grid-layout
<grid-layout
:layout.sync=
"layout"
:layout.sync=
"layout"
:isDraggable=
"false"
:isDraggable=
"false"
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
:h=
"item.point.h"
:h=
"item.point.h"
:i=
"item.point.i"
:i=
"item.point.i"
:key=
"item.point.i"
>
:key=
"item.point.i"
>
<component
class=
"Dcmc-panel-com"
:data-index=
"index"
:containerIndex=
"index"
:childItem=
"item"
:is=
"item.name"
:key=
"index"
@
delete=
"delPageInfo(index)
"
v-bind=
"item.props"
></component>
<component
:style=
"transformStyle(item.commonStyle)"
class=
"Dcmc-panel-com"
:data-index=
"index"
:containerIndex=
"index"
:childItem=
"item"
:is=
"item.name"
:key=
"index
"
v-bind=
"item.props"
></component>
</grid-item>
</grid-item>
</grid-layout>
</grid-layout>
</div>
</div>
...
@@ -45,6 +45,7 @@
...
@@ -45,6 +45,7 @@
background-color: rgb(244, 244, 244);
background-color: rgb(244, 244, 244);
box-shadow: 2px 0px 10px rgba(0, 0, 0, 0.2);
box-shadow: 2px 0px 10px rgba(0, 0, 0, 0.2);
/deep/ .vue-grid-layout {
/deep/ .vue-grid-layout {
min-height: 667px;
// transform: translateY(-10px);
// transform: translateY(-10px);
transition-property: none;
transition-property: none;
.vue-grid-item {
.vue-grid-item {
...
...
app/web/page/editor/component/DynamicComponent/index.ts
View file @
e79407ce
...
@@ -2,6 +2,7 @@ import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
...
@@ -2,6 +2,7 @@ import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
import
FreedomContainer
from
'
../../component/FreedomContainer/index.vue
'
;
import
FreedomContainer
from
'
../../component/FreedomContainer/index.vue
'
;
import
{
kebabCase
,
chunk
,
flatten
}
from
'
lodash
'
;
import
{
kebabCase
,
chunk
,
flatten
}
from
'
lodash
'
;
import
{
State
}
from
'
vuex-class
'
;
import
{
State
}
from
'
vuex-class
'
;
import
{
v4
as
uuid
}
from
'
uuid
'
;
@
Component
({
name
:
'
DynamicComponent
'
})
@
Component
({
name
:
'
DynamicComponent
'
})
export
default
class
DynamicComponent
extends
Vue
{
export
default
class
DynamicComponent
extends
Vue
{
...
@@ -18,30 +19,26 @@ export default class DynamicComponent extends Vue {
...
@@ -18,30 +19,26 @@ export default class DynamicComponent extends Vue {
dragstart
(
event
,
eleName
)
{
dragstart
(
event
,
eleName
)
{
this
.
$emit
(
'
dragstart
'
);
this
.
$emit
(
'
dragstart
'
);
const
eleConfig
=
flatten
(
this
.
eleConfig
).
find
(
config
=>
config
.
eleName
===
eleName
);
const
eleConfig
=
flatten
(
this
.
eleConfig
).
find
(
config
=>
config
.
eleName
===
eleName
);
const
id
=
uuid
().
slice
(
19
);
const
compontObj
=
{
id
,
name
:
eleName
,
title
:
eleConfig
.
title
,
point
:
{
x
:
0
,
y
:
0
,
w
:
this
.
colNum
,
h
:
300
,
i
:
id
},
schame
:
eleConfig
.
config
,
props
:
{...
eleConfig
.
value
},
commonStyle
:
eleConfig
.
commonStyle
};
// const props = this.getProps(eleName);
// const props = this.getProps(eleName);
if
(
eleName
.
includes
(
'
template
'
))
{
if
(
eleName
.
includes
(
'
template
'
))
{
event
.
dataTransfer
.
setData
(
'
text
'
,
JSON
.
stringify
({
event
.
dataTransfer
.
setData
(
'
text
'
,
JSON
.
stringify
({
template
:
eleConfig
.
page
template
:
eleConfig
.
page
}));
}));
}
else
if
(
eleName
===
'
freedom-container
'
)
{
// 自由容器和商品导航组件有child属性
event
.
dataTransfer
.
setData
(
'
text
'
,
JSON
.
stringify
({
}
else
if
(
eleName
===
'
freedom-container
'
||
eleName
===
'
goods-tabs
'
)
{
name
:
eleName
,
event
.
dataTransfer
.
setData
(
'
text
'
,
JSON
.
stringify
({
...
compontObj
,
child
:
[]
}));
title
:
eleConfig
.
title
,
point
:
{
x
:
0
,
y
:
2
,
w
:
this
.
colNum
,
h
:
eleConfig
.
h
||
1
,
i
:
'
0
'
},
child
:
[],
schame
:
eleConfig
.
config
,
props
:
{...
eleConfig
.
value
},
commonStyle
:
eleConfig
.
commonStyle
}));
}
else
{
}
else
{
event
.
dataTransfer
.
setData
(
'
text
'
,
JSON
.
stringify
({
event
.
dataTransfer
.
setData
(
'
text
'
,
JSON
.
stringify
(
compontObj
));
name
:
eleName
,
title
:
eleConfig
.
title
,
point
:
{
x
:
0
,
y
:
0
,
w
:
this
.
colNum
,
h
:
eleConfig
.
h
||
1
,
i
:
'
0
'
},
schame
:
eleConfig
.
config
,
props
:
{...
eleConfig
.
value
},
commonStyle
:
eleConfig
.
commonStyle
}));
}
}
event
.
dataTransfer
.
effectAllowed
=
'
copyMove
'
;
event
.
dataTransfer
.
effectAllowed
=
'
copyMove
'
;
}
}
...
...
app/web/page/editor/component/DynamicComponent/index.vue
View file @
e79407ce
...
@@ -34,7 +34,7 @@
...
@@ -34,7 +34,7 @@
}
}
}
}
/deep/
.ivu-card {
.ivu-card {
&-head {
&-head {
padding: 5px;
padding: 5px;
}
}
...
...
app/web/page/editor/component/DynamicForm/component/ColorSelector/index.vue
View file @
e79407ce
<
template
>
<
template
>
<div
class=
"color-selector"
>
<div
class=
"color-selector"
>
<Input
class=
"color-selector-input"
v-model=
"color"
placeholder=
"请输入"
></Input>
<Input
class=
"color-selector-input"
v-model=
"color"
placeholder=
"请输入"
@
on-change=
"change"
></Input>
<ColorPicker
v-model=
"color"
/>
<ColorPicker
v-model=
"color"
@
on-change=
"change"
/>
</div>
</div>
</
template
>
</
template
>
<
script
>
<
script
>
...
@@ -14,8 +14,16 @@
...
@@ -14,8 +14,16 @@
color
:
this
.
value
,
color
:
this
.
value
,
}
}
},
},
created
()
{
console
.
log
(
this
.
color
);
},
watch
:
{
watch
:
{
color
(
val
)
{
value
(
val
)
{
this
.
color
=
val
;
}
},
methods
:
{
change
(
val
)
{
console
.
log
(
'
color
'
,
val
);
console
.
log
(
'
color
'
,
val
);
this
.
$emit
(
'
input
'
,
val
);
this
.
$emit
(
'
input
'
,
val
);
}
}
...
...
app/web/page/editor/component/DynamicForm/component/ColumnSelector/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"column-selector"
>
<Tooltip
placement=
"top"
content=
"通栏"
>
<Button
type=
"ghost"
icon=
"minus-round"
@
click=
"select(1)"
></Button>
</Tooltip>
<Tooltip
placement=
"top"
content=
"两列"
>
<Button
type=
"ghost"
icon=
"ios-pause"
@
click=
"select(2)"
></Button>
</Tooltip>
<Tooltip
placement=
"top"
content=
"三列"
>
<Button
type=
"ghost"
icon=
"navicon-round"
@
click=
"select(3)"
></Button>
</Tooltip>
</div>
</
template
>
<
script
>
export
default
{
props
:
{
value
:
Number
,
},
data
()
{
return
{
column
:
this
.
value
,
}
},
watch
:
{
value
(
val
)
{
this
.
color
=
val
;
}
},
methods
:
{
select
(
column
)
{
console
.
log
(
'
column-selector
'
,
column
);
this
.
$emit
(
'
input
'
,
column
);
}
}
}
</
script
>
<
style
lang=
"less"
>
</
style
>
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/ComponentSelect/index.ts
0 → 100644
View file @
e79407ce
import
{
Component
,
Mixins
,
Prop
,
Watch
,
Vue
}
from
'
vue-property-decorator
'
;
import
{
Getter
,
State
}
from
'
vuex-class
'
;
import
EventBus
from
'
@/service/eventBus.service
'
;
@
Component
({
components
:
{},
name
:
'
ComponentSelect
'
})
export
default
class
DynamicForm
extends
Vue
{
@
State
(
state
=>
state
.
editor
.
curEleIndex
)
curEleIndex
;
@
Getter
(
'
pageData
'
)
pageData
;
@
Prop
([
String
,
Number
])
value
;
selected
:
string
=
this
.
value
;
list
:
object
[]
=
[];
@
Watch
(
'
selected
'
,
{
immediate
:
true
})
onSelectedChange
(
val
)
{
this
.
$emit
(
'
input
'
,
val
);
}
@
Watch
(
'
curEleIndex
'
,
{
immediate
:
true
})
onCurEleIndexChange
(
val
)
{
this
.
updateOptions
(
val
);
}
mounted
()
{
EventBus
.
$on
(
'
component-moved
'
,
()
=>
{
this
.
updateOptions
();
});
}
updateOptions
(
val
=
this
.
curEleIndex
)
{
if
(
val
||
val
===
0
)
{
const
pointY
=
this
.
pageData
?.
elements
[
val
]?.
point
?.
y
;
this
.
list
=
this
.
pageData
?.
elements
?.
filter
(
v
=>
pointY
<
v
?.
point
?.
y
)?.
map
((
element
,
index
)
=>
({
id
:
element
.
id
,
label
:
element
.
title
+
'
-
'
+
element
.
id
}));
console
.
log
(
'
curEleIndex
'
,
pointY
,
this
.
pageData
?.
elements
?.
filter
(
v
=>
pointY
<
v
?.
point
?.
y
),
this
.
list
);
}
}
}
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/ComponentSelect/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"select"
>
<Select
v-model=
"selected"
>
<Option
v-for=
"item in list"
:value=
"item.id"
:key=
"item.id"
>
{{
item
.
label
}}
</Option>
</Select>
</div>
</
template
>
<
script
lang=
"ts"
src=
"./index.ts"
></
script
>
<
style
lang=
"less"
>
.color-selector {
display: flex;
align-items: center;
justify-content: space-between;
&-input {
flex-basis: 150px;
}
}
</
style
>
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/CouponTableModal/columns/coupon.column.ts
0 → 100644
View file @
e79407ce
const
couponTypeList
:
object
[]
=
[
{
id
:
1
,
name
:
'
满减券
'
,
},
{
id
:
2
,
name
:
'
运费券
'
,
},
];
const
receiverTypeList
:
object
[]
=
[
{
id
:
1
,
name
:
'
主动领取
'
,
},
{
id
:
2
,
name
:
'
自动发放
'
,
},
{
id
:
3
,
name
:
'
不限
'
,
},
];
const
listStatus
:
object
[]
=
[
{
id
:
'
WAIT_ON_LINE
'
,
name
:
'
待发布
'
,
},
{
id
:
'
ON_LINE
'
,
name
:
'
已上架
'
,
},
{
id
:
'
OFF_LINE
'
,
name
:
'
已下架
'
,
},
];
const
statusList
:
object
[]
=
[
{
id
:
1
,
name
:
'
待发布
'
,
},
{
id
:
2
,
name
:
'
已上架
'
,
},
{
id
:
3
,
name
:
'
已下架
'
,
},
{
id
:
4
,
name
:
'
已过期
'
,
},
];
const
columns
:
object
[]
=
[
{
type
:
'
selection
'
,
width
:
60
,
hideSearch
:
true
},
{
title
:
'
批次id
'
,
key
:
'
id
'
,
hideSearch
:
true
},
{
title
:
'
批次id
'
,
hideTable
:
true
,
key
:
'
couponId
'
,
formType
:
'
input
'
},
{
title
:
'
优惠券名称
'
,
key
:
'
name
'
,
hideSearch
:
true
},
{
title
:
'
优惠券类型
'
,
key
:
'
couponType
'
,
formType
:
'
select
'
,
valueEnum
:
couponTypeList
.
reduce
((
pre
,
cur
)
=>
{
pre
[
cur
.
id
]
=
cur
.
name
;
return
pre
;
},
{}),
render
:
(
h
,
params
)
=>
{
const
obj
=
couponTypeList
.
find
(
item
=>
item
.
id
===
params
.
row
.
couponType
)
||
{};
return
h
(
'
div
'
,
obj
.
name
);
},
},
{
title
:
'
优惠券面值
'
,
key
:
'
couponAmt
'
,
hideSearch
:
true
,
},
{
title
:
'
优惠券属性
'
,
key
:
''
,
hideSearch
:
true
,
render
:
(
h
,
params
)
=>
{
const
obj
=
params
.
row
.
couponType
===
1
?
`满
${
params
.
row
.
limitAmt
}
减
${
params
.
row
.
couponAmt
}
元`
:
`满
${
params
.
row
.
limitAmt
}
可用`
;
return
h
(
'
div
'
,
obj
);
},
},
{
title
:
'
发行数量
'
,
key
:
'
pushCount
'
,
hideSearch
:
true
,
},
{
title
:
'
发行有效期
'
,
key
:
'
receiverTime
'
,
hideSearch
:
true
},
{
title
:
'
使用有效期
'
,
key
:
'
useTime
'
,
hideSearch
:
true
},
{
title
:
'
领取方式
'
,
key
:
'
receiverType
'
,
hideSearch
:
true
,
render
:
(
h
,
params
)
=>
{
const
obj
=
receiverTypeList
.
find
(
item
=>
item
.
id
===
params
.
row
.
receiverType
)
||
{};
return
h
(
'
div
'
,
obj
.
name
);
},
},
{
title
:
'
状态
'
,
key
:
'
status
'
,
hideSearch
:
true
,
render
:
(
h
,
params
)
=>
{
const
obj
=
listStatus
.
find
(
item
=>
item
.
id
===
params
.
row
.
status
)
||
{};
return
h
(
'
div
'
,
obj
.
name
);
}
},
{
title
:
'
状态
'
,
key
:
'
status
'
,
formType
:
'
select
'
,
hideTable
:
true
,
valueEnum
:
statusList
.
reduce
((
pre
,
cur
)
=>
{
pre
[
cur
.
id
]
=
cur
.
name
;
return
pre
;
},
{}),
}
];
export
default
columns
;
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/CouponTableModal/index.ts
0 → 100644
View file @
e79407ce
import
{
Component
,
Prop
,
Watch
,
Vue
}
from
'
vue-property-decorator
'
;
import
TableModal
from
'
../TableModal/index.vue
'
;
import
couponColumn
from
'
./columns/coupon.column
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
operationApi
from
'
@api/operation.api
'
;
@
Component
({
components
:
{
TableModal
},
name
:
'
CouponTableModal
'
})
export
default
class
CouponTableModal
extends
Vue
{
@
Prop
({
default
:
()
=>
([]),
type
:
Array
})
value
;
@
Prop
({
default
:
()
=>
([]),
type
:
Array
})
formControl
;
goods
:
object
=
cloneDeep
(
this
.
value
);
table
:
object
[]
=
[
{
title
:
'
选择优惠券
'
,
type
:
'
coupon
'
,
multiple
:
true
,
columns
:
couponColumn
,
query
:
this
.
query
}
];
@
Watch
(
'
goods
'
)
onFormChange
(
newVal
)
{
this
.
$emit
(
'
input
'
,
newVal
);
}
async
query
(
data
)
{
const
res
=
await
operationApi
.
couponList
(
data
);
const
couponInfoList
=
res
?.
couponInfoList
?.
map
(
item
=>
{
item
.
receiverTime
=
`
${
item
.
receiverStartTime
.
slice
(
0
,
10
)}
--
${
item
.
receiverEndTime
.
slice
(
0
,
10
)}
`
;
item
.
useTime
=
item
.
useTimeStart
?
`
${
item
.
useTimeStart
}
-
${
item
.
useTimeEnd
}
`
:
`自领取
${
item
.
receiverDaysValid
}
天后生效,有效天数
${
item
.
validDays
}
天`
;
return
item
;
});
return
{
data
:
couponInfoList
||
[],
total
:
res
?.
pageInfo
?.
totalCount
};
}
}
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/CouponTableModal/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<table-modal
:table=
"table"
:formControl=
"formControl"
v-model=
"goods"
title=
"优惠券"
></table-modal>
</
template
>
<
script
lang=
"ts"
src=
"./index.ts"
></
script
>
<
style
></
style
>
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/FormList/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"form-list"
>
<Card
class=
"form-list-card"
:key=
"index"
v-for=
"(item, index) in list"
>
<div
slot=
'title'
class=
"Fl-card-title"
>
<h4>
项目
{{
index
+
1
}}
</h4>
<a
@
click=
"del(index)"
>
删除
</a>
</div>
<Form
:model=
"item"
:label-width=
"80"
>
<FormItem
:prop=
"`$
{keywords.key}`" :label="keywords.name" :key="idx" v-for="(keywords, idx) in formControl">
<component
:is=
"getComponent(keywords.type)"
:options=
"item.options"
v-model=
"item[keywords.key]"
/>
</FormItem>
</Form>
</Card>
<div
class=
"form-list-button"
>
<Button
type=
"dashed"
icon=
"plus-round"
@
click=
"add"
>
添加项目
</Button>
</div>
</div>
</
template
>
<
script
>
import
ComponentSelect
from
'
../ComponentSelect/index.vue
'
;
import
Upload
from
'
../Upload/index.vue
'
;
export
default
{
components
:
{
ComponentSelect
,
Upload
},
props
:
{
value
:
{
type
:
Array
,
default
:
()
=>
[]
},
formControl
:
{
type
:
Array
,
default
:
()
=>
[]
},
name
:
String
},
data
()
{
return
{
list
:
this
.
value
,
}
},
watch
:
{
list
(
val
)
{
this
.
$emit
(
'
input
'
,
val
);
},
value
(
val
)
{
this
.
list
=
val
;
}
},
methods
:
{
getComponent
(
type
)
{
let
result
=
type
;
switch
(
type
)
{
case
'
text
'
:
result
=
'
Input
'
;
break
;
case
'
select
'
:
result
=
'
BaseSelect
'
;
break
;
case
'
checkbox
'
:
result
=
'
Checkbox
'
;
break
;
case
'
textarea
'
:
result
=
'
Textarea
'
;
break
;
case
'
number
'
:
result
=
'
Number
'
;
break
;
}
return
result
;
},
add
()
{
const
object
=
this
.
formControl
.
reduce
((
pre
,
cur
)
=>
{
pre
[
cur
.
key
]
=
''
;
return
pre
;
},
{})
this
.
list
.
push
(
object
);
},
del
(
index
)
{
this
.
list
.
splice
(
index
,
1
);
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.form-list {
/deep/ .ivu-card {
margin-bottom: 16px;
.ivu-form {
.ivu-form-item-label {
text-align: left;
}
}
}
h3 {
padding-bottom: 10px;
text-align: center;
}
&-card {
/deep/ .ivu-card-head{
background: #f0f2f5;
}
.Fl-card-title {
display: flex;
justify-content: space-between;
}
}
&-button {
margin-top: 20px;
text-align: center;
}
}
</
style
>
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/GoodsTableModal/columns/goods.column.ts
0 → 100644
View file @
e79407ce
const
commodityChannel
:
object
[]
=
[
{
id
:
1
,
name
:
'
自营
'
,
},
{
id
:
2
,
name
:
'
京东开普勒
'
,
},
{
id
:
3
,
name
:
'
京东联盟
'
,
},
{
id
:
4
,
name
:
'
众联
'
,
},
{
id
:
5
,
name
:
'
企业购
'
,
},
];
const
goodsStatus
:
object
[]
=
[
{
id
:
1
,
name
:
'
未上架
'
,
},
{
id
:
2
,
name
:
'
审核中
'
,
},
{
id
:
3
,
name
:
'
已上架
'
,
},
{
id
:
4
,
name
:
'
我方下架
'
,
},
{
id
:
5
,
name
:
'
三方下架
'
,
},
];
const
columns
=
function
()
{
return
[
{
type
:
'
selection
'
,
width
:
60
,
hideSearch
:
true
},
{
title
:
'
商品ID
'
,
key
:
'
id
'
,
formType
:
'
input
'
},
{
title
:
'
商品图片
'
,
key
:
'
imageUrl
'
,
width
:
130
,
hideSearch
:
true
,
render
:
(
h
,
params
)
=>
{
return
h
(
'
img
'
,
{
attrs
:
{
src
:
params
.
row
.
imageUrl
,
width
:
50
,
height
:
50
}
});
}
},
{
title
:
'
商品名称
'
,
key
:
'
skuName
'
,
width
:
155
,
hideSearch
:
true
},
{
title
:
'
商品渠道
'
,
key
:
'
skuSource
'
,
hideSearch
:
true
,
render
:
(
h
,
params
)
=>
{
const
obj
=
commodityChannel
.
find
(
item
=>
item
.
id
===
params
.
row
.
skuSource
)
||
{};
return
h
(
'
div
'
,
obj
.
name
);
},
},
{
title
:
'
销售价格
'
,
key
:
'
salePrice
'
,
hideSearch
:
true
},
{
title
:
'
划线价格
'
,
key
:
'
marketPrice
'
,
hideSearch
:
true
},
{
title
:
'
发布状态
'
,
key
:
'
status
'
,
formType
:
'
select
'
,
valueEnum
:
goodsStatus
.
reduce
((
pre
,
cur
)
=>
{
pre
[
cur
.
id
]
=
cur
.
name
;
return
pre
;
},
{}),
render
:
(
h
,
params
)
=>
{
const
obj
=
goodsStatus
.
find
(
item
=>
item
.
id
===
params
.
row
.
status
)
||
{};
return
h
(
'
div
'
,
obj
.
name
);
},
},
{
title
:
'
创建时间
'
,
key
:
'
createdAt
'
,
hideSearch
:
true
},
{
title
:
'
发布时间
'
,
key
:
'
pushedAt
'
,
hideSearch
:
true
},
{
title
:
'
下架时间
'
,
key
:
'
offlineAt
'
,
hideSearch
:
true
},
{
title
:
'
标签
'
,
hideSearch
:
true
,
render
:
(
h
,
params
)
=>
{
const
labelName
=
[];
if
(
params
.
row
.
labelList
)
{
params
.
row
.
labelList
.
forEach
(
e
=>
{
labelName
.
push
(
e
.
labelName
);
});
}
return
h
(
'
div
'
,
labelName
.
join
(
'
,
'
));
},
},
{
title
:
'
商品类目
'
,
key
:
'
cid1
'
,
formType
:
'
treeSelect
'
,
hideTable
:
true
,
valueEnum
:
this
.
getCategory
},
];
};
export
default
columns
;
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/GoodsTableModal/columns/goodsGroup.column.ts
0 → 100644
View file @
e79407ce
const
groupColumns
=
function
()
{
return
[
{
type
:
'
selection
'
,
width
:
60
,
hideSearch
:
true
},
{
title
:
'
专题ID
'
,
key
:
'
id
'
,
formType
:
'
input
'
},
{
title
:
'
专题名称
'
,
key
:
'
name
'
,
formType
:
'
input
'
},
{
title
:
'
有效期
'
,
key
:
'
validityTime
'
,
hideSearch
:
true
,
render
:
(
h
,
params
)
=>
{
const
time
=
`
${
params
.
row
.
startTime
}
至
${
params
.
row
.
endTime
}
`
;
return
h
(
'
div
'
,
time
);
},
},
{
title
:
'
标签
'
,
key
:
'
labelName
'
,
hideSearch
:
true
,
render
:
(
h
,
params
)
=>
{
const
labelName
=
[];
params
.
row
?.
listLabel
?.
forEach
(
e
=>
{
labelName
.
push
(
e
.
labelName
);
});
return
h
(
'
div
'
,
labelName
.
join
(
'
,
'
));
},
},
{
title
:
'
创建时间
'
,
key
:
'
createdAt
'
,
hideSearch
:
true
,
}
];
};
export
default
groupColumns
;
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/GoodsTableModal/index.ts
0 → 100644
View file @
e79407ce
import
{
Component
,
Prop
,
Watch
,
Vue
}
from
'
vue-property-decorator
'
;
import
TableModal
from
'
../TableModal/index.vue
'
;
import
goodsColumn
from
'
./columns/goods.column
'
;
import
goodsGroupColumn
from
'
./columns/goodsGroup.column
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
operationApi
from
'
@api/operation.api
'
;
@
Component
({
components
:
{
TableModal
},
name
:
'
GoodsTableModal
'
})
export
default
class
GoodsTableModal
extends
Vue
{
@
Prop
({
default
:
()
=>
({
type
:
'
goods
'
,
ids
:
[]
}),
type
:
Object
})
value
;
@
Prop
({
default
:
()
=>
([]),
type
:
Array
})
formControl
;
goods
:
object
=
cloneDeep
(
this
.
value
);
table
:
object
[]
=
[
{
title
:
'
选择商品
'
,
type
:
'
goods
'
,
multiple
:
true
,
columns
:
goodsColumn
.
call
(
this
),
query
:
this
.
query
},
{
title
:
'
选择商品组
'
,
type
:
'
goodsGroup
'
,
multiple
:
false
,
columns
:
goodsGroupColumn
.
call
(
this
),
query
:
this
.
queryGroup
}
];
@
Watch
(
'
goods
'
)
onFormChange
(
newVal
)
{
this
.
$emit
(
'
input
'
,
newVal
);
}
async
query
(
data
)
{
const
{
records
,
total
}
=
await
operationApi
.
skuInfo
({
type
:
'
list
'
,
...
data
});
records
.
forEach
(
record
=>
{
if
(
this
.
goods
.
ids
.
some
(
v
=>
v
===
record
.
id
))
{
record
.
_checked
=
true
;
}
});
return
{
data
:
records
||
[],
total
};
},
async
getCategory
()
{
function
recursionData
(
data
)
{
const
list
=
[];
data
.
forEach
(
item
=>
{
const
{
categoryId
:
id
,
categoryName
:
label
,
categoryLevel
:
level
,
children
}
=
item
;
const
itemData
=
{
id
,
label
,
level
};
if
(
item
.
children
&&
item
.
children
.
length
)
{
itemData
.
children
=
recursionData
(
children
);
}
list
.
push
(
itemData
);
});
return
list
;
}
const
res
=
await
operationApi
.
categoryQuery
();
return
recursionData
(
res
.
level1List
||
[]);
},
async
queryGroup
(
data
)
{
const
{
records
,
total
}
=
await
operationApi
.
specialPage
(
data
);
records
.
forEach
(
record
=>
{
if
(
this
.
goods
.
ids
.
some
(
v
=>
v
===
record
.
id
))
{
record
.
_checked
=
true
;
}
});
return
{
data
:
records
||
[],
total
};
}
}
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/GoodsTableModal/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<table-modal
:table=
"table"
:formControl=
"formControl"
v-model=
"goods"
title=
"商品"
></table-modal>
</
template
>
<
script
lang=
"ts"
src=
"./index.ts"
></
script
>
<
style
></
style
>
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/TableModal/index.ts
0 → 100644
View file @
e79407ce
import
{
Component
,
Prop
,
Watch
,
Vue
,
Mixins
}
from
'
vue-property-decorator
'
;
import
{
Getter
,
State
}
from
'
vuex-class
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
Number
from
'
../Number/index.vue
'
;
import
QGTable
from
'
@editor/component/QgTable/index.vue
'
;
import
{
validateType
}
from
'
@/service/utils.service
'
;
import
operationApi
from
'
@api/operation.api
'
;
import
DynamicFormMixin
from
'
../mixins/dynamicForm.mixin
'
;
@
Component
({
components
:
{
Number
,
QGTable
},
name
:
'
ComponentSelect
'
})
export
default
class
DynamicForm
extends
Mixins
(
DynamicFormMixin
)
{
@
State
(
state
=>
state
.
editor
.
curEleIndex
)
curEleIndex
;
@
Getter
(
'
pageData
'
)
pageData
;
@
Prop
({
default
:
()
=>
([]),
type
:
Array
})
formControl
;
@
Prop
({
default
:
()
=>
([]),
type
:
Array
})
table
;
@
Prop
([
Object
,
Array
])
value
;
@
Prop
(
String
)
title
;
form
:
object
=
{};
modal
:
boolean
=
false
;
selections
:
object
[]
=
[];
activeName
:
number
=
0
;
get
idsLength
()
{
if
(
validateType
(
this
.
value
)
===
'
object
'
)
{
return
this
.
value
?.
ids
?.
length
;
}
return
this
.
value
?.
length
;
}
@
Watch
(
'
curEleIndex
'
,
{
immediate
:
true
})
onElementChange
(
newVal
)
{
this
.
formControl
.
forEach
(
schame
=>
{
this
.
$set
(
this
.
form
,
schame
.
key
,
this
.
pageData
.
elements
[
this
.
curEleIndex
].
props
[
schame
.
key
]);
});
}
@
Watch
(
'
form
'
,
{
immediate
:
true
,
deep
:
true
})
onFormChange
(
newVal
)
{
console
.
log
(
'
onFormChange
'
,
newVal
);
let
parent
=
this
.
$parent
;
while
(
!
parent
.
modProps
)
{
parent
=
parent
.
$parent
;
}
parent
.
modProps
(
this
.
form
,
'
component
'
);
}
add
()
{
this
.
modal
=
true
;
}
selectionChange
(
selection
)
{
if
(
!
this
.
table
[
this
.
activeName
]?.
multiple
&&
selection
.
length
>
1
)
{
return
this
.
$Notice
.
warning
({
title
:
'
商品组只能单选
'
});
}
this
.
selections
=
selection
;
}
ok
()
{
if
(
this
.
table
.
length
>
1
)
{
this
.
$emit
(
'
input
'
,
{
type
:
this
.
table
[
this
.
activeName
].
type
,
ids
:
this
.
selections
.
map
(
v
=>
v
.
id
)
});
}
else
{
this
.
$emit
(
'
input
'
,
this
.
selections
.
map
(
v
=>
v
.
id
));
}
}
cancel
()
{
this
.
selections
=
[];
}
menuChange
(
name
)
{
this
.
activeName
=
name
;
this
.
selections
=
[];
}
editText
(
type
)
{
let
rs
=
''
;
switch
(
type
)
{
case
'
edit
'
:
rs
=
`编辑
${
this
.
title
}
`
;
break
;
case
'
add
'
:
rs
=
`添加
${
this
.
title
}
`
;
break
;
case
'
choose
'
:
rs
=
`选择
${
this
.
title
}
`
;
break
;
}
return
rs
;
}
}
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/TableModal/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"table-modal"
>
<Button
v-if=
"!idsLength"
type=
"dashed"
icon=
"plus-round"
@
click=
"add"
>
{{
editText
(
'
add
'
)
}}
</Button>
<Card
v-else
class=
"table-modal-card"
>
<div
slot=
'title'
class=
"Fl-card-title"
>
<a
slot=
'title'
@
click=
"add()"
>
{{
editText
(
'
edit
'
)
}}
</a>
</div>
<Form
:model=
"form"
:label-width=
"80"
>
<FormItem
:prop=
"`$
{keywords.key}`" :label="keywords.name" :key="idx" v-for="(keywords, idx) in formControl">
<component
:is=
"getComponent(keywords.type)"
:options=
"keywords.options"
v-model=
"form[keywords.key]"
/>
</FormItem>
</Form>
</Card>
<Modal
:width=
"1150"
v-model=
"modal"
@
on-ok=
"ok"
@
on-cancel=
"cancel"
class=
"table-modal-popup"
:title=
"editText('choose')"
>
<div
class=
"Tm-popup-body"
v-if=
"modal"
>
<Menu
v-if=
"table.length > 1"
width=
"90px"
:active-name=
"activeName"
@
on-select=
"menuChange"
>
<MenuItem
:name=
"index"
:key=
"index"
v-for=
"(item, index) in table"
>
<span>
{{
item
.
title
}}
</span>
</MenuItem>
</Menu>
<div
class=
"Tmp-body-content"
>
<template
v-for=
"(item, index) in table"
>
<div
v-show=
"activeName === index"
>
<QGTable
ref=
"qgTable"
:columns=
"item.columns"
:request=
"item.query"
:hideAdd=
"true"
:height=
"500"
@
on-selection-change=
"selectionChange"
>
</QGTable>
</div>
</
template
>
</div>
</div>
</Modal>
</div>
</template>
<
script
lang=
"ts"
src=
"./index.ts"
></
script
>
<
style
lang=
"less"
scoped
>
.table-modal {
&-card {
/deep/ .ivu-card-head{
background: #f0f2f5;
}
/deep/ .ivu-form {
.ivu-form-item-label {
width: 100px !important;
text-align: left;
}
}
.Fl-card-title {
text-align: right;
}
}
&-popup {
/deep/ .tableComStyle {
min-height: 0;
// .tableGroupStyle {
// height: 500px;
// overflow: scroll;
// }
}
.Tm-popup-body {
display: flex;
.Tmp-body-content {
flex: 1;
}
/deep/ .ivu-menu-item {
text-align: center;
padding: 10px 0;
}
}
}
}
</
style
>
\ No newline at end of file
app/web/page/editor/component/DynamicForm/component/Upload/index.vue
View file @
e79407ce
...
@@ -72,6 +72,7 @@
...
@@ -72,6 +72,7 @@
.upload {
.upload {
display: flex;
display: flex;
align-items: center;
align-items: center;
width: 100%;
&-img {
&-img {
display: inline-block;
display: inline-block;
width: 60px;
width: 60px;
...
...
app/web/page/editor/component/DynamicForm/component/mixins/dynamicForm.mixin.ts
0 → 100644
View file @
e79407ce
import
{
Component
,
Vue
}
from
'
vue-property-decorator
'
;
@
Component
({
name
:
'
dynamicFormMixin
'
})
export
default
class
DynamicFormMixin
extends
Vue
{
getComponent
(
type
)
{
let
result
=
type
;
switch
(
type
)
{
case
'
text
'
:
result
=
'
Input
'
;
break
;
case
'
select
'
:
result
=
'
BaseSelect
'
;
break
;
case
'
checkbox
'
:
result
=
'
Checkbox
'
;
break
;
case
'
textarea
'
:
result
=
'
Textarea
'
;
break
;
case
'
number
'
:
result
=
'
Number
'
;
break
;
}
return
result
;
}
}
\ No newline at end of file
app/web/page/editor/component/DynamicForm/index.ts
View file @
e79407ce
import
{
Component
,
Mixins
,
Prop
,
Watch
}
from
'
vue-property-decorator
'
;
import
{
Component
,
Mixins
,
Prop
,
Watch
}
from
'
vue-property-decorator
'
;
import
{
Getter
,
State
}
from
'
vuex-class
'
;
import
{
Getter
,
State
}
from
'
vuex-class
'
;
import
{
reduce
,
ceil
,
subtract
,
divide
}
from
'
lodash
'
;
import
{
reduce
,
ceil
,
subtract
,
divide
,
pick
,
cloneDeep
,
pickBy
}
from
'
lodash
'
;
import
{
ContextMenu
}
from
'
@editor/mixins/contextMenu.mixin
'
;
import
ContextMenuMixin
from
'
@editor/mixins/contextMenu.mixin
'
;
import
DynamicFormMixin
from
'
./component/mixins/dynamicForm.mixin
'
;
import
Upload
from
'
./component/Upload/index.vue
'
;
import
Upload
from
'
./component/Upload/index.vue
'
;
import
ColorSelector
from
'
./component/ColorSelector/index.vue
'
;
import
ColorSelector
from
'
./component/ColorSelector/index.vue
'
;
import
BaseSelect
from
'
./component/BaseSelect/index.vue
'
;
import
BaseSelect
from
'
./component/BaseSelect/index.vue
'
;
import
ComponentSelect
from
'
./component/ComponentSelect/index.vue
'
;
import
FormList
from
'
./component/FormList/index.vue
'
;
import
GoodsTableModal
from
'
./component/GoodsTableModal/index.vue
'
;
import
CouponTableModal
from
'
./component/CouponTableModal/index.vue
'
;
import
Textarea
from
'
./component/Textarea/index.vue
'
;
import
Textarea
from
'
./component/Textarea/index.vue
'
;
import
Number
from
'
./component/Number/index.vue
'
;
import
Number
from
'
./component/Number/index.vue
'
;
import
ColumnSelector
from
'
./component/ColumnSelector/index.vue
'
;
import
{
resizeDiv
,
getStyle
}
from
'
@/service/utils.service
'
;
import
{
resizeDiv
,
getStyle
}
from
'
@/service/utils.service
'
;
@
Component
({
components
:
{
Upload
,
ColorSelector
,
BaseSelect
,
Textarea
,
Numbe
r
},
name
:
'
DynamicForm
'
})
@
Component
({
components
:
{
Upload
,
ColorSelector
,
BaseSelect
,
FormList
,
Textarea
,
Number
,
ComponentSelect
,
GoodsTableModal
,
CouponTableModal
,
ColumnSelecto
r
},
name
:
'
DynamicForm
'
})
export
default
class
DynamicForm
extends
Mixins
(
ContextMenu
)
{
export
default
class
DynamicForm
extends
Mixins
(
ContextMenu
Mixin
,
DynamicFormMixin
)
{
@
State
(
state
=>
state
.
editor
.
curEleIndex
)
curEleIndex
;
@
State
(
state
=>
state
.
editor
.
curEleIndex
)
curEleIndex
;
@
State
(
state
=>
state
.
editor
.
curChildIndex
)
curChildIndex
;
@
State
(
state
=>
state
.
editor
.
curChildIndex
)
curChildIndex
;
@
Getter
(
'
pageData
'
)
pageData
;
@
Getter
(
'
pageData
'
)
pageData
;
...
@@ -26,43 +32,112 @@ export default class DynamicForm extends Mixins(ContextMenu) {
...
@@ -26,43 +32,112 @@ export default class DynamicForm extends Mixins(ContextMenu) {
element
=
this
.
pageData
.
elements
[
this
.
curEleIndex
];
element
=
this
.
pageData
.
elements
[
this
.
curEleIndex
];
}
}
}
}
console
.
log
(
'
curElement
'
,
element
);
return
element
;
return
element
;
}
}
get
point
()
{
get
point
()
{
return
this
.
curEleIndex
||
this
.
curEleIndex
===
0
?
this
.
pageData
.
elements
[
this
.
curEleIndex
]?.
point
:
{
h
:
0
,
w
:
0
};
return
this
.
curEleIndex
||
this
.
curEleIndex
===
0
?
cloneDeep
(
this
.
pageData
.
elements
[
this
.
curEleIndex
]?.
point
)
:
{
h
:
0
,
w
:
0
};
}
}
get
commonStyle
()
{
get
commonStyle
()
{
return
(
this
.
curEleIndex
||
this
.
curEleIndex
===
0
)
&&
(
this
.
curChildIndex
||
this
.
curChildIndex
===
0
)
?
this
.
pageData
.
elements
[
this
.
curEleIndex
].
child
[
this
.
curChildIndex
].
commonStyle
:
{
h
:
0
,
w
:
0
};
let
rs
=
{
backgroundColor
:
''
,
backgroundImage
:
''
};
if
(
this
.
curEleIndex
||
this
.
curEleIndex
===
0
)
{
rs
=
cloneDeep
({
...
rs
,
...
this
.
pageData
.
elements
[
this
.
curEleIndex
].
commonStyle
});
if
(
this
.
curChildIndex
||
this
.
curChildIndex
===
0
)
{
rs
=
cloneDeep
({
...
rs
,
...
this
.
pageData
.
elements
[
this
.
curEleIndex
].
child
[
this
.
curChildIndex
].
commonStyle
});
}
}
// console.log('commonStyle', rs);
return
rs
;
}
get
hasGroup
()
{
return
this
.
curElement
?.
schame
?.
some
(
v
=>
v
.
title
);
}
get
curFormKey
()
{
const
keys
=
[];
this
.
curElement
.
schame
?.
forEach
(
schame
=>
{
if
(
schame
.
children
)
{
schame
.
children
.
forEach
(
child
=>
{
keys
.
push
(
child
.
key
);
});
}
else
{
keys
.
push
(
schame
.
key
);
}
});
return
keys
;
}
}
get
eleName
()
{
let
result
=
''
;
if
(
!
this
.
curChildIndex
&&
this
.
curChildIndex
!==
0
)
{
result
=
this
.
pageData
?.
elements
[
this
.
curEleIndex
]?.
name
??
''
;
}
return
result
;
}
// 监听curElement变化, 更新form
@
Watch
(
'
curElement
'
,
{
immediate
:
true
,
deep
:
true
})
@
Watch
(
'
curElement
'
,
{
immediate
:
true
,
deep
:
true
})
onElementChange
(
newVal
)
{
onElementChange
(
newVal
)
{
// curEleIndex选中时commonStyle为空, curChildIndex选中时commonStyle有值且不可设置背景
newVal
?.
schame
?.
forEach
(
schame
=>
{
newVal
?.
schame
?.
forEach
(
schame
=>
{
this
.
$set
(
this
.
form
,
schame
.
key
,
newVal
.
props
[
schame
.
key
]);
if
(
schame
.
children
)
{
schame
.
children
.
forEach
(
child
=>
{
this
.
$set
(
this
.
form
,
child
.
key
,
newVal
.
props
[
child
.
key
]);
});
}
else
{
this
.
$set
(
this
.
form
,
schame
.
key
,
newVal
.
props
[
schame
.
key
]);
}
});
});
console
.
log
(
'
curElement
'
,
newVal
,
this
.
form
);
}
}
// 监听form变化, 更新pageData
@
Watch
(
'
form
'
,
{
immediate
:
true
,
deep
:
true
})
@
Watch
(
'
form
'
,
{
immediate
:
true
,
deep
:
true
})
onFormChange
(
newVal
)
{
onFormChange
(
newVal
)
{
this
.
$emit
(
'
modProps
'
,
this
.
form
);
if
(
!
Object
.
keys
(
newVal
).
length
)
{
return
;
}
const
params
=
pick
(
this
.
form
,
this
.
curFormKey
);
console
.
log
(
'
form
'
,
newVal
,
params
);
this
.
$nextTick
(()
=>
this
.
adjustHeight
());
this
.
$emit
(
'
modProps
'
,
params
,
'
component
'
);
}
}
get
eleName
()
{
updatePoint
(
value
,
key
)
{
let
result
=
''
;
// console.log('updatePoint', this.point);
if
(
!
this
.
curChildIndex
&&
this
.
curChildIndex
!==
0
)
{
const
elements
=
this
.
pageData
.
elements
[
this
.
curEleIndex
];
result
=
this
.
pageData
?.
elements
[
this
.
curEleIndex
]?.
name
??
''
;
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
data
:
{
...
elements
,
point
:
{
...
elements
.
point
,
...
this
.
point
}
}
});
}
updateStyle
(
value
,
key
)
{
console
.
log
(
'
updateCommonStyle
'
,
this
.
commonStyle
);
const
elements
=
this
.
pageData
.
elements
[
this
.
curEleIndex
];
// this.updatePageInfo({ containerIndex: this.curEleIndex, data: { ...elements, commonStyle: { ...elements.commonStyle, ...this.commonStyle } } });
this
.
updateCommonStyle
({
containerIndex
:
this
.
curEleIndex
,
childIndex
:
this
.
curChildIndex
,
data
:
this
.
commonStyle
});
}
getDataFromProps
()
{
if
(
this
.
curEleIndex
||
this
.
curEleIndex
===
0
)
{
this
.
point
=
this
.
pageData
.
elements
[
this
.
curEleIndex
]?.
point
||
this
.
point
;
this
.
commonStyle
=
Object
.
assign
({},
initialCommonStyle
,
this
.
pageData
.
elements
[
this
.
curEleIndex
].
commonStyle
);
if
(
this
.
curChildIndex
||
this
.
curChildIndex
===
0
)
{
this
.
commonStyle
=
Object
.
assign
({},
this
.
pageData
.
elements
[
this
.
curEleIndex
].
child
[
this
.
curChildIndex
].
commonStyle
);
}
}
}
return
result
;
}
}
resizedEvent
(
h
,
w
,
responsive
)
{
resizedEvent
(
h
,
w
,
responsive
)
{
const
elements
=
this
.
pageData
.
elements
[
this
.
curEleIndex
];
const
elements
=
this
.
pageData
.
elements
[
this
.
curEleIndex
];
if
(
responsive
)
{
if
(
responsive
)
{
resizeDiv
(
this
.
form
.
backgroundImage
,
667
,
375
,
(
imgHeight
)
=>
{
if
(
this
.
form
.
backgroundImage
)
{
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
data
:
{
...
elements
,
point
:
{
...
elements
.
point
,
w
:
w
??
elements
.
point
.
w
,
h
:
imgHeight
??
elements
.
point
.
h
,
responsive
:
true
}
}
});
resizeDiv
(
this
.
form
.
backgroundImage
,
667
,
375
,
(
imgHeight
)
=>
{
});
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
data
:
{
...
elements
,
point
:
{
...
elements
.
point
,
w
:
w
??
elements
.
point
.
w
,
h
:
imgHeight
??
elements
.
point
.
h
,
responsive
:
true
}
}
});
});
}
else
if
(
elements
.
id
)
{
this
.
adjustHeight
();
}
}
else
{
}
else
{
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
data
:
{
...
elements
,
point
:
{
...
elements
.
point
,
w
:
w
??
elements
.
point
.
w
,
h
:
h
??
elements
.
point
.
h
}
}
});
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
data
:
{
...
elements
,
point
:
{
...
elements
.
point
,
w
:
w
??
elements
.
point
.
w
,
h
:
h
??
elements
.
point
.
h
}
}
});
}
}
...
@@ -97,32 +172,4 @@ export default class DynamicForm extends Mixins(ContextMenu) {
...
@@ -97,32 +172,4 @@ export default class DynamicForm extends Mixins(ContextMenu) {
}
}
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
childIndex
:
this
.
curChildIndex
,
data
:
{
...
elements
,
commonStyle
:
{
...
elements
.
commonStyle
,
left
,
top
}
}
});
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
childIndex
:
this
.
curChildIndex
,
data
:
{
...
elements
,
commonStyle
:
{
...
elements
.
commonStyle
,
left
,
top
}
}
});
}
}
getComponent
(
type
)
{
let
result
=
'
Input
'
;
switch
(
type
)
{
case
'
text
'
:
result
=
'
Input
'
;
break
;
case
'
select
'
:
result
=
'
BaseSelect
'
;
break
;
case
'
checkbox
'
:
result
=
'
Checkbox
'
;
break
;
case
'
ColorSelector
'
:
result
=
'
ColorSelector
'
;
break
;
case
'
textarea
'
:
result
=
'
Textarea
'
;
break
;
case
'
number
'
:
result
=
'
Number
'
;
break
;
case
'
Upload
'
:
result
=
'
Upload
'
;
break
;
}
return
result
;
}
}
}
\ No newline at end of file
app/web/page/editor/component/DynamicForm/index.vue
View file @
e79407ce
...
@@ -2,16 +2,26 @@
...
@@ -2,16 +2,26 @@
<div
class=
"dynamic-form"
>
<div
class=
"dynamic-form"
>
<h2>
{{
curElement
.
title
}}
</h2>
<h2>
{{
curElement
.
title
}}
</h2>
<template>
<template>
<h4>
组件属性
</h4>
<Form
class=
"dynamic-form-component"
:label-width=
"80"
:model=
"form"
>
<Form
class=
"dynamic-form-component"
:label-width=
"80"
:model=
"form"
>
<FormItem
:label=
"item.name"
:key=
"index"
v-for=
"(item, index) in curElement.schame"
>
<h3
v-if=
"!hasGroup"
>
组件属性
</h3>
<component
:is=
"getComponent(item.type)"
:options=
"item.options"
v-model=
"form[item.key]"
/>
<template
v-for=
"(item, index) in curElement.schame"
>
</FormItem>
<div
v-if=
"item.title"
>
<h3>
{{
item
.
title
}}
</h3>
<FormItem
:label=
"child.name"
:key=
"child.key"
v-for=
"child in item.children"
>
<component
:is=
"getComponent(child.type)"
:options=
"child.options"
:formControl=
"child.formControl"
v-model=
"form[child.key]"
/>
</FormItem>
</div>
<!--
<component
v-else-if=
"item.formControl"
:is=
"getComponent(item.type)"
:options=
"item.options"
:formControl=
"item.formControl"
:name=
"item.name"
v-model=
"form[item.key]"
/>
-->
<FormItem
class=
"Df-component-formitem"
v-else
:label=
"item.name"
>
<component
:is=
"getComponent(item.type)"
:options=
"item.options"
:formControl=
"item.formControl"
v-model=
"form[item.key]"
/>
</FormItem>
</
template
>
</Form>
</Form>
</template>
</template>
<
template
>
<
template
>
<
h4>
基础样式
</h4
>
<
!--
<h3>
基础样式
</h3>
--
>
<Form
class=
"dynamic-form-basic"
:label-width=
"80"
>
<Form
class=
"dynamic-form-basic"
:label-width=
"80"
>
<h3>
基础样式
</h3>
<template
v-if=
"curChildIndex || curChildIndex === 0"
>
<template
v-if=
"curChildIndex || curChildIndex === 0"
>
<FormItem
label=
"定位"
>
<FormItem
label=
"定位"
>
<Tooltip
placement=
"top"
content=
"上对齐"
>
<Tooltip
placement=
"top"
content=
"上对齐"
>
...
@@ -34,8 +44,8 @@
...
@@ -34,8 +44,8 @@
</Tooltip>
</Tooltip>
</FormItem>
</FormItem>
<FormItem
label=
"位置"
>
<FormItem
label=
"位置"
>
<InputNumber
class=
"Df-basic-inputnumber"
v-model=
"commonStyle.left"
></InputNumber>
<InputNumber
class=
"Df-basic-inputnumber"
v-model=
"commonStyle.left"
@
on-change=
"updateStyle($event, 'left')"
></InputNumber>
<InputNumber
v-model=
"commonStyle.top"
></InputNumber>
<InputNumber
v-model=
"commonStyle.top"
@
on-change=
"updateStyle($event, 'top')"
></InputNumber>
</FormItem>
</FormItem>
<FormItem
label=
"尺寸"
>
<FormItem
label=
"尺寸"
>
<Tooltip
placement=
"top"
content=
"全屏"
>
<Tooltip
placement=
"top"
content=
"全屏"
>
...
@@ -49,16 +59,16 @@
...
@@ -49,16 +59,16 @@
</Tooltip>
</Tooltip>
</FormItem>
</FormItem>
<FormItem
label=
"宽高"
>
<FormItem
label=
"宽高"
>
<InputNumber
class=
"Df-basic-inputnumber"
:max=
"375"
:min=
"0"
v-model=
"commonStyle.width"
></InputNumber>
<InputNumber
class=
"Df-basic-inputnumber"
:max=
"375"
:min=
"0"
v-model=
"commonStyle.width"
@
on-change=
"updateStyle($event, 'width')"
></InputNumber>
<InputNumber
:max=
"667"
:min=
"0"
v-model=
"commonStyle.height"
></InputNumber>
<InputNumber
:max=
"667"
:min=
"0"
v-model=
"commonStyle.height"
@
on-change=
"updateStyle($event, 'height')"
></InputNumber>
</FormItem>
</FormItem>
</
template
>
</
template
>
<
template
v-if=
"(curEleIndex || curEleIndex === 0) && !curChildIndex && curChildIndex !== 0"
>
<
template
v-if=
"(curEleIndex || curEleIndex === 0) && !curChildIndex && curChildIndex !== 0"
>
<FormItem
label=
"尺寸"
>
<FormItem
label=
"
容器
尺寸"
>
<Tooltip
placement=
"top"
content=
"全屏"
>
<Tooltip
placement=
"top"
content=
"全屏"
>
<Button
type=
"ghost"
icon=
"arrow-resize"
@
click=
"resizedEvent(667, 375)"
></Button>
<Button
type=
"ghost"
icon=
"arrow-resize"
@
click=
"resizedEvent(667, 375)"
></Button>
</Tooltip>
</Tooltip>
<Tooltip
placement=
"top"
content=
"根据背景图片自动调整宽高"
>
<Tooltip
placement=
"top"
content=
"根据背景图片
或组件
自动调整宽高"
>
<Button
type=
"ghost"
icon=
"image"
@
click=
"resizedEvent(667, 375, true)"
></Button>
<Button
type=
"ghost"
icon=
"image"
@
click=
"resizedEvent(667, 375, true)"
></Button>
</Tooltip>
</Tooltip>
<Tooltip
placement=
"top"
content=
"宽100%"
>
<Tooltip
placement=
"top"
content=
"宽100%"
>
...
@@ -68,11 +78,17 @@
...
@@ -68,11 +78,17 @@
<Button
type=
"ghost"
icon=
"arrow-swap"
@
click=
"resizedEvent(667, null)"
></Button>
<Button
type=
"ghost"
icon=
"arrow-swap"
@
click=
"resizedEvent(667, null)"
></Button>
</Tooltip>
</Tooltip>
</FormItem>
</FormItem>
<FormItem
label=
"宽高"
>
<FormItem
label=
"
容器
宽高"
>
<InputNumber
class=
"Df-basic-inputnumber"
:max=
"375"
:min=
"0"
v-model=
"point.w"
></InputNumber>
<InputNumber
class=
"Df-basic-inputnumber"
:max=
"375"
:min=
"0"
v-model=
"point.w"
@
on-change=
"updatePoint($event, 'w')"
></InputNumber>
<InputNumber
:max=
"667"
:min=
"0"
v-model=
"point.h"
></InputNumber>
<InputNumber
:max=
"667"
:min=
"0"
v-model=
"point.h"
@
on-change=
"updatePoint($event, 'h')"
></InputNumber>
</FormItem>
</FormItem>
</
template
>
</
template
>
<FormItem
label=
"背景图片"
>
<Upload
v-model=
"commonStyle.backgroundImage"
@
change=
"updateStyle($event, 'backgroundImage')"
></Upload>
</FormItem>
<FormItem
label=
"背景颜色"
>
<ColorSelector
v-model=
"commonStyle.backgroundColor"
@
input=
"updateStyle($event, 'backgroundColor')"
></ColorSelector>
</FormItem>
</Form>
</Form>
</template>
</template>
</div>
</div>
...
@@ -80,17 +96,21 @@
...
@@ -80,17 +96,21 @@
<
script
lang=
"ts"
src=
"./index.ts"
></
script
>
<
script
lang=
"ts"
src=
"./index.ts"
></
script
>
<
style
lang=
"less"
scoped
>
<
style
lang=
"less"
scoped
>
.dynamic-form {
.dynamic-form {
padding: 0 15px 16px;
padding: 0 0 16px;
background: #fff;
h2 {
h2 {
padding: 17px 0;
border-bottom: 8px solid #F5F6FA;
text-align: center;
text-align: center;
}
}
h
4
{
h
3
{
padding: 10px 0;
padding: 10px 0;
margin-bottom: 10px;
margin-bottom: 10px;
border-bottom: 1px solid #ebeef5;
border-bottom: 1px solid #ebeef5;
}
}
&-component {
&-component {
padding: 0 20px;
padding: 0 20px;
border-bottom: 8px solid #F5F6FA;
}
}
&-basic {
&-basic {
padding: 0 20px;
padding: 0 20px;
...
...
app/web/page/editor/component/DynamicPageForm/index.ts
0 → 100644
View file @
e79407ce
import
{
Component
,
Mixins
,
Prop
,
Watch
}
from
'
vue-property-decorator
'
;
import
{
Getter
,
State
}
from
'
vuex-class
'
;
import
{
reduce
,
ceil
,
subtract
,
divide
}
from
'
lodash
'
;
import
ContextMenuMixin
from
'
@editor/mixins/contextMenu.mixin
'
;
import
Upload
from
'
../DynamicForm/component/Upload/index.vue
'
;
import
ColorSelector
from
'
../DynamicForm/component/ColorSelector/index.vue
'
;
import
BaseSelect
from
'
../DynamicForm/component/BaseSelect/index.vue
'
;
import
Textarea
from
'
../DynamicForm/component/Textarea/index.vue
'
;
import
Number
from
'
../DynamicForm/component/Number/index.vue
'
;
import
{
resizeDiv
,
getStyle
}
from
'
@/service/utils.service
'
;
@
Component
({
components
:
{
Upload
,
ColorSelector
,
BaseSelect
,
Textarea
,
Number
},
name
:
'
DynamicForm
'
})
export
default
class
DynamicPageForm
extends
Mixins
(
ContextMenuMixin
)
{
@
Getter
(
'
pageData
'
)
pageData
;
title
:
string
=
'
页面背景
'
;
form
:
object
=
{};
schame
:
object
[]
=
[
{
key
:
'
backgroundImage
'
,
name
:
'
背景图片
'
,
type
:
'
Upload
'
},
{
key
:
'
backgroundColor
'
,
name
:
'
背景颜色
'
,
type
:
'
ColorSelector
'
},
];
@
Watch
(
'
pageData
'
,
{
immediate
:
true
,
deep
:
true
})
onElementChange
(
newVal
)
{
const
keys
=
Object
.
keys
(
this
.
schame
);
// this.form = {};
this
.
schame
.
forEach
(
schame
=>
{
this
.
$set
(
this
.
form
,
schame
.
key
,
this
.
pageData
?.
commonStyle
[
schame
.
key
]);
});
}
@
Watch
(
'
form
'
,
{
immediate
:
true
,
deep
:
true
})
onFormChange
(
newVal
)
{
this
.
$emit
(
'
modProps
'
,
this
.
form
,
'
page
'
);
}
// resizedChildEvent(type) {
// this.$emit('resizedChildEvent', type);
// // const containerEle = this.$refs.freedomContainer[this.curEleIndex];
// }
}
\ No newline at end of file
app/web/page/editor/component/DynamicPageForm/index.vue
0 → 100644
View file @
e79407ce
<
template
>
<div
class=
"dynamic-form"
>
<h2>
{{
title
}}
</h2>
<Form
class=
"dynamic-form-component"
:label-width=
"80"
:model=
"form"
>
<h3>
组件属性
</h3>
<template
v-for=
"(item, index) in schame"
>
<FormItem
class=
"Df-component-formitem"
:label=
"item.name"
>
<component
:is=
"item.type"
:options=
"item.options"
v-model=
"form[item.key]"
/>
</FormItem>
</
template
>
</Form>
</div>
</template>
<
script
lang=
"ts"
src=
"./index.ts"
></
script
>
<
style
lang=
"less"
scoped
>
.dynamic-form {
background: #fff;
h2 {
padding: 17px 0;
border-bottom: 8px solid #F5F6FA;
text-align: center;
}
h3 {
padding: 10px 0;
margin-bottom: 10px;
border-bottom: 1px solid #ebeef5;
}
&-component {
padding: 0 20px;
border-bottom: 8px solid #F5F6FA;
}
&-basic {
padding: 0 20px;
.Df-basic-inputnumber {
margin-right: 10px;
}
}
/deep/ .ivu-form-item-label {
font-size: 14px;
}
/deep/ .ivu-input-number {
width: 60px;
}
/deep/ .ivu-form-item-content {
.ivu-tooltip {
margin-right: 6px;
.ivu-btn-ghost {
padding: 2px 6px;
display: flex;
align-items: center;
justify-content: center;
.ivu-icon {
font-size: 20px;
}
}
&:last-child {
.ivu-icon {
transform: rotate(90deg);
}
}
}
}
}
</
style
>
\ No newline at end of file
app/web/page/editor/component/FreedomContainer/index.ts
View file @
e79407ce
import
{
Component
,
Prop
,
Mixins
,
Watch
}
from
'
vue-property-decorator
'
;
import
{
Component
,
Prop
,
Mixins
,
Watch
}
from
'
vue-property-decorator
'
;
import
LoginForm
from
'
@/lib/Form/index.vue
'
;
//
import LoginForm from '@/lib/Form/index.vue';
import
DownloadGuide
from
'
@/lib/DownloadGuide/index.vue
'
;
import
DownloadGuide
from
'
@/lib/DownloadGuide/index.vue
'
;
import
{
ContextMenu
}
from
'
@editor/mixins/contextMenu.mixin
'
;
import
Marquee
from
'
@/lib/Marquee/index.vue
'
;
import
ContextMenuMixin
from
'
@editor/mixins/contextMenu.mixin
'
;
import
TransformStyleMixin
from
'
@/page/mixins/transformStyle.mixin
'
;
import
{
cloneDeep
,
pick
,
omit
,
throttle
}
from
'
lodash
'
;
import
{
cloneDeep
,
pick
,
omit
,
throttle
}
from
'
lodash
'
;
import
{
Action
,
Mutation
,
State
}
from
'
vuex-class
'
;
import
{
Action
,
Mutation
,
State
,
Getter
}
from
'
vuex-class
'
;
import
{
convertPointStyle
,
getStyle
}
from
'
@/service/utils.service
'
;
import
{
convertPointStyle
,
getStyle
}
from
'
@/service/utils.service
'
;
@
Component
({
components
:
{
LoginForm
,
DownloadGuid
e
},
name
:
'
FreedomContainer
'
})
@
Component
({
components
:
{
DownloadGuide
,
Marque
e
},
name
:
'
FreedomContainer
'
})
export
default
class
FreedomContainer
extends
Mixins
(
ContextMenu
)
{
export
default
class
FreedomContainer
extends
Mixins
(
ContextMenu
Mixin
,
TransformStyleMixin
)
{
@
Action
(
'
setDragable
'
)
setDragable
;
@
Action
(
'
setDragable
'
)
setDragable
;
@
State
(
state
=>
state
.
editor
.
curEleIndex
)
curEleIndex
;
@
State
(
state
=>
state
.
editor
.
curChildIndex
)
curChildIndex
;
@
State
(
state
=>
state
.
editor
.
curChildIndex
)
curChildIndex
;
@
Getter
(
'
pageData
'
)
pageData
;
@
Prop
({
type
:
Object
,
default
:
()
=>
({
child
:
[]
})})
childItem
;
@
Prop
({
type
:
Object
,
default
:
()
=>
({
child
:
[]
})})
childItem
;
@
Prop
({
type
:
Number
,
default
:
0
})
containerIndex
;
@
Prop
({
type
:
Number
,
default
:
0
})
containerIndex
;
@
Prop
({
type
:
Boolean
,
default
:
false
})
showHeader
;
@
Prop
({
type
:
Boolean
,
default
:
false
})
showHeader
;
@
Prop
(
String
)
backgroundImage
;
@
Prop
(
String
)
backgroundImage
;
@
Prop
({
type
:
String
,
default
:
'
#fff
'
})
backgroundColor
;
dots
:
object
=
{};
dots
:
object
=
{};
get
styles
()
{
return
{
// background: `url(${this.backgroundImage}) no-repeat 0 0 / cover`,
// backgroundColor: this.backgroundColor
};
}
mousedown
(
childIndex
,
event
)
{
mousedown
(
childIndex
,
event
)
{
this
.
setDragable
(
false
);
this
.
setDragable
(
false
);
const
childItem
=
cloneDeep
(
this
.
childItem
);
const
childItem
=
cloneDeep
(
this
.
childItem
);
...
@@ -42,37 +54,45 @@ export default class FreedomContainer extends Mixins(ContextMenu) {
...
@@ -42,37 +54,45 @@ export default class FreedomContainer extends Mixins(ContextMenu) {
document
.
addEventListener
(
'
mouseup
'
,
up
,
true
);
document
.
addEventListener
(
'
mouseup
'
,
up
,
true
);
}
}
transformStyle
(
styleObj
,
element
)
{
let
style
=
{};
for
(
const
key
of
Object
.
keys
(
styleObj
))
{
if
(
typeof
styleObj
[
key
]
===
'
number
'
)
{
style
[
key
]
=
`
${(
styleObj
[
key
]
/
37.5
).
toFixed
(
2
)}
rem`
;
}
else
{
style
[
key
]
=
styleObj
[
key
]?.
includes
(
'
px
'
)
?
`
${(
+
(
styleObj
[
key
].
slice
(
0
,
-
2
))
/
37.5
).
toFixed
(
2
)}
rem`
:
styleObj
[
key
];
}
if
(
key
===
'
backgroundImage
'
)
{
style
.
backgroundImage
=
`url(
${
style
.
backgroundImage
}
)`
;
}
}
const
transformFun
=
element
===
'
container
'
?
pick
:
omit
;
style
=
transformFun
(
style
,
[
'
position
'
,
'
top
'
,
'
left
'
]);
return
style
;
}
handleElementClick
(
curEleIndex
,
curChildIndex
)
{
handleElementClick
(
curEleIndex
,
curChildIndex
)
{
this
.
$emit
(
'
handleElementClick
'
,
curEleIndex
,
curChildIndex
);
this
.
$emit
(
'
handleElementClick
'
,
curEleIndex
,
curChildIndex
);
}
}
get
commonStyle
()
{
if
((
this
.
curEleIndex
||
this
.
curEleIndex
===
0
)
&&
(
this
.
curChildIndex
||
this
.
curChildIndex
===
0
))
{
return
this
.
pageData
?.
elements
[
this
.
curEleIndex
]?.
child
[
this
.
curChildIndex
]?.
commonStyle
;
}
return
null
;
}
@
Watch
(
'
curChildIndex
'
)
@
Watch
(
'
curChildIndex
'
)
onIndexChange
(
newVal
)
{
onIndexChange
(
newVal
)
{
this
.
dots
=
{};
this
.
dots
=
{};
if
(
newVal
||
newVal
===
0
)
{
// console.log('onIndexChange');
if
(
this
.
curChildIndex
||
this
.
curChildIndex
===
0
)
{
this
.
setPointStyle
();
this
.
setPointStyle
();
}
}
}
}
@
Watch
(
'
commonStyle
'
)
onCommonStyleChange
(
newVal
)
{
// console.log('onCommonStyleChange', newVal);
if
(
newVal
)
{
this
.
setDotsStyle
();
}
}
// 获取point计算后样式
// 获取point计算后样式
setPointStyle
()
{
setPointStyle
()
{
this
.
$nextTick
(()
=>
{
const
[
height
,
width
]
=
this
.
getHW
(
this
.
curChildIndex
);
const
childEle
=
this
.
childItem
.
child
[
this
.
curChildIndex
];
this
.
setDotsStyle
();
this
.
updateCommonStyle
({
containerIndex
:
this
.
containerIndex
,
childIndex
:
this
.
curChildIndex
,
data
:
{
...
childEle
.
commonStyle
,
height
:
+
height
,
width
:
+
width
}});
});
}
setDotsStyle
()
{
this
.
$nextTick
(()
=>
{
this
.
$nextTick
(()
=>
{
const
points
=
[
'
lt
'
,
'
rt
'
,
'
lb
'
,
'
rb
'
,
'
l
'
,
'
r
'
,
'
t
'
,
'
b
'
];
const
points
=
[
'
lt
'
,
'
rt
'
,
'
lb
'
,
'
rb
'
,
'
l
'
,
'
r
'
,
'
t
'
,
'
b
'
];
const
[
height
,
width
]
=
this
.
getHW
(
this
.
curChildIndex
);
const
[
height
,
width
]
=
this
.
getHW
(
this
.
curChildIndex
);
...
@@ -80,8 +100,6 @@ export default class FreedomContainer extends Mixins(ContextMenu) {
...
@@ -80,8 +100,6 @@ export default class FreedomContainer extends Mixins(ContextMenu) {
pre
[
cur
]
=
convertPointStyle
(
cur
,
{
height
,
width
});
pre
[
cur
]
=
convertPointStyle
(
cur
,
{
height
,
width
});
return
pre
;
return
pre
;
},
{});
},
{});
const
childEle
=
this
.
childItem
.
child
[
this
.
curChildIndex
];
this
.
updateCommonStyle
({
containerIndex
:
this
.
containerIndex
,
childIndex
:
this
.
curChildIndex
,
data
:
{
...
childEle
.
commonStyle
,
height
:
+
height
,
width
:
+
width
}});
});
});
}
}
...
...
app/web/page/editor/component/FreedomContainer/index.vue
View file @
e79407ce
<
template
>
<
template
>
<div
class=
"freedom"
:ref=
"`freedomContainer$
{containerIndex}`" @click.stop="handleElementClick(containerIndex)">
<div
class=
"freedom"
:ref=
"`freedomContainer$
{containerIndex}`" @click.stop="handleElementClick(containerIndex)">
<div
class=
"freedom-body"
:style=
"
{background: `url(${backgroundImage}) no-repeat 0 0 / cover`}
">
<div
class=
"freedom-body"
:style=
"
styles"
:data-index=
"containerIndex
"
>
<div
v-for=
"(item, index) in childItem.child"
:style=
"transformStyle(item.commonStyle, 'container')"
:class=
"['freedom-body-item',
{ 'Fb-item_selected': curChildIndex === index }]" :key="index" @click.stop="handleElementClick(containerIndex, index)" @mousedown.stop="mousedown(index, $event)" @contextmenu.prevent.stop="show($event, containerIndex, index)">
<div
v-for=
"(item, index) in childItem.child"
:style=
"transformStyle(item.commonStyle, 'container')"
:class=
"['freedom-body-item',
{ 'Fb-item_selected': curChildIndex === index }]" :key="index" @click.stop="handleElementClick(containerIndex, index)" @mousedown.stop
.prevent
="mousedown(index, $event)" @contextmenu.prevent.stop="show($event, containerIndex, index)">
<component
ref=
"childComponent"
:style=
"transformStyle(item.commonStyle, 'component')"
:is=
"item.name"
v-bind=
"item.props"
></component>
<component
ref=
"childComponent"
:style=
"transformStyle(item.commonStyle, 'component')"
:is=
"item.name"
v-bind=
"item.props"
></component>
<div
class=
"freedom-body-dot"
<div
class=
"freedom-body-dot"
v-for=
"(style, key) in dots[index]"
v-for=
"(style, key) in dots[index]"
...
...
app/web/page/editor/component/QgTable/index.vue
View file @
e79407ce
...
@@ -7,7 +7,8 @@
...
@@ -7,7 +7,8 @@
<Select
v-model=
"searchForm[item.key]"
class=
"comWidth"
filterable
v-else-if=
"item.type === 'select'"
clearable
>
<Select
v-model=
"searchForm[item.key]"
class=
"comWidth"
filterable
v-else-if=
"item.type === 'select'"
clearable
>
<Option
:value=
"isNum(value, item.number)"
:key=
"value"
v-for=
"(label,value) in item.option"
:label=
"label"
/>
<Option
:value=
"isNum(value, item.number)"
:key=
"value"
v-for=
"(label,value) in item.option"
:label=
"label"
/>
</Select>
</Select>
<DatePicker
v-else
class=
"timeWidth"
type=
"datetimerange"
placeholder=
""
v-model=
"searchForm[item.key]"
></DatePicker>
<DatePicker
v-else-if=
"item.type === 'date'"
class=
"timeWidth"
type=
"datetimerange"
placeholder=
""
v-model=
"searchForm[item.key]"
></DatePicker>
<treeselect
v-else-if=
"item.type === 'treeSelect'"
v-model.number=
"searchForm[item.key]"
:multiple=
"false"
:options=
"item.option"
placeholder=
"请选择"
:normalizer=
"normalizer"
style=
"width:180px"
/>
</FormItem>
</FormItem>
<FormItem
class=
"btnGroupStyle"
>
<FormItem
class=
"btnGroupStyle"
>
<div>
<div>
...
@@ -18,14 +19,14 @@
...
@@ -18,14 +19,14 @@
</Form>
</Form>
</div>
</div>
<div
class=
"tableGroupStyle"
>
<div
class=
"tableGroupStyle"
>
<div
class=
"toolBarStyle"
>
<div
v-if=
"!hideAdd"
class=
"toolBarStyle"
>
<h3>
查询数据
</h3>
<h3>
查询数据
</h3>
<div>
<div>
<Button
type=
"primary"
class=
"btnStyle"
@
click=
"newEvent()"
>
新增
</Button>
<Button
type=
"primary"
class=
"btnStyle"
@
click=
"newEvent()"
>
新增
</Button>
<slot></slot>
<slot></slot>
</div>
</div>
</div>
</div>
<Table
:columns=
"renderColumns"
:data=
"tableData"
class=
"tableStyle"
></Table>
<Table
:
height=
"height"
@
on-selection-change=
"selectionChange"
:
columns=
"renderColumns"
:data=
"tableData"
class=
"tableStyle"
></Table>
<Page
<Page
:total=
"total"
:total=
"total"
v-if=
"total > 0"
v-if=
"total > 0"
...
@@ -41,14 +42,25 @@
...
@@ -41,14 +42,25 @@
</div>
</div>
</
template
>
</
template
>
<
script
>
<
script
>
import
Treeselect
from
'
@riophae/vue-treeselect
'
;
import
'
@riophae/vue-treeselect/dist/vue-treeselect.css
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
export
default
{
export
default
{
components
:
{
Treeselect
},
props
:
{
props
:
{
columns
:
Array
,
columns
:
{
type
:
Array
,
default
:
()
=>
({})
},
hideAdd
:
Boolean
,
request
:
Function
,
request
:
Function
,
toolBar
:
Function
,
toolBar
:
Function
,
height
:
Number
,
},
},
data
()
{
data
()
{
return
{
return
{
cols
:
this
.
transformData
(),
tableData
:
[],
tableData
:
[],
total
:
0
,
total
:
0
,
searchForm
:
{
searchForm
:
{
...
@@ -70,7 +82,7 @@ export default {
...
@@ -70,7 +82,7 @@ export default {
},
},
computed
:
{
computed
:
{
renderColumns
:
function
()
{
renderColumns
:
function
()
{
return
this
.
handleColumns
(
this
.
col
umn
s
)
return
this
.
handleColumns
(
this
.
cols
)
}
}
},
},
methods
:
{
methods
:
{
...
@@ -105,12 +117,16 @@ export default {
...
@@ -105,12 +117,16 @@ export default {
this
.
searchForm
.
pageSize
=
10
;
this
.
searchForm
.
pageSize
=
10
;
this
.
searchForm
.
pageNo
=
1
;
this
.
searchForm
.
pageNo
=
1
;
},
},
refresh
()
{
this
.
query
();
},
newEvent
(
e
)
{
newEvent
(
e
)
{
this
.
$emit
(
'
newBtnClick
'
,
e
);
this
.
$emit
(
'
newBtnClick
'
,
e
);
},
},
handleColumns
(
col
=
[])
{
handleColumns
(
col
=
[])
{
const
data
=
[]
const
data
=
[]
col
.
forEach
(
item
=>
{
this
.
searchCondition
=
[];
col
.
forEach
(
item
=>
{
item
.
align
=
item
.
align
||
'
center
'
;
item
.
align
=
item
.
align
||
'
center
'
;
if
(
item
.
valueEnum
&&!
item
.
render
)
{
if
(
item
.
valueEnum
&&!
item
.
render
)
{
item
.
render
=
(
h
,
params
)
=>
{
item
.
render
=
(
h
,
params
)
=>
{
...
@@ -128,6 +144,35 @@ export default {
...
@@ -128,6 +144,35 @@ export default {
},
},
isNum
(
value
,
number
)
{
isNum
(
value
,
number
)
{
return
number
?
+
value
:
value
;
return
number
?
+
value
:
value
;
},
selectionChange
(
selection
)
{
this
.
$emit
(
'
on-selection-change
'
,
selection
);
},
normalizer
(
node
)
{
if
(
node
.
children
&&
!
node
.
children
.
length
)
{
delete
node
.
children
;
}
return
{
id
:
node
.
id
||
null
,
label
:
node
.
label
,
children
:
node
.
children
,
};
},
transformData
()
{
return
cloneDeep
(
this
.
columns
).
map
(
item
=>
{
// 处理valueEnum为异步函数的情况
if
(
item
.
valueEnum
&&
typeof
item
.
valueEnum
===
'
function
'
)
{
item
.
valueEnum
().
then
(
v
=>
{
this
.
cols
.
forEach
(
column
=>
{
if
(
column
.
key
===
item
.
key
)
{
column
.
valueEnum
=
v
;
}
})
});
item
.
valueEnum
=
[];
}
return
item
;
})
}
}
},
},
mounted
()
{
mounted
()
{
...
@@ -148,16 +193,14 @@ export default {
...
@@ -148,16 +193,14 @@ export default {
background-color: #ffffff;
background-color: #ffffff;
padding: @padding;
padding: @padding;
min-height: 70px;
min-height: 70px;
font-size: 0;
.labelStyle {
.labelStyle {
font-weight: bold !important;
font-weight: bold !important;
display: inline-block;
display: inline-block;
}
}
// & @{deep} .ivu-form-item .ivu-form-item-label {
/deep/ .ivu-form {
// .labelStyle;
margin-bottom: -24px;
// }
}
// & @{deep} .ivu-form-item-content {
// .labelStyle;
// }
.required:before {
.required:before {
content: '* ';
content: '* ';
color: #ed3f14;
color: #ed3f14;
...
...
app/web/page/editor/mixins/contextMenu.mixin.ts
View file @
e79407ce
import
{
Component
,
Vue
}
from
'
vue-property-decorator
'
;
import
{
Component
,
Vue
}
from
'
vue-property-decorator
'
;
import
{
Mutation
}
from
'
vuex-class
'
;
import
{
Mutation
}
from
'
vuex-class
'
;
import
{
getStyle
}
from
'
@/service/utils.service
'
;
@
Component
({
name
:
'
ContextMenu
'
})
@
Component
({
name
:
'
ContextMenu
Mixin
'
})
export
class
ContextMenu
extends
Vue
{
export
default
class
ContextMenuMixin
extends
Vue
{
@
Mutation
(
'
COPY_OR_DELETE_PAGE_INFO
'
)
updatePageData
;
@
Mutation
(
'
COPY_OR_DELETE_PAGE_INFO
'
)
updatePageData
;
@
Mutation
(
'
UPDATE_PAGE_INFO
'
)
updatePageInfo
;
@
Mutation
(
'
UPDATE_PAGE_INFO
'
)
updatePageInfo
;
@
Mutation
(
'
UPDATE_COMMON_STYLE
'
)
updateCommonStyle
;
@
Mutation
(
'
UPDATE_COMMON_STYLE
'
)
updateCommonStyle
;
...
@@ -31,4 +32,13 @@ export class ContextMenu extends Vue {
...
@@ -31,4 +32,13 @@ export class ContextMenu extends Vue {
minWidth
:
100
minWidth
:
100
});
});
}
}
adjustHeight
()
{
if
(
!
this
.
curEleIndex
&&
this
.
curEleIndex
!==
0
)
{
return
;
}
const
elements
=
this
.
pageData
.
elements
[
this
.
curEleIndex
];
const
component
=
document
.
getElementById
(
elements
.
id
);
const
height
=
component
?
getStyle
(
component
,
'
height
'
)
:
0
;
console
.
log
(
'
adjustHeight
'
,
height
);
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
data
:
{
...
elements
,
point
:
{
...
elements
.
point
,
h
:
+
height
||
elements
.
point
.
h
}
}
});
}
}
}
\ No newline at end of file
app/web/page/editor/mixins/goodsTabs.mixin.ts
0 → 100644
View file @
e79407ce
import
{
Component
,
Vue
}
from
'
vue-property-decorator
'
;
import
{
Mutation
,
Getter
}
from
'
vuex-class
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
@
Component
({
name
:
'
GoodsTabsMixin
'
})
export
default
class
GoodsTabsMixin
extends
Vue
{
@
Getter
(
'
pageData
'
)
pageData
;
@
Mutation
(
'
UPDATE_PAGE_INFO
'
)
updatePageInfo
;
@
Mutation
(
'
COPY_OR_DELETE_PAGE_INFO
'
)
updatePageData
;
handleGoodsTabs
()
{
const
goodsTabs
=
{};
const
pageData
=
cloneDeep
(
this
.
pageData
);
pageData
.
elements
.
forEach
((
element
,
idx
)
=>
{
if
(
element
.
name
===
'
goods-tabs
'
&&
element
?.
props
?.
list
.
length
)
{
const
childs
=
[];
const
childIndexs
=
[];
element
.
props
.
list
.
forEach
((
data
,
index
)
=>
{
const
index
=
pageData
.
elements
.
findIndex
(
v
=>
v
.
id
===
data
.
componentId
);
if
(
index
!==
-
1
)
{
childIndexs
.
push
(
index
);
childs
.
push
(
pageData
.
elements
[
index
]);
}
});
goodsTabs
[
element
.
id
]
=
{
idx
,
childs
,
childIndexs
};
}
});
Object
.
keys
(
goodsTabs
).
forEach
(
key
=>
{
const
{
idx
,
childIndexs
,
childs
}
=
goodsTabs
[
key
];
pageData
.
elements
[
idx
].
child
=
childs
;
// 逆向循环
for
(
let
i
=
childIndexs
.
length
-
1
;
i
>=
0
;
i
--
)
{
pageData
.
elements
.
splice
(
childIndexs
[
i
],
1
);
}
});
return
pageData
;
}
parseGoodsTabs
()
{
const
goodsTabs
=
{};
this
.
pageData
.
elements
.
forEach
((
element
,
idx
)
=>
{
if
(
element
.
name
===
'
goods-tabs
'
&&
element
.
child
.
length
)
{
goodsTabs
[
idx
]
=
cloneDeep
(
element
.
child
);
// 逆向循环
for
(
let
i
=
element
.
child
.
length
-
1
;
i
>=
0
;
i
--
)
{
this
.
updatePageData
({
type
:
'
delete
'
,
containerIndex
:
idx
,
childIndex
:
i
});
}
}
});
console
.
log
(
'
parseGoodsTabs
'
,
goodsTabs
);
Object
.
keys
(
goodsTabs
).
forEach
(
key
=>
{
goodsTabs
[
key
].
forEach
((
child
,
index
)
=>
{
// console.log('parseGoodsTabs', { containerIndex: +key + 1 + index, data: child });
this
.
updatePageInfo
({
containerIndex
:
+
key
+
1
+
index
,
data
:
child
});
});
});
}
}
\ No newline at end of file
app/web/page/editor/view/dashboard/index.ts
View file @
e79407ce
import
{
kebabCase
,
maxBy
}
from
'
lodash
'
;
import
{
kebabCase
,
maxBy
}
from
'
lodash
'
;
import
{
Getter
,
Action
,
State
,
Mutation
}
from
'
vuex-class
'
;
import
{
Getter
,
Action
,
State
,
Mutation
}
from
'
vuex-class
'
;
import
{
Mixins
,
Component
,
Watch
}
from
'
vue-property-decorator
'
;
import
{
Mixins
,
Component
,
Watch
,
Provide
}
from
'
vue-property-decorator
'
;
import
DynamicComponent
from
'
@editor/component/DynamicComponent/index.vue
'
;
import
DynamicComponent
from
'
@editor/component/DynamicComponent/index.vue
'
;
import
VueGridLayout
from
'
vue-grid-layout
'
;
import
VueGridLayout
from
'
vue-grid-layout
'
;
import
FreedomContainer
from
'
../../component/FreedomContainer/index.vue
'
;
import
FreedomContainer
from
'
../../component/FreedomContainer/index.vue
'
;
import
DynamicForm
from
'
../../component/DynamicForm/index.vue
'
;
import
DynamicForm
from
'
../../component/DynamicForm/index.vue
'
;
import
LoginForm
from
'
@/lib/Form/index.vue
'
;
import
DynamicPageForm
from
'
../../component/DynamicPageForm/index.vue
'
;
// import LoginForm from '@/lib/Form/index.vue';
import
DownloadGuide
from
'
@/lib/DownloadGuide/index.vue
'
;
import
DownloadGuide
from
'
@/lib/DownloadGuide/index.vue
'
;
import
{
ContextMenu
}
from
'
@editor/mixins/contextMenu.mixin
'
;
import
GoodsTabs
from
'
@/lib/GoodsTabs/index.vue
'
;
import
Goods
from
'
@/lib/Goods/index.vue
'
;
import
Advertisement
from
'
@/lib/Advertisement/index.vue
'
;
import
Coupon
from
'
@/lib/Coupon/index.vue
'
;
import
Placeholder
from
'
@/lib/Placeholder/index.vue
'
;
import
GuideCube
from
'
@/lib/GuideCube/index.vue
'
;
import
Marquee
from
'
@/lib/Marquee/index.vue
'
;
import
ContextMenuMixin
from
'
@editor/mixins/contextMenu.mixin
'
;
import
GoodsTabsMixin
from
'
@editor/mixins/goodsTabs.mixin
'
;
import
TransformStyleMixin
from
'
@/page/mixins/transformStyle.mixin
'
;
import
BasicPageForm
from
'
@editor/component/BasicPageForm/index.vue
'
;
import
BasicPageForm
from
'
@editor/component/BasicPageForm/index.vue
'
;
import
{
basicComponents
,
businessComponents
}
from
'
@/lib/config
'
;
import
{
basicComponents
,
businessComponents
}
from
'
@/lib/config
'
;
import
config
from
'
@/config/index
'
;
import
config
from
'
@/config/index
'
;
import
localStorage
from
'
@/service/localStorage.service
'
;
import
localStorage
from
'
@/service/localStorage.service
'
;
import
EventBus
from
'
@/service/eventBus.service
'
;
@
Component
({
components
:
{
DynamicComponent
,
FreedomContainer
,
DynamicForm
,
GridLayout
:
VueGridLayout
.
GridLayout
,
@
Component
({
components
:
{
DynamicComponent
,
FreedomContainer
,
DynamicForm
,
GridLayout
:
VueGridLayout
.
GridLayout
,
GridItem
:
VueGridLayout
.
GridItem
,
LoginForm
,
DownloadGuide
,
BasicPageForm
},
name
:
'
DashBoard
'
})
GridItem
:
VueGridLayout
.
GridItem
,
DownloadGuide
,
BasicPageForm
,
DynamicPageForm
,
GoodsTabs
,
Goods
,
Coupon
,
Advertisement
,
Placeholder
,
GuideCube
,
Marquee
},
name
:
'
DashBoard
'
})
export
default
class
DashBoard
extends
Mixins
(
ContextMenu
)
{
export
default
class
DashBoard
extends
Mixins
(
ContextMenu
Mixin
,
GoodsTabsMixin
,
TransformStyleMixin
)
{
@
Mutation
(
'
ADD_ELEMENTS
'
)
addElements
;
@
Mutation
(
'
ADD_ELEMENTS
'
)
addElements
;
@
Mutation
(
'
SET_CUR_ELE_INDEX
'
)
setCurEleIndex
;
@
Mutation
(
'
SET_CUR_ELE_INDEX
'
)
setCurEleIndex
;
@
Mutation
(
'
SET_CUR_CHILD_INDEX
'
)
setCurChildIndex
;
@
Mutation
(
'
SET_CUR_CHILD_INDEX
'
)
setCurChildIndex
;
@
Mutation
(
'
SET_PAGE_INFO
'
)
setPageInfo
;
@
Mutation
(
'
SET_PAGE_INFO
'
)
setPageInfo
;
@
Mutation
(
'
SET_PAGE_DATA
'
)
setPageData
;
@
Mutation
(
'
SET_PAGE_DATA
'
)
setPageData
;
@
Mutation
(
'
UPDATE_PAGE_STYLE
'
)
setPageStyle
;
@
Action
(
'
resetPageData
'
)
resetPageData
;
@
Action
(
'
resetPageData
'
)
resetPageData
;
@
Action
(
'
savePageData
'
)
savePageData
;
@
Action
(
'
savePageData
'
)
savePageData
;
@
Action
(
'
getPageDate
'
)
getPageDate
;
@
Action
(
'
getPageDate
'
)
getPageDate
;
...
@@ -35,6 +47,8 @@ export default class DashBoard extends Mixins(ContextMenu) {
...
@@ -35,6 +47,8 @@ export default class DashBoard extends Mixins(ContextMenu) {
@
State
(
state
=>
state
.
editor
.
curChildIndex
)
curChildIndex
;
@
State
(
state
=>
state
.
editor
.
curChildIndex
)
curChildIndex
;
@
State
(
state
=>
state
.
editor
.
templateList
)
templateList
;
@
State
(
state
=>
state
.
editor
.
templateList
)
templateList
;
@
Provide
()
editor
=
this
;
activeName
:
string
=
'
1
'
;
activeName
:
string
=
'
1
'
;
isCollapsed
:
boolean
=
true
;
isCollapsed
:
boolean
=
true
;
isDragIn
:
boolean
=
false
;
isDragIn
:
boolean
=
false
;
...
@@ -48,10 +62,11 @@ export default class DashBoard extends Mixins(ContextMenu) {
...
@@ -48,10 +62,11 @@ export default class DashBoard extends Mixins(ContextMenu) {
console
.
log
(
'
env
'
,
process
.
env
);
console
.
log
(
'
env
'
,
process
.
env
);
this
.
resetPageData
();
this
.
resetPageData
();
if
(
pageId
)
{
if
(
pageId
)
{
this
.
getPageDate
({
pageId
});
await
this
.
getPageDate
({
pageId
});
}
else
if
(
templateId
)
{
}
else
if
(
templateId
)
{
this
.
setTemplateInfo
({
pageId
:
templateId
});
await
this
.
setTemplateInfo
({
pageId
:
templateId
});
}
}
this
.
parseGoodsTabs
();
this
.
getTemplateList
();
this
.
getTemplateList
();
}
}
...
@@ -70,10 +85,11 @@ export default class DashBoard extends Mixins(ContextMenu) {
...
@@ -70,10 +85,11 @@ export default class DashBoard extends Mixins(ContextMenu) {
this
.
showSubmitPopup
=
true
;
this
.
showSubmitPopup
=
true
;
}
else
{
}
else
{
this
.
pageData
.
elements
.
sort
((
a
,
b
)
=>
a
.
point
.
y
-
b
.
point
.
y
);
this
.
pageData
.
elements
.
sort
((
a
,
b
)
=>
a
.
point
.
y
-
b
.
point
.
y
);
const
pageData
=
this
.
handleGoodsTabs
();
const
{
pageName
,
pageDescribe
,
coverImage
,
isPublish
,
isTemplate
}
=
pageConfig
;
const
{
pageName
,
pageDescribe
,
coverImage
,
isPublish
,
isTemplate
}
=
pageConfig
;
const
pageInfo
=
{
page
:
JSON
.
stringify
(
this
.
pageData
),
author
:
user
?.
account
,
isPublish
,
pageName
,
pageDescribe
,
coverImage
,
isTemplate
};
const
pageInfo
=
{
page
:
JSON
.
stringify
(
pageData
),
author
:
user
?.
account
,
isPublish
,
pageName
,
pageDescribe
,
coverImage
,
isTemplate
};
if
(
+
this
.
pageId
)
{
pageInfo
.
id
=
this
.
pageId
;
}
if
(
+
this
.
pageId
)
{
pageInfo
.
id
=
this
.
pageId
;
}
await
this
.
savePageData
(
pageInfo
);
await
this
.
savePageData
(
{
pageInfo
,
pageData
:
this
.
pageData
}
);
this
.
showSubmitPopup
=
false
;
this
.
showSubmitPopup
=
false
;
if
(
type
===
'
preview
'
)
{
if
(
type
===
'
preview
'
)
{
window
.
open
(
`
${
config
.
apiHost
}
activity/
${
this
.
pageId
}
`
);
window
.
open
(
`
${
config
.
apiHost
}
activity/
${
this
.
pageId
}
`
);
...
@@ -93,10 +109,6 @@ export default class DashBoard extends Mixins(ContextMenu) {
...
@@ -93,10 +109,6 @@ export default class DashBoard extends Mixins(ContextMenu) {
}
}
toggle
(
val
)
{
toggle
(
val
)
{
if
(
val
)
{
this
.
setCurEleIndex
(
null
);
this
.
setCurChildIndex
(
null
);
}
this
.
isCollapsed
=
val
;
this
.
isCollapsed
=
val
;
}
}
...
@@ -126,15 +138,19 @@ export default class DashBoard extends Mixins(ContextMenu) {
...
@@ -126,15 +138,19 @@ export default class DashBoard extends Mixins(ContextMenu) {
}
}
}
}
modProps
(
props
)
{
modProps
(
props
,
ele
)
{
let
currentEle
=
{};
if
(
ele
===
'
page
'
)
{
if
(
this
.
curEleIndex
!==
null
)
{
this
.
setPageStyle
({
data
:
props
});
if
(
this
.
curChildIndex
!==
null
)
{
}
else
if
(
ele
===
'
component
'
)
{
currentEle
=
this
.
pageData
.
elements
[
this
.
curEleIndex
].
child
[
this
.
curChildIndex
];
let
currentEle
=
{};
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
childIndex
:
this
.
curChildIndex
,
data
:
{
...
currentEle
,
props
:
{
...
currentEle
.
props
,
...
props
}
}
});
if
(
this
.
curEleIndex
!==
null
)
{
}
else
{
if
(
this
.
curChildIndex
!==
null
)
{
currentEle
=
this
.
pageData
.
elements
[
this
.
curEleIndex
];
currentEle
=
this
.
pageData
.
elements
[
this
.
curEleIndex
].
child
[
this
.
curChildIndex
];
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
data
:
{
...
this
.
pageData
.
elements
[
this
.
curEleIndex
],
props
:
{
...
currentEle
.
props
,
...
props
}
}
});
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
childIndex
:
this
.
curChildIndex
,
data
:
{
...
currentEle
,
props
:
{
...
currentEle
.
props
,
...
props
}
}
});
}
else
{
currentEle
=
this
.
pageData
.
elements
[
this
.
curEleIndex
];
this
.
updatePageInfo
({
containerIndex
:
this
.
curEleIndex
,
data
:
{
...
this
.
pageData
.
elements
[
this
.
curEleIndex
],
props
:
{
...
currentEle
.
props
,
...
props
}
}
});
}
}
}
}
}
}
}
...
@@ -150,7 +166,7 @@ export default class DashBoard extends Mixins(ContextMenu) {
...
@@ -150,7 +166,7 @@ export default class DashBoard extends Mixins(ContextMenu) {
this
.
setPageData
(
JSON
.
parse
(
data
.
template
));
this
.
setPageData
(
JSON
.
parse
(
data
.
template
));
this
.
handleElementClick
(
null
,
null
);
this
.
handleElementClick
(
null
,
null
);
// freedom
// freedom
}
else
if
(
event
.
target
.
classList
.
contains
(
'
freedom
'
))
{
}
else
if
(
event
.
target
.
classList
.
contains
(
'
freedom
-body
'
))
{
const
{
y
:
curY
}
=
this
.
pageData
.
elements
[
event
.
target
.
dataset
.
index
].
point
;
const
{
y
:
curY
}
=
this
.
pageData
.
elements
[
event
.
target
.
dataset
.
index
].
point
;
const
scrollTop
=
this
.
layout
.
reduce
((
pre
,
cur
)
=>
{
const
scrollTop
=
this
.
layout
.
reduce
((
pre
,
cur
)
=>
{
if
(
cur
.
y
<
curY
)
{
if
(
cur
.
y
<
curY
)
{
...
@@ -162,18 +178,24 @@ export default class DashBoard extends Mixins(ContextMenu) {
...
@@ -162,18 +178,24 @@ export default class DashBoard extends Mixins(ContextMenu) {
this
.
handleElementClick
(
+
event
.
target
.
dataset
.
index
,
this
.
pageData
.
elements
[
event
.
target
.
dataset
.
index
].
child
.
length
-
1
);
this
.
handleElementClick
(
+
event
.
target
.
dataset
.
index
,
this
.
pageData
.
elements
[
event
.
target
.
dataset
.
index
].
child
.
length
-
1
);
// component
// component
}
else
{
}
else
{
const
{
i
}
=
maxBy
(
this
.
layout
,
'
i
'
)
||
{};
const
y
=
Math
.
floor
(
top
/
this
.
rowHeight
);
const
y
=
Math
.
floor
(
top
/
this
.
rowHeight
);
console
.
log
(
'
drops
'
,
i
);
this
.
addElements
({
data
:
{...
data
,
point
:
{
...
data
.
point
,
y
}
});
this
.
addElements
({
data
:
{...
data
,
point
:
{
...
data
.
point
,
i
:
i
||
i
===
0
?
String
(
+
i
+
1
)
:
'
0
'
,
y
}
});
this
.
handleElementClick
(
this
.
pageData
.
elements
.
length
-
1
,
null
);
this
.
handleElementClick
(
this
.
pageData
.
elements
.
length
-
1
,
null
);
}
}
// 调整组件高度
this
.
$nextTick
(()
=>
this
.
adjustHeight
());
}
}
resizedEvent
(
i
,
h
,
w
)
{
resizedEvent
(
i
,
h
,
w
)
{
const
index
=
this
.
pageData
.
elements
.
findIndex
(
ele
=>
ele
.
point
.
i
===
i
);
const
index
=
this
.
pageData
.
elements
.
findIndex
(
ele
=>
ele
.
point
.
i
===
i
);
this
.
updatePageInfo
({
containerIndex
:
index
,
data
:
{
...
this
.
pageData
.
elements
[
index
],
point
:
{
...
this
.
pageData
.
elements
[
index
].
point
,
w
,
h
}
}
});
this
.
updatePageInfo
({
containerIndex
:
index
,
data
:
{
...
this
.
pageData
.
elements
[
index
],
point
:
{
...
this
.
pageData
.
elements
[
index
].
point
,
w
,
h
}
}
});
}
}
movedEvent
(
i
,
newX
,
newY
)
{
EventBus
.
$emit
(
'
component-moved
'
);
console
.
log
(
'
MOVED i=
'
+
i
+
'
, X=
'
+
newX
+
'
, Y=
'
+
newY
);
}
/**
/**
* 调整自由容器子元素宽高及边框原点位置
* 调整自由容器子元素宽高及边框原点位置
* @param {[type]} type 尺寸类型
* @param {[type]} type 尺寸类型
...
...
app/web/page/editor/view/dashboard/index.vue
View file @
e79407ce
...
@@ -60,6 +60,8 @@
...
@@ -60,6 +60,8 @@
:is-mirrored=
"false"
:is-mirrored=
"false"
:vertical-compact=
"true"
:vertical-compact=
"true"
:use-css-transforms=
"true"
:use-css-transforms=
"true"
:style=
"transformStyle(pageData.commonStyle)"
@
click.native.stop=
"toggle(false)"
>
>
<grid-item
@
click.native.stop=
"handleElementClick(index, null)"
v-for=
"(item, index) in pageData.elements"
<grid-item
@
click.native.stop=
"handleElementClick(index, null)"
v-for=
"(item, index) in pageData.elements"
:x=
"item.point.x"
:x=
"item.point.x"
...
@@ -70,8 +72,9 @@
...
@@ -70,8 +72,9 @@
:key=
"item.point.i"
:key=
"item.point.i"
@
contextmenu.native.prevent=
"show($event, index)"
@
contextmenu.native.prevent=
"show($event, index)"
@
resized=
"resizedEvent"
@
resized=
"resizedEvent"
@
moved=
"movedEvent"
:class=
"
{'Dcmcp-item_selected': curEleIndex === index
&&
curChildIndex === null}">
:class=
"
{'Dcmcp-item_selected': curEleIndex === index
&&
curChildIndex === null}">
<component
ref=
"container"
class=
"Dcmcp-item-com"
@
handleElementClick=
"handleElementClick"
:data-index=
"index
"
:containerIndex=
"index"
:childItem=
"item"
:is=
"item.name"
:key=
"index"
v-bind=
"item.props"
></component>
<component
ref=
"container"
:style=
"transformStyle(item.commonStyle)"
:id=
"item.id"
class=
"Dcmcp-item-com"
@
handleElementClick=
"handleElementClick
"
:containerIndex=
"index"
:childItem=
"item"
:is=
"item.name"
:key=
"index"
v-bind=
"item.props"
></component>
</grid-item>
</grid-item>
</grid-layout>
</grid-layout>
</div>
</div>
...
@@ -82,7 +85,9 @@
...
@@ -82,7 +85,9 @@
<dynamic-form
@
modProps=
"modProps"
@
resizedChildEvent=
"resizedChildEvent"
></dynamic-form>
<dynamic-form
@
modProps=
"modProps"
@
resizedChildEvent=
"resizedChildEvent"
></dynamic-form>
</TabPane>
</TabPane>
<TabPane
label=
"事件"
>
事件
</TabPane>
<TabPane
label=
"事件"
>
事件
</TabPane>
<TabPane
label=
"页面设置"
>
页面设置
</TabPane>
<TabPane
label=
"页面设置"
>
<dynamic-page-form
@
modProps=
"modProps"
@
resizedChildEvent=
"resizedChildEvent"
></dynamic-page-form>
</TabPane>
</Tabs>
</Tabs>
</Col>
</Col>
</Row>
</Row>
...
@@ -91,7 +96,7 @@
...
@@ -91,7 +96,7 @@
<BasicPageForm
v-model=
"showSubmitPopup"
@
submit=
"save"
/>
<BasicPageForm
v-model=
"showSubmitPopup"
@
submit=
"save"
/>
</Row>
</Row>
</
template
>
</
template
>
<
style
lang=
"less"
>
<
style
lang=
"less"
scoped
>
.tabs-position() {
.tabs-position() {
/deep/ .ivu-tabs-nav-scroll {
/deep/ .ivu-tabs-nav-scroll {
display: flex;
display: flex;
...
@@ -152,16 +157,16 @@
...
@@ -152,16 +157,16 @@
background-color: rgb(244, 244, 244);
background-color: rgb(244, 244, 244);
box-shadow: 2px 0px 10px rgba(0, 0, 0, 0.2);
box-shadow: 2px 0px 10px rgba(0, 0, 0, 0.2);
/deep/ .vue-grid-layout {
/deep/ .vue-grid-layout {
min-height: 667px;
.vue-grid-item {
.vue-grid-item {
text-align: center;
text-align: center;
background: #fff;
overflow: hidden;
overflow: hidden;
&:hover {
&:hover {
border: 1px dashed #0c0c0c !important;
border: 1px dashed #0c0c0c !important;
}
}
&>*:first-child {
//
&>*:first-child {
height: 100%;
//
height: 100%;
}
//
}
.vue-resizable-handle {
.vue-resizable-handle {
z-index: 10000;
z-index: 10000;
}
}
...
@@ -189,10 +194,18 @@
...
@@ -189,10 +194,18 @@
height: 100%;
height: 100%;
min-width: 320px;
min-width: 320px;
.tabs-position();
.tabs-position();
background: #F5F6FA;
/deep/ .ivu-tabs-bar {
background: #fff;
margin-bottom: 0;
}
/deep/ .ivu-tabs-content {
/deep/ .ivu-tabs-content {
height: calc(100% - 48px);
height: calc(100% - 48px);
overflow-y: scroll;
.ivu-tabs-tabpane {
overflow-x: hidden;
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
}
}
}
}
}
}
}
...
...
app/web/page/mixins/transformStyle.mixin.ts
0 → 100644
View file @
e79407ce
import
{
Component
,
Vue
}
from
'
vue-property-decorator
'
;
import
{
pick
,
omit
}
from
'
lodash
'
;
import
{
transformStyle
}
from
'
@/service/utils.service
'
;
@
Component
({
name
:
'
TransformStyleMixin
'
})
export
default
class
TransformStyleMixin
extends
Vue
{
transformStyle
(
styleObj
,
element
)
{
// console.log('transformStyle', styleObj, element);
let
style
=
{};
if
(
!
styleObj
)
{
return
style
;
}
for
(
const
key
of
Object
.
keys
(
styleObj
))
{
if
(
typeof
styleObj
[
key
]
===
'
number
'
)
{
style
[
key
]
=
`
${(
styleObj
[
key
]
/
37.5
).
toFixed
(
2
)}
rem`
;
}
else
{
style
[
key
]
=
styleObj
[
key
]?.
includes
(
'
px
'
)
?
`
${(
+
(
styleObj
[
key
].
slice
(
0
,
-
2
))
/
37.5
).
toFixed
(
2
)}
rem`
:
styleObj
[
key
];
}
if
(
key
===
'
backgroundImage
'
)
{
style
.
backgroundImage
=
`url(
${
style
.
backgroundImage
}
)`
;
}
}
const
transformFun
=
element
===
'
container
'
?
pick
:
omit
;
style
=
transformFun
(
style
,
[
'
position
'
,
'
top
'
,
'
left
'
]);
return
style
;
}
}
\ No newline at end of file
app/web/page/store/modules/editor/index.ts
View file @
e79407ce
import
api
from
'
@/api/editor.api
'
;
import
api
from
'
@/api/editor.api
'
;
import
{
Module
,
GetterTree
,
ActionTree
,
MutationTree
}
from
'
vuex
'
;
import
{
Module
,
GetterTree
,
ActionTree
,
MutationTree
}
from
'
vuex
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
Vue
from
'
vue
'
;
import
{
import
{
SET_PAGE_INFO
,
SET_PAGE_INFO
,
SET_DRAGABLE
,
SET_DRAGABLE
,
COPY_OR_DELETE_PAGE_INFO
,
COPY_OR_DELETE_PAGE_INFO
,
UPDATE_PAGE_INFO
,
UPDATE_PAGE_INFO
,
ADD_ELEMENTS
,
ADD_ELEMENTS
,
DEL_ELEMENTS
,
SET_CUR_ELE_INDEX
,
SET_CUR_ELE_INDEX
,
SET_CUR_CHILD_INDEX
,
SET_CUR_CHILD_INDEX
,
RESET_PAGE_DATA
,
RESET_PAGE_DATA
,
SET_TEMPLATE_LIST
,
SET_TEMPLATE_LIST
,
SET_PAGE_DATA
,
SET_PAGE_DATA
,
UPDATE_COMMON_STYLE
,
UPDATE_COMMON_STYLE
,
UPDATE_PAGE_STYLE
,
}
from
'
./type
'
;
}
from
'
./type
'
;
import
RootState
from
'
../../state
'
;
import
RootState
from
'
../../state
'
;
...
@@ -35,14 +36,15 @@ export default class EditorModule implements Module<EditorState, RootState> {
...
@@ -35,14 +36,15 @@ export default class EditorModule implements Module<EditorState, RootState> {
};
};
actions
:
ActionTree
<
EditorState
,
RootState
>
=
{
actions
:
ActionTree
<
EditorState
,
RootState
>
=
{
async
savePageData
({
commit
},
condition
)
{
// pageInfo: 处理过的页面数据 - activity, pageData: 未处理的数据 - editor
if
(
condition
.
id
)
{
async
savePageData
({
commit
},
{
pageInfo
,
pageData
})
{
await
api
.
updatePage
(
condition
);
if
(
pageInfo
.
id
)
{
commit
(
SET_PAGE_INFO
,
{
...
condition
,
page
:
JSON
.
parse
(
condition
.
page
as
string
)
});
await
api
.
updatePage
(
pageInfo
);
commit
(
SET_PAGE_INFO
,
{
...
pageInfo
,
page
:
pageData
});
}
else
{
}
else
{
const
res
=
await
api
.
savePage
(
condition
);
const
res
=
await
api
.
savePage
(
pageInfo
);
const
{
page
,
...
rest
}
=
res
as
PageInfo
;
const
{
page
,
...
rest
}
=
res
as
PageInfo
;
commit
(
SET_PAGE_INFO
,
{
...
rest
,
page
:
JSON
.
parse
(
page
as
string
)
});
commit
(
SET_PAGE_INFO
,
{
...
rest
,
page
:
pageData
});
}
}
},
},
async
getPageDate
({
commit
},
condition
)
{
async
getPageDate
({
commit
},
condition
)
{
...
@@ -125,11 +127,14 @@ export default class EditorModule implements Module<EditorState, RootState> {
...
@@ -125,11 +127,14 @@ export default class EditorModule implements Module<EditorState, RootState> {
[
UPDATE_COMMON_STYLE
](
state
,
{
containerIndex
,
childIndex
,
data
})
{
[
UPDATE_COMMON_STYLE
](
state
,
{
containerIndex
,
childIndex
,
data
})
{
const
page
=
(
state
.
pageInfo
.
page
as
Page
).
elements
;
const
page
=
(
state
.
pageInfo
.
page
as
Page
).
elements
;
if
(
childIndex
||
childIndex
===
0
)
{
if
(
childIndex
||
childIndex
===
0
)
{
page
[
containerIndex
].
child
[
childIndex
].
commonStyle
=
data
;
Vue
.
set
(
page
[
containerIndex
].
child
[
childIndex
],
'
commonStyle
'
,
data
)
;
}
else
{
}
else
{
page
[
containerIndex
].
commonStyle
=
data
;
Vue
.
set
(
page
[
containerIndex
],
'
commonStyle
'
,
data
)
;
}
}
},
},
[
UPDATE_PAGE_STYLE
](
state
,
{
data
})
{
(
state
.
pageInfo
.
page
as
Page
).
commonStyle
=
data
;
},
[
ADD_ELEMENTS
](
state
,
{
containerIndex
,
data
})
{
[
ADD_ELEMENTS
](
state
,
{
containerIndex
,
data
})
{
const
page
=
(
state
.
pageInfo
.
page
as
Page
).
elements
;
const
page
=
(
state
.
pageInfo
.
page
as
Page
).
elements
;
if
(
containerIndex
||
containerIndex
===
0
)
{
if
(
containerIndex
||
containerIndex
===
0
)
{
...
@@ -138,10 +143,6 @@ export default class EditorModule implements Module<EditorState, RootState> {
...
@@ -138,10 +143,6 @@ export default class EditorModule implements Module<EditorState, RootState> {
page
.
push
(
data
);
page
.
push
(
data
);
}
}
},
},
[
DEL_ELEMENTS
](
state
,
{
containerIndex
})
{
const
page
=
(
state
.
pageInfo
.
page
as
Page
).
elements
;
page
.
splice
(
containerIndex
,
1
);
},
};
};
constructor
(
initState
:
EditorState
=
cloneDeep
(
defaultState
))
{
constructor
(
initState
:
EditorState
=
cloneDeep
(
defaultState
))
{
...
...
app/web/page/store/modules/editor/state.ts
View file @
e79407ce
...
@@ -34,6 +34,7 @@ export interface PageElement {
...
@@ -34,6 +34,7 @@ export interface PageElement {
}
}
export
interface
Page
{
export
interface
Page
{
commonStyle
:
CommonStyle
;
elements
:
PageElement
[];
elements
:
PageElement
[];
}
}
...
@@ -57,6 +58,10 @@ export const defaultState = {
...
@@ -57,6 +58,10 @@ export const defaultState = {
coverImage
:
'
http://activitystatic.q-gp.com/low_code.jpg
'
,
coverImage
:
'
http://activitystatic.q-gp.com/low_code.jpg
'
,
isPublish
:
false
,
isPublish
:
false
,
page
:
{
page
:
{
commonStyle
:
{
backgroundColor
:
'
#f7f8fa
'
,
backgroundImage
:
''
},
elements
:
[],
elements
:
[],
}
}
},
},
...
...
app/web/page/store/modules/editor/type.ts
View file @
e79407ce
...
@@ -4,10 +4,10 @@ export const SET_DRAGABLE = 'SET_DRAGABLE';
...
@@ -4,10 +4,10 @@ export const SET_DRAGABLE = 'SET_DRAGABLE';
export
const
COPY_OR_DELETE_PAGE_INFO
=
'
COPY_OR_DELETE_PAGE_INFO
'
;
export
const
COPY_OR_DELETE_PAGE_INFO
=
'
COPY_OR_DELETE_PAGE_INFO
'
;
export
const
UPDATE_PAGE_INFO
=
'
UPDATE_PAGE_INFO
'
;
export
const
UPDATE_PAGE_INFO
=
'
UPDATE_PAGE_INFO
'
;
export
const
ADD_ELEMENTS
=
'
ADD_ELEMENTS
'
;
export
const
ADD_ELEMENTS
=
'
ADD_ELEMENTS
'
;
export
const
DEL_ELEMENTS
=
'
DEL_ELEMENTS
'
;
export
const
SET_CUR_ELE_INDEX
=
'
SET_CUR_ELE_INDEX
'
;
export
const
SET_CUR_ELE_INDEX
=
'
SET_CUR_ELE_INDEX
'
;
export
const
SET_CUR_CHILD_INDEX
=
'
SET_CUR_CHILD_INDEX
'
;
export
const
SET_CUR_CHILD_INDEX
=
'
SET_CUR_CHILD_INDEX
'
;
export
const
RESET_PAGE_DATA
=
'
RESET_PAGE_DATA
'
;
export
const
RESET_PAGE_DATA
=
'
RESET_PAGE_DATA
'
;
export
const
SET_TEMPLATE_LIST
=
'
SET_TEMPLATE_LIST
'
;
export
const
SET_TEMPLATE_LIST
=
'
SET_TEMPLATE_LIST
'
;
export
const
SET_PAGE_DATA
=
'
SET_PAGE_DATA
'
;
export
const
SET_PAGE_DATA
=
'
SET_PAGE_DATA
'
;
export
const
UPDATE_COMMON_STYLE
=
'
UPDATE_COMMON_STYLE
'
;
export
const
UPDATE_COMMON_STYLE
=
'
UPDATE_COMMON_STYLE
'
;
\ No newline at end of file
export
const
UPDATE_PAGE_STYLE
=
'
UPDATE_PAGE_STYLE
'
;
\ No newline at end of file
app/web/service/eventBus.service.ts
0 → 100644
View file @
e79407ce
import
Vue
from
'
vue
'
;
export
default
new
Vue
();
\ No newline at end of file
app/web/service/http.service.ts
View file @
e79407ce
...
@@ -53,12 +53,14 @@ const instance = axios.create();
...
@@ -53,12 +53,14 @@ const instance = axios.create();
// 请求拦截器
// 请求拦截器
instance
.
interceptors
.
request
.
use
(
instance
.
interceptors
.
request
.
use
(
config
=>
{
config
=>
{
// op-api识别API使用
config
.
headers
[
'
X-Requested-With
'
]
=
'
XMLHttpRequest
'
;
// beforeRequest();
// beforeRequest();
// 发起请求时,取消掉当前正在进行的相同请求
// 发起请求时,取消掉当前正在进行的相同请求
if
(
pending
[
config
.
url
as
string
])
{
if
(
pending
[
config
.
url
as
string
])
{
pending
[
config
.
url
as
string
](
'
取消重复请求
'
);
pending
[
config
.
url
as
string
](
'
取消重复请求
'
);
}
}
config
.
cancelToken
=
new
CancelToken
(
c
=>
(
pending
[
config
.
url
as
string
]
=
c
));
config
.
cancelToken
=
new
CancelToken
(
c
=>
(
pending
[
(
config
.
url
+
JSON
.
stringify
(
config
.
data
))
as
string
]
=
c
));
// 添加token
// 添加token
const
token
=
localStorage
.
get
(
'
token
'
);
const
token
=
localStorage
.
get
(
'
token
'
);
if
(
token
)
{
if
(
token
)
{
...
@@ -118,6 +120,14 @@ instance.interceptors.response.use(
...
@@ -118,6 +120,14 @@ instance.interceptors.response.use(
return
axios
.
request
(
err
.
config
);
return
axios
.
request
(
err
.
config
);
}
}
if
(
err
.
response
)
{
switch
(
err
.
response
.
status
)
{
case
401
:
window
.
location
.
href
=
`
${
window
.
location
.
origin
}
/editor/login`
;
return
;
}
}
// 错误提示
// 错误提示
let
message
=
''
;
let
message
=
''
;
if
(
err
.
response
)
{
if
(
err
.
response
)
{
...
...
app/web/service/qg.service.ts
View file @
e79407ce
...
@@ -21,9 +21,12 @@ import {
...
@@ -21,9 +21,12 @@ import {
Form
,
Form
,
Sticky
,
Sticky
,
Tab
,
Tab
,
Tabs
Tabs
,
Notify
,
Swipe
,
SwipeItem
}
from
'
@qg/cherry-ui
'
;
}
from
'
@qg/cherry-ui
'
;
//
import { KaLoginForm } from '@qg/citrus-ui';
import
{
KaLoginForm
}
from
'
@qg/citrus-ui
'
;
Vue
.
use
(
Button
);
Vue
.
use
(
Button
);
Vue
.
use
(
Image
);
Vue
.
use
(
Image
);
...
@@ -44,7 +47,11 @@ Vue.use(Form);
...
@@ -44,7 +47,11 @@ Vue.use(Form);
// Vue.use(CardList);
// Vue.use(CardList);
// Vue.use(Loading);
// Vue.use(Loading);
// Vue.use(List);
// Vue.use(List);
// Vue.use(Tab);
Vue
.
use
(
Tab
);
// Vue.use(Tabs);
Vue
.
use
(
Tabs
);
// Vue.use(Swipe);
// Vue.use(SwipeItem);
// Vue.use(KaLoginForm);
Vue
.
use
(
KaLoginForm
);
Vue
.
prototype
.
$notify
=
Notify
;
app/web/service/utils.service.ts
View file @
e79407ce
...
@@ -93,3 +93,28 @@ export const getStyle = function(oElement, sName) {
...
@@ -93,3 +93,28 @@ export const getStyle = function(oElement, sName) {
const
result
=
oElement
.
currentStyle
?
oElement
.
currentStyle
[
sName
]
:
getComputedStyle
(
oElement
,
null
)[
sName
];
const
result
=
oElement
.
currentStyle
?
oElement
.
currentStyle
[
sName
]
:
getComputedStyle
(
oElement
,
null
)[
sName
];
return
result
.
includes
(
'
px
'
)
?
result
.
slice
(
0
,
-
2
)
:
result
;
return
result
.
includes
(
'
px
'
)
?
result
.
slice
(
0
,
-
2
)
:
result
;
};
};
export
const
validateType
=
function
(
obj
)
{
const
class2type
=
{};
'
Array Date RegExp Object Error
'
.
split
(
'
'
).
forEach
(
e
=>
{
class2type
[
`[object
${
e
}
]`
]
=
e
.
toLowerCase
();
});
if
(
obj
==
null
)
{
return
String
(
obj
);
}
return
typeof
obj
===
'
object
'
?
class2type
[
Object
.
prototype
.
toString
.
call
(
obj
)]
||
'
object
'
:
typeof
obj
;
};
export
const
transformStyle
=
function
(
styleObj
=
{})
{
// console.log('transformStyle', styleObj);
const
style
=
{};
for
(
const
key
of
Object
.
keys
(
styleObj
))
{
if
(
typeof
styleObj
[
key
]
===
'
number
'
)
{
style
[
key
]
=
`
${(
styleObj
[
key
]
/
37.5
).
toFixed
(
3
)}
rem`
;
}
else
{
style
[
key
]
=
styleObj
[
key
].
includes
(
'
px
'
)
?
`
${(
+
(
styleObj
[
key
].
slice
(
0
,
-
2
))
/
37.5
).
toFixed
(
3
)}
rem`
:
styleObj
[
key
];
}
if
(
key
===
'
backgroundImage
'
&&
style
.
backgroundImage
)
{
style
.
background
=
`url(
${
style
.
backgroundImage
}
) no-repeat 0 0 / cover`
;
}
}
return
style
;
};
package.json
View file @
e79407ce
...
@@ -25,10 +25,11 @@
...
@@ -25,10 +25,11 @@
"
@hubcarl/json-typescript-mapper
"
:
"
^2.0.0
"
,
"
@hubcarl/json-typescript-mapper
"
:
"
^2.0.0
"
,
"
@qg/cherry-ui
"
:
"
^2.18.66
"
,
"
@qg/cherry-ui
"
:
"
^2.18.66
"
,
"
@qg/citrus-ui
"
:
"
0.0.1-alpha.2
"
,
"
@qg/citrus-ui
"
:
"
0.0.1-alpha.2
"
,
"
@riophae/vue-treeselect
"
:
"
^0.4.0
"
,
"
@types/lodash
"
:
"
^4.14.117
"
,
"
@types/lodash
"
:
"
^4.14.117
"
,
"
@types/node
"
:
"
^10.12.0
"
,
"
@types/node
"
:
"
^10.12.0
"
,
"
@types/validator
"
:
"
^4.5.26
"
,
"
@types/validator
"
:
"
^4.5.26
"
,
"
axios
"
:
"
^0.
18
.1
"
,
"
axios
"
:
"
^0.
21
.1
"
,
"
babel-plugin-transform-vue-jsx
"
:
"
^4.0.1
"
,
"
babel-plugin-transform-vue-jsx
"
:
"
^4.0.1
"
,
"
cz-conventional-changelog
"
:
"
^2.1.0
"
,
"
cz-conventional-changelog
"
:
"
^2.1.0
"
,
"
egg
"
:
"
^2.3.0
"
,
"
egg
"
:
"
^2.3.0
"
,
...
@@ -65,6 +66,7 @@
...
@@ -65,6 +66,7 @@
"
tslint-loader
"
:
"
^3.5.3
"
,
"
tslint-loader
"
:
"
^3.5.3
"
,
"
typescript
"
:
"
^3.9.2
"
,
"
typescript
"
:
"
^3.9.2
"
,
"
vue
"
:
"
^2.6.12
"
,
"
vue
"
:
"
^2.6.12
"
,
"
vue-awesome-swiper
"
:
"
^3.1.3
"
,
"
vue-grid-layout
"
:
"
^2.3.11
"
,
"
vue-grid-layout
"
:
"
^2.3.11
"
,
"
vue-property-decorator
"
:
"
^7.2.0
"
,
"
vue-property-decorator
"
:
"
^7.2.0
"
,
"
vue-router
"
:
"
^3.0.1
"
,
"
vue-router
"
:
"
^3.0.1
"
,
...
...
webpack.config.js
View file @
e79407ce
...
@@ -25,22 +25,19 @@ module.exports = {
...
@@ -25,22 +25,19 @@ module.exports = {
},
},
nodeExternals
:
{
nodeExternals
:
{
whitelist
:
[
moduleName
=>
{
whitelist
:
[
moduleName
=>
{
if
(
moduleName
.
includes
(
'
cherry-ui
'
)
||
moduleName
.
includes
(
'
@interactjs
'
))
{
return
/cherry-ui/
.
test
(
moduleName
)
||
/citrus-ui/
.
test
(
moduleName
)
||
/@interactjs/
.
test
(
moduleName
);
console
.
log
(
moduleName
);
}
return
/cherry-ui/
.
test
(
moduleName
)
||
/@interactjs/
.
test
(
moduleName
);
}]
}]
},
},
module
:{
module
:{
rules
:[
rules
:[
{
babel
:
{
{
babel
:
{
include
:
[
resolve
(
'
app/web
'
),
resolve
(
'
node_modules/@qg/cherry-ui
'
),
resolve
(
'
node_modules/@interactjs
'
)],
include
:
[
resolve
(
'
app/web
'
),
resolve
(
'
node_modules/@qg/cherry-ui
'
),
resolve
(
'
node_modules/@interactjs
'
)
,
resolve
(
'
node_modules/@qg/citrus-ui
'
)
],
exclude
:
[]
exclude
:
[]
}
}
},
},
{
{
vue
:
{
vue
:
{
include
:
[
resolve
(
'
app/web
'
),
resolve
(
'
node_modules/@qg/cherry-ui
'
)],
include
:
[
resolve
(
'
app/web
'
),
resolve
(
'
node_modules/@qg/cherry-ui
'
)
,
resolve
(
'
node_modules/@qg/citrus-ui
'
)
],
exclude
:
[]
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