Browse Source

feat: first commit

carver 2 years ago
commit
b8151e747f
100 changed files with 2799 additions and 0 deletions
  1. BIN
      .DS_Store
  2. 2 0
      .gitignore
  3. 3 0
      .mini-ide/project-ide.json
  4. 94 0
      ab_integration_info.txt
  5. 16 0
      antbuilder/core/components/a-footer/index.acss
  6. 5 0
      antbuilder/core/components/a-footer/index.axml
  7. 7 0
      antbuilder/core/components/a-footer/index.js
  8. 3 0
      antbuilder/core/components/a-footer/index.json
  9. 83 0
      antbuilder/core/components/a-tabbar/index.acss
  10. 20 0
      antbuilder/core/components/a-tabbar/index.axml
  11. 24 0
      antbuilder/core/components/a-tabbar/index.js
  12. 6 0
      antbuilder/core/components/a-tabbar/index.json
  13. 8 0
      antbuilder/core/components/activity-ad/index.acss
  14. 11 0
      antbuilder/core/components/activity-ad/index.axml
  15. 15 0
      antbuilder/core/components/activity-ad/index.js
  16. 7 0
      antbuilder/core/components/activity-ad/index.json
  17. 12 0
      antbuilder/core/components/advert-show/index.acss
  18. 25 0
      antbuilder/core/components/advert-show/index.axml
  19. 56 0
      antbuilder/core/components/advert-show/index.js
  20. 7 0
      antbuilder/core/components/advert-show/index.json
  21. 38 0
      antbuilder/core/components/advert-wheel-card/index.acss
  22. 35 0
      antbuilder/core/components/advert-wheel-card/index.axml
  23. 19 0
      antbuilder/core/components/advert-wheel-card/index.js
  24. 7 0
      antbuilder/core/components/advert-wheel-card/index.json
  25. 52 0
      antbuilder/core/components/advert-wheel-card/index.sjs
  26. 9 0
      antbuilder/core/components/advert-wheel/index.acss
  27. 26 0
      antbuilder/core/components/advert-wheel/index.axml
  28. 20 0
      antbuilder/core/components/advert-wheel/index.js
  29. 6 0
      antbuilder/core/components/advert-wheel/index.json
  30. 50 0
      antbuilder/core/components/advert-wheel/index.sjs
  31. 0 0
      antbuilder/core/components/anxinchong/index.acss
  32. 12 0
      antbuilder/core/components/anxinchong/index.axml
  33. 74 0
      antbuilder/core/components/anxinchong/index.js
  34. 6 0
      antbuilder/core/components/anxinchong/index.json
  35. 41 0
      antbuilder/core/components/button-auth/index.acss
  36. 31 0
      antbuilder/core/components/button-auth/index.axml
  37. 68 0
      antbuilder/core/components/button-auth/index.js
  38. 3 0
      antbuilder/core/components/button-auth/index.json
  39. 51 0
      antbuilder/core/components/button-auth/index.sjs
  40. 56 0
      antbuilder/core/components/city-tab/index.acss
  41. 36 0
      antbuilder/core/components/city-tab/index.axml
  42. 51 0
      antbuilder/core/components/city-tab/index.js
  43. 9 0
      antbuilder/core/components/city-tab/index.json
  44. 4 0
      antbuilder/core/components/component-card-wrapper/index.acss
  45. 11 0
      antbuilder/core/components/component-card-wrapper/index.axml
  46. 8 0
      antbuilder/core/components/component-card-wrapper/index.js
  47. 6 0
      antbuilder/core/components/component-card-wrapper/index.json
  48. 25 0
      antbuilder/core/components/component-card-wrapper/index.sjs
  49. 59 0
      antbuilder/core/components/consult-list/index.acss
  50. 29 0
      antbuilder/core/components/consult-list/index.axml
  51. 14 0
      antbuilder/core/components/consult-list/index.js
  52. 6 0
      antbuilder/core/components/consult-list/index.json
  53. 8 0
      antbuilder/core/components/consult-service/index.acss
  54. 11 0
      antbuilder/core/components/consult-service/index.axml
  55. 16 0
      antbuilder/core/components/consult-service/index.js
  56. 7 0
      antbuilder/core/components/consult-service/index.json
  57. 9 0
      antbuilder/core/components/contact-button/index.acss
  58. 10 0
      antbuilder/core/components/contact-button/index.axml
  59. 20 0
      antbuilder/core/components/contact-button/index.js
  60. 3 0
      antbuilder/core/components/contact-button/index.json
  61. 25 0
      antbuilder/core/components/core-container/index.acss
  62. 157 0
      antbuilder/core/components/core-container/index.axml
  63. 47 0
      antbuilder/core/components/core-container/index.js
  64. 47 0
      antbuilder/core/components/core-container/index.json
  65. 74 0
      antbuilder/core/components/core-container/index.sjs
  66. 57 0
      antbuilder/core/components/custom-form/index.acss
  67. 18 0
      antbuilder/core/components/custom-form/index.axml
  68. 172 0
      antbuilder/core/components/custom-form/index.js
  69. 6 0
      antbuilder/core/components/custom-form/index.json
  70. 36 0
      antbuilder/core/components/custom-swiper/index.acss
  71. 28 0
      antbuilder/core/components/custom-swiper/index.axml
  72. 58 0
      antbuilder/core/components/custom-swiper/index.js
  73. 3 0
      antbuilder/core/components/custom-swiper/index.json
  74. 24 0
      antbuilder/core/components/dynamic-chars/index.acss
  75. 9 0
      antbuilder/core/components/dynamic-chars/index.axml
  76. 8 0
      antbuilder/core/components/dynamic-chars/index.js
  77. 3 0
      antbuilder/core/components/dynamic-chars/index.json
  78. 53 0
      antbuilder/core/components/el-list/index.acss
  79. 31 0
      antbuilder/core/components/el-list/index.axml
  80. 21 0
      antbuilder/core/components/el-list/index.js
  81. 7 0
      antbuilder/core/components/el-list/index.json
  82. 21 0
      antbuilder/core/components/enter-ad/index.acss
  83. 13 0
      antbuilder/core/components/enter-ad/index.axml
  84. 36 0
      antbuilder/core/components/enter-ad/index.js
  85. 6 0
      antbuilder/core/components/enter-ad/index.json
  86. 102 0
      antbuilder/core/components/equal-division/index.acss
  87. 44 0
      antbuilder/core/components/equal-division/index.axml
  88. 59 0
      antbuilder/core/components/equal-division/index.js
  89. 9 0
      antbuilder/core/components/equal-division/index.json
  90. 26 0
      antbuilder/core/components/float-button/index.acss
  91. 6 0
      antbuilder/core/components/float-button/index.axml
  92. 42 0
      antbuilder/core/components/float-button/index.js
  93. 5 0
      antbuilder/core/components/float-button/index.json
  94. 49 0
      antbuilder/core/components/footer/index.acss
  95. 21 0
      antbuilder/core/components/footer/index.axml
  96. 19 0
      antbuilder/core/components/footer/index.js
  97. 4 0
      antbuilder/core/components/footer/index.json
  98. 65 0
      antbuilder/core/components/four-pic/index.acss
  99. 22 0
      antbuilder/core/components/four-pic/index.axml
  100. 16 0
      antbuilder/core/components/four-pic/index.js

BIN
.DS_Store


+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+node_modules
+package-lock.json

+ 3 - 0
.mini-ide/project-ide.json

@@ -0,0 +1,3 @@
+{
+  "enableLegacyRemoteDebug": false
+}

+ 94 - 0
ab_integration_info.txt

@@ -0,0 +1,94 @@
+core-antbuilder version: 4.16.9
+components
+	null@null    OK
+	certListComponent@1.1.0    OK
+	medicareQueryMyComponent@1.1.0    OK
+	hospitalMainServicesComponent@1.0.0    OK
+	b2bMiniStore@1.0.0    OK
+	ownerGetCardFail@1.1.0    OK
+	healthCardComponent@1.1.0    OK
+	medicareQueryComponent@1.1.0    OK
+	hospitalcommonlyServicesComponent@1.0.0    OK
+	null@null    OK
+	null@null    OK
+	null@null    OK
+	ScenicInfo@1.1.0    OK
+	inpatientMock@1.0.0    OK
+	hospitalCardRegistrationComponent@1.1.0    OK
+	nucleicProject@1.0.0    OK
+	seckillActivity@1.0.0    OK
+	ScenicTouristList@1.1.0    OK
+	hospitalCardManageComponent@1.1.0    OK
+	null@null    OK
+	certDetailComponent@1.1.0    OK
+	zmGoComponent@1.0.0    OK
+	null@null    OK
+	nucleicMock@1.0.0    OK
+	hospitalSelectDepartmentComponent@1.0.0    OK
+	null@null    OK
+	null@null    OK
+	null@null    OK
+	visitScanComponent@1.1.0    OK
+	hospitalCardChargeComponent@1.1.0    OK
+	null@null    OK
+	hospitalInpatientTabNew@1.0.0    OK
+	hospitalOperationInformationComponent@1.0.0    OK
+	getCoupons@1.0.0    OK
+	advertiseComponent@1.1.0    OK
+	ownerGetCard@1.1.0    OK
+	inpatientIndexTab@1.0.0    OK
+	ScenicOrderDetail@1.1.0    OK
+	null@null    OK
+	hospitalUserCenterComponent@1.0.0    OK
+	null@null    OK
+	null@null    OK
+	b2bMiniCouponComponent@1.0.0    OK
+	null@null    OK
+	hospitalHeadertComponent@1.0.0    OK
+	null@null    OK
+	explosiveComponent@1.0.0    OK
+	null@null    OK
+	slyderAdventures@1.0.0    OK
+	hospitalMedicalInformationComponent@1.0.0    OK
+	hospitalReportComponent@1.1.0    OK
+	null@null    OK
+	luckyDrawComponent@1.0.0    OK
+	visitUserComponent@1.1.0    OK
+	null@null    OK
+	visitRegistrationComponent@1.1.0    OK
+	null@null    OK
+	hospitalPaymentComponent@1.1.0    OK
+	scratchActivity@1.0.0    OK
+	TicketReserve@1.1.0    OK
+	ScenicTouristManage@1.1.0    OK
+	hospitalDepartmentIntroductionComponent@1.0.0    OK
+	ownerGetCardNew@1.1.0    OK
+	null@null    OK
+	mallOrderDetail@1.0.0    OK
+	hospitalTopBrandComponent@1.0.0    OK
+	null@null    OK
+	certReceiveComponent@1.1.0    OK
+	null@null    OK
+	hospitalConsultingServiceComponent@1.0.0    OK
+	ScenicOrderList@1.1.0    OK
+	mallStoreComponent@1.0.0    OK
+	hospitalRegistrationEntryComponent@1.0.0    OK
+	receiveAddressComponent@1.0.0    OK
+	hospitalCardTipsComponent@1.1.0    OK
+	null@null    OK
+	null@null    OK
+	null@null    OK
+	null@null    OK
+	mallOrderList@1.0.0    OK
+	null@null    OK
+	null@null    OK
+	hospitalProxyTempletes@1.0.0    OK
+	null@null    OK
+	b2bMiniStoreComponent@1.0.0    OK
+	hospitalCardComponent@1.1.0    OK
+	merchantMapComponent@1.1.0    OK
+	null@null    OK
+	null@null    OK
+	hospitalCardServiceComponent@1.1.0    OK
+	mallGoodsList@1.0.0    OK
+	ScenicList@1.1.0    OK

+ 16 - 0
antbuilder/core/components/a-footer/index.acss

@@ -0,0 +1,16 @@
+.a-footer {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 60rpx 0 34rpx;
+}
+.a-footer text {
+  font-size: 26rpx;
+  color: #ccc;
+}
+.a-footer .line {
+  width: 80rpx;
+  height: 2rpx;
+  background: #ddd;
+  margin: 25rpx;
+}

+ 5 - 0
antbuilder/core/components/a-footer/index.axml

@@ -0,0 +1,5 @@
+<view class="a-footer" a:if="{{show}}">
+  <text class="line"></text>
+  <text>我是有底线的</text>
+  <text class="line"></text>
+</view>

+ 7 - 0
antbuilder/core/components/a-footer/index.js

@@ -0,0 +1,7 @@
+Component({
+  props: {
+    show: false,
+  },
+  methods: {
+  },
+});

+ 3 - 0
antbuilder/core/components/a-footer/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 83 - 0
antbuilder/core/components/a-tabbar/index.acss

@@ -0,0 +1,83 @@
+.tabbar-container {
+  position: relative;
+}
+.tabbar-box {
+  display: flex;
+  position: sticky;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  flex-flow: row nowrap;
+  justify-content: space-between;
+  background: #fff;
+  box-sizing: border-box;
+  padding-bottom: constant(safe-area-inset-bottom);
+  padding-bottom: env(safe-area-inset-bottom);
+  box-shadow: 0 1px 0.08rem 0 rgba(153, 153, 153, 0.2);
+}
+.tabbar-box.fixed {
+  z-index: 1000;
+  position: fixed;
+}
+.tabbar-box::before {
+  content: " ";
+  position: absolute;
+  height: 1px;
+  background-color: #f0f0f0;
+  left: 0;
+  right: 0;
+  top: 0;
+  transform: scaleY(0.5);
+}
+.tabbar-box .item-tab {
+  display: flex;
+  padding-top: 14rpx;
+  padding-bottom: 14rpx;
+  flex: 1;
+  flex-flow: column nowrap;
+  align-items: center;
+  justify-content: space-between;
+}
+.tabbar-box .item-tab .form {
+  width: 100%;
+  height: 100%;
+}
+.tabbar-box .item-tab .bottom_active {
+  height: 10rpx;
+  width: 100%;
+  background-color: #5e5a5a;
+  border-radius: 5rpx;
+  margin-top: 40rpx;
+}
+.tabbar-box .item-tab.tab_active .item_name {
+  color: #108ee9;
+}
+.tabbar-box .item-tab .item-icon-box {
+  height: 100%;
+  display: flex;
+  flex-flow: column nowrap;
+  align-items: center;
+  font-size: 20rpx;
+  line-height: 28rpx;
+  color: #ccc;
+}
+.tabbar-box .item-tab .item_icon {
+  width: 44rpx;
+  height: 44rpx;
+}
+.tabbar-container.circle .tabbar-box {
+  padding-bottom: 0;
+  width: 90%;
+  margin: auto;
+  border-radius: 100rpx;
+  bottom: constant(safe-area-inset-bottom);
+  bottom: env(safe-area-inset-bottom);
+  box-shadow: 0 1px 0.5rem 0 rgba(153, 153, 153, 0.2);
+}
+.tabbar-container.circle .tabbar-box .item-tab {
+  padding-top: 16rpx;
+  padding-bottom: 16rpx;
+}
+.tabbar-container.circle .tabbar-box:before {
+  display: none;
+}

+ 20 - 0
antbuilder/core/components/a-tabbar/index.axml

@@ -0,0 +1,20 @@
+<view class="tabbar-container{{cardMode?' '+cardMode:''}}" a:if="{{list && list.length > 0}}">
+  <!-- <view class="tabbar-space"></view> -->
+  <view class="tabbar-box {{className}}">
+    <view a:for="{{list}}" className="item-tab {{index === activeIndex ? 'tab_active' : ''}}" >
+      <button-auth
+      item="{{...item, index, activeIndex, from: 'tabBar', templateUUID}}"
+      formClass="form"
+      needCallBack="{{false}}"
+      onCallBack="handleTabBarChange"
+      >
+        <view class="item-icon-box">
+          <image
+            class="item_icon"
+            src="{{index === activeIndex ? (item.extInfo.lightIcon.length === 32 ? imgSrcPrefix + item.extInfo.lightIcon : item.extInfo.lightIcon) : (item.extInfo.inactiveIcon.length === 32 ? imgSrcPrefix + item.extInfo.inactiveIcon: item.extInfo.inactiveIcon)}}" />
+          <text number-of-lines="1" class="item_name">{{item.title}}</text>
+        </view>
+      </button-auth>
+    </view>
+  </view>
+</view>

+ 24 - 0
antbuilder/core/components/a-tabbar/index.js

@@ -0,0 +1,24 @@
+import { connect } from 'herculex';
+
+const app = getApp();
+Component(connect({
+  mapStateToProps: {
+    activeIndex: state => state.activeIndex,
+    list: state => (state.$global.pageConfig[state.templateUUID] || {}).tabbar || [],
+    templateUUID: state => state.templateUUID,
+  },
+})({
+  props: {
+    className: 'fixed',
+    cardMode: '',
+  },
+  data: {
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+  },
+  methods: {
+    async handleTabBarChange(pageUuid) {
+      // 改变当前componnentData,改变activeIndex
+      await this.dispatch('startInTabBar', { pageUuid });
+    },
+  },
+}));

+ 6 - 0
antbuilder/core/components/a-tabbar/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "button-auth": "../button-auth/index"
+  }
+}

+ 8 - 0
antbuilder/core/components/activity-ad/index.acss

@@ -0,0 +1,8 @@
+.activity-ad {
+  padding: 0 24rpx;
+  background: #fff;
+  overflow: hidden;
+}
+.activity-ad .service-market-activity-container {
+  padding-top: 24rpx;
+}

+ 11 - 0
antbuilder/core/components/activity-ad/index.axml

@@ -0,0 +1,11 @@
+<view class="activity-ad" a:if="{{componentData && componentData.serviceList && componentData.serviceList.length}}">
+  <view class="activity-type">
+    <service-title 
+      class="title"
+      imgSrcPrefix="{{imgSrcPrefix}}"
+      componentData="{{componentData}}"/>
+    <service-market-activity
+      imgSrcPrefix="{{imgSrcPrefix}}"
+      serviceList="{{componentData.serviceList}}"/>
+  </view>
+</view>

+ 15 - 0
antbuilder/core/components/activity-ad/index.js

@@ -0,0 +1,15 @@
+import { connect } from 'herculex';
+
+const app = getApp();
+Component(connect({})({
+  data: {
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+  },
+  props: {
+    componentData: {},
+  },
+  didMount() {
+  },
+  methods: {
+  },
+}));

+ 7 - 0
antbuilder/core/components/activity-ad/index.json

@@ -0,0 +1,7 @@
+{
+  "component": true,
+  "usingComponents": {
+    "service-title": "../service-title/index",
+    "service-market-activity": "../service-market-activity/index"
+  }
+}

+ 12 - 0
antbuilder/core/components/advert-show/index.acss

@@ -0,0 +1,12 @@
+.advert-show-container .box {
+  display: flex;
+  justify-content: center;
+  width: auto;
+  height: auto;
+  max-width: 80%;
+  max-height: 600rpx;
+  background-color: transparent;
+}
+.advert-show-container .box .am-modal-show {
+  position: relative;
+}

+ 25 - 0
antbuilder/core/components/advert-show/index.axml

@@ -0,0 +1,25 @@
+<view
+  class="advert-show-container"
+  a:if="{{componentData.serviceList}}"
+>
+  <modal
+    show="{{show}}"
+    advice="{{true}}"
+    topImageSize="{{lg}}"
+    className="box"
+    showClose="true"
+    zIndex="{{9999}}"
+    onModalClose="onModalClose"
+  >
+    <button-auth item="{{componentData.serviceList[0]}}">
+      <image
+        mode="widthFix"
+        style="width: auto;height:none;"
+        src="{{componentData.serviceList[0].icon.length == 32 ? imgSrcPrefix + componentData.serviceList[0].icon : componentData.serviceList[0].icon}}"
+      />
+    </button-auth>
+  </modal>
+  <!-- <my-modal myurl="{{componentData.serviceList[0].icon.length == 32 ? imgSrcPrefix + componentData.serviceList[0].icon : componentData.serviceList[0].icon}}"> -->
+
+  <!-- </my-modal> -->
+</view>

+ 56 - 0
antbuilder/core/components/advert-show/index.js

@@ -0,0 +1,56 @@
+import { connect } from 'herculex';
+import { setStorage } from '../../utils';
+
+const app = getApp();
+Component(connect({
+  mapStateToProps: {
+    pageUuid: state => state.pageUuid,
+  },
+})({
+  props: {
+    componentData: {},
+  },
+  data: {
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+    show: false,
+    key: 'ADVERT_SHOW',
+  },
+  didMount() {
+    this.init();
+  },
+  methods: {
+    async init() {
+      const { key, pageUuid } = this.data;
+      const {
+        serviceList,
+        componentExtInfo,
+      } = this.props.componentData;
+      let showRate = componentExtInfo.showRate || 0;
+      showRate = parseInt(showRate);
+      const service = serviceList[0];
+      let { data } = my.getStorageSync({ key }) || {};
+      let rate = 0;
+      if (showRate < 0) return;
+      if (data && data[pageUuid]) {
+        rate = data[pageUuid].serviceUUID === service.serviceUUID ? data[pageUuid].showRate : 0;
+        if (!data[pageUuid].show || (rate >= showRate && showRate !== 0)) return;
+      }
+      this.setData({
+        show: true,
+      });
+      rate += 1;
+      data = {
+        ...data,
+        [pageUuid]: {
+          show: false,
+          showRate: rate,
+          serviceUUID: service.serviceUUID,
+        },
+      };
+      await setStorage(key, data);
+    },
+    onModalClose() {
+      this.setData({ show: false });
+    },
+  },
+}));

+ 7 - 0
antbuilder/core/components/advert-show/index.json

@@ -0,0 +1,7 @@
+{
+  "component": true,
+  "usingComponents": {
+    "modal": "mini-ali-ui/es/modal/index",
+    "button-auth": "../button-auth/index"
+  }
+}

+ 38 - 0
antbuilder/core/components/advert-wheel-card/index.acss

@@ -0,0 +1,38 @@
+.advert-wheel-card .advert-card-banner {
+  background-color: transparent;
+}
+.advert-wheel-card .advert-card-item,
+.advert-wheel-card .advert-card-item-content {
+  display: block;
+}
+.advert-wheel-card .advert-card-item {
+  background-color: #fff;
+}
+.advert-wheel-card .advert-card-item.circle {
+  border-radius: 12rpx;
+  overflow: hidden;
+}
+.advert-wheel-card .advert-card-item.circle .advert-card-item-content {
+  border-radius: 12rpx;
+}
+.advert-wheel-card .advert-card-item-wrapper {
+  padding-bottom: 16rpx;
+}
+.advert-wheel-card .advert-card-item-content {
+  overflow: hidden;
+}
+.advert-wheel-card .advert-card-image {
+  border-radius: 0;
+}
+.advert-wheel-card .advert-card-desc {
+  padding: 28rpx 24rpx;
+}
+.advert-wheel-card .card-service-title {
+  font-size: 32rpx;
+  font-size: 800;
+}
+.advert-wheel-card .desc-content {
+  color: #666;
+  font-size: 26rpx;
+  margin-top: 12rpx;
+}

+ 35 - 0
antbuilder/core/components/advert-wheel-card/index.axml

@@ -0,0 +1,35 @@
+<import-sjs from="./index.sjs" name="utils" />
+<view
+  class="advert-wheel-card"
+  a:if="{{ utils.hasService(componentData) }}"
+>
+    <custom-swiper
+      circular="{{circular}}"
+      autoplay="{{autoplay}}"
+      swiperClass="advert-card-banner"
+      images="{{ utils.getServiceList(componentData) }}"
+      indicatorDots="{{componentData.serviceList.length > 1}}"
+      interval="{{utils.getInterval(componentData,interval)}}"
+    >
+      <view slot-scope="props" class="advert-card-item-wrapper">
+        <button-auth
+          class="advert-card-item-content" item="{{props.data.item}}"
+          formClass="advert-card-item{{utils.getItemCardMode(componentData)}}"
+        >
+          <image
+            class="advert-card-image"
+            style="{{utils.getStyle(componentData)}}"
+            src="{{utils.getFullUrl(props.data.item.icon,imgSrcPrefix)}}"
+          />
+          <view class="advert-card-desc">
+            <view class="card-service-title">
+              {{props.data.item.name}}
+            </view>
+            <view class="desc-content">
+              {{props.data.item.serviceDesc}}
+            </view>
+          </view>
+        </button-auth>
+      </view>
+    </custom-swiper>
+</view>

+ 19 - 0
antbuilder/core/components/advert-wheel-card/index.js

@@ -0,0 +1,19 @@
+import { connect } from 'herculex';
+
+const app = getApp();
+Component(connect({})({
+  data: {
+    indicatorDots: true,
+    autoplay: true,
+    interval: 5,
+    circular: true,
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+  },
+  props: {
+    componentData: {},
+  },
+  didMount() {
+  },
+  methods: {
+  },
+}));

+ 7 - 0
antbuilder/core/components/advert-wheel-card/index.json

@@ -0,0 +1,7 @@
+{
+  "component": true,
+  "usingComponents": {
+    "button-auth": "../button-auth/index",
+    "custom-swiper": "../custom-swiper/index"
+  }
+}

+ 52 - 0
antbuilder/core/components/advert-wheel-card/index.sjs

@@ -0,0 +1,52 @@
+function replacePx(val) {
+  return +(val || '').replace('px', '');
+}
+
+function getStyle(componentData) {
+  const styles = [];
+
+  const { componentExtInfo } = componentData;
+  const { height } = componentExtInfo || {};
+
+  styles.push(`height:${(replacePx(height) || 260) / 50}rem`);
+
+  return styles.join(';');
+}
+
+function getServiceList(componentData) {
+  const { serviceList = [] } = componentData || {};
+  return serviceList || [];
+}
+
+function hasService(componentData) {
+  return !!getServiceList(componentData).length;
+}
+
+function getInterval(componentData, interval) {
+  const { componentExtInfo } = componentData;
+  const { advertRate = 0 } = componentExtInfo || {};
+  return (+advertRate || interval) * 1000;
+}
+
+function getFullUrl(url, prefix) {
+  return url.length === 32 ? `${prefix}${url}` : url;
+}
+
+function getItemCardMode(componentData) {
+  const {
+    componentExtInfo,
+  } = componentData;
+  const {
+    cardMode = '',
+  } = componentExtInfo;
+  return cardMode ? ` ${cardMode}` : '';
+}
+
+export default {
+  getFullUrl,
+  getStyle,
+  hasService,
+  getItemCardMode,
+  getInterval,
+  getServiceList,
+};

+ 9 - 0
antbuilder/core/components/advert-wheel/index.acss

@@ -0,0 +1,9 @@
+.advert-wheel {
+  overflow: hidden;
+}
+.advert-wheel .advert-banner {
+  height: 100%;
+}
+.advert-wheel .advert-banner .advert-img {
+  width: 100%;
+}

+ 26 - 0
antbuilder/core/components/advert-wheel/index.axml

@@ -0,0 +1,26 @@
+<import-sjs from="./index.sjs" name="utils" />
+<view
+  class="advert-wheel"
+  style="{{ utils.getStyle(componentData) }}"
+  a:if="{{ utils.hasService(componentData) }}"
+>
+    <swiper
+      circular="{{circular}}"
+      class="advert-banner"
+      autoplay="{{autoplay}}"
+      indicator-dots="{{componentData.serviceList.length > 1}}"
+      interval="{{utils.getInterval(componentData,interval)}}"
+    >
+      <block a:for="{{ utils.getServiceList(componentData) }}">
+        <swiper-item class="swiperItem" key="{{index}}">
+          <button-auth className="advert-img" item="{{item}}">
+            <image
+              class="advert-img"
+              style="{{utils.getStyle(componentData)}}"
+              src="{{ utils.getFullUrl(item.icon,imgSrcPrefix) }}"
+            />
+          </button-auth>
+        </swiper-item>
+      </block>
+    </swiper>
+</view>

+ 20 - 0
antbuilder/core/components/advert-wheel/index.js

@@ -0,0 +1,20 @@
+import { connect } from 'herculex';
+
+const app = getApp();
+Component(connect({})({
+  data: {
+    indicatorDots: true,
+    autoplay: true,
+    interval: 5,
+    circular: true,
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+  },
+  props: {
+    componentData: {},
+    showFirst: true,
+  },
+  didMount() {
+  },
+  methods: {
+  },
+}));

+ 6 - 0
antbuilder/core/components/advert-wheel/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "button-auth": "../button-auth/index"
+  }
+}

+ 50 - 0
antbuilder/core/components/advert-wheel/index.sjs

@@ -0,0 +1,50 @@
+function replacePx(val) {
+  return +(val || '').replace('px', '');
+}
+
+function getStyle(componentData) {
+  const styles = [];
+
+  const {
+    componentExtInfo,
+  } = componentData;
+
+  const { height } = componentExtInfo || {};
+
+  styles.push(`height:${(replacePx(height) || 130) / 50}rem`);
+
+  return styles.join(';');
+}
+
+function getServiceList(componentData) {
+  const {
+    serviceList = [],
+  } = componentData || {};
+  return serviceList;
+}
+
+function hasService(componentData) {
+  return !!getServiceList(componentData).length;
+}
+
+function getInterval(componentData, interval) {
+  const {
+    componentExtInfo,
+  } = componentData;
+  const {
+    advertRate = 0,
+  } = componentExtInfo || {};
+  return (+advertRate || interval) * 1000;
+}
+
+function getFullUrl(url, prefix) {
+  return url.length === 32 ? `${prefix}${url}` : url;
+}
+
+export default {
+  getFullUrl,
+  getStyle,
+  hasService,
+  getInterval,
+  getServiceList,
+};

+ 0 - 0
antbuilder/core/components/anxinchong/index.acss


+ 12 - 0
antbuilder/core/components/anxinchong/index.axml

@@ -0,0 +1,12 @@
+<view>
+    <component 
+      a:if="{{isReady}}" 
+      is="dynamic-plugin://{{pluginAppId}}/{{pluginComponent}}" 
+      
+      pid="{{pid}}"
+      scene="THREE_PARTY_MIMI_PROGRAMS" 
+      shopId="{{shopId}}"
+      isWrapped="{{wrap == 'Y'}}"
+    >
+    </component>
+</view>

+ 74 - 0
antbuilder/core/components/anxinchong/index.js

@@ -0,0 +1,74 @@
+Component({
+  props: {
+    componentData: {},
+  },
+  data: {
+    isReady: false,
+    pluginAppId: '',
+    pluginComponent: '',
+    pluginVersion: '',
+
+    pid: '',
+    shopId: '',
+    wrap: 'N',
+  },
+
+  didMount() {
+    const {
+      componentData: { componentExtInfo },
+    } = this.props;
+    // const { query } = my.getLaunchOptionsSync() || {};
+    const {
+      plgId,
+      plgComp,
+      plgVer,
+      pid,
+      shopId,
+      wrap,
+      wrapTitle,
+    } = componentExtInfo;
+    this.setData({
+      pluginAppId: plgId,
+      pluginComponent: plgComp,
+      pluginVersion: plgVer,
+
+      pid,
+      shopId,
+      wrap,
+      wrapTitle,
+    });
+    this.loadPlugin();
+  },
+
+  methods: {
+    loadPlugin() {
+      const { pluginVersion, pluginAppId, pluginComponent } = this.data;
+
+      const {
+        componentData: { componentType },
+      } = this.props;
+      console.log(
+        `加载插件, 开始 ${pluginAppId}, ${componentType} ${pluginComponent}`,
+      );
+      try {
+        my.loadPlugin({
+          plugin: `${pluginAppId}@${pluginVersion}`,
+          success: () => {
+            this.setData({
+              isReady: true,
+            });
+          },
+          fail: () => {
+            console.log(
+              `加载插件失败, id: ${pluginAppId}, type: ${componentType}`,
+            );
+          },
+        });
+      } catch (e) {
+        throw new Error(
+          'plugin must be pluginAppId and pluginVersion, please configure on AB saas!',
+        );
+      }
+    },
+  },
+});

+ 6 - 0
antbuilder/core/components/anxinchong/index.json

@@ -0,0 +1,6 @@
+{
+    "component": true,
+    "usingComponents": {
+    }
+  }
+  

+ 41 - 0
antbuilder/core/components/button-auth/index.acss

@@ -0,0 +1,41 @@
+.container {
+  min-height: 100vh;
+}
+.container .loading-con {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+.container .loading-image {
+  width: 44rpx;
+  height: 72rpx;
+  margin-bottom: 12rpx;
+  animation: loading 1s linear infinite;
+}
+.container .loading-text {
+  color: #999;
+  font-size: 24rpx;
+}
+@keyframes loading {
+  0% {
+    transform: scale(0.8);
+  }
+  25% {
+    transform: scale(1);
+  }
+  50% {
+    transform: scale(0.8);
+  }
+  75% {
+    transform: scale(1);
+  }
+  100% {
+    transform: scale(0.8);
+  }
+}

+ 31 - 0
antbuilder/core/components/button-auth/index.axml

@@ -0,0 +1,31 @@
+<import-sjs from="./index.sjs" name="utils" />
+<form onSubmit="onSubmit" report-submit="{{true}}" class="{{formClass}}">
+  <button
+    style="{{style}}"
+    formType="submit"
+    hover-class="none"
+    data-item="{{item}}"
+    onError="onAuthError"
+    open-type="getAuthorize"
+    onGetAuthorize="onGetAuthorize"
+    class="clear-button {{className}}"
+    scope="{{ utils.getScope(item,userInfo) }}"
+    a:if="{{ utils.showButton(item,userInfo) }}"
+    data-scope="{{ utils.getScope(item,userInfo) }}"
+  >
+    <slot />
+  </button>
+  <button
+    a:else
+    style="{{style}}"
+    formType="submit"
+    hover-class="none"
+    data-item="{{item}}"
+    onTap="onClickItem"
+    class="clear-button  {{className}}"
+  >
+    <slot />
+  </button>
+</form>
+
+

+ 68 - 0
antbuilder/core/components/button-auth/index.js

@@ -0,0 +1,68 @@
+import { connect } from 'herculex';
+import { navigateTo } from '../../utils';
+import { getIn } from 'herculex/dist/utils/manipulate';
+
+const fn = () => null;
+Component(connect({
+  mapStateToProps: {
+    // 取global中的数据
+    scopes: state => state.$global.scopes,
+    userInfo: state => state.$global.userInfo,
+  },
+})({
+  props: {
+    className: '', // 自定义样式
+    formClass: '',
+    item: {},
+    style: '',
+    onCallBack2: fn,
+    onCallBack: fn,
+    onError: fn,
+    needLogin: false, // 是否展示登录形式的按钮
+    needCallBack: false, // 单独处理
+    needHandleError: false, // 单独处理
+  },
+  data: {},
+  didUpdate() {
+  },
+  methods: {
+    onSubmit(e) {
+      const formId = getIn(e, ['detail', 'formId'], '');
+      this.commit('$global:updateFormId', { formId });
+    },
+    async onClickItem(e) {
+      await this.onJmp(e);
+    },
+    async onGetAuthorize(e) {
+      await this.onJmp(e);
+    },
+    /* 跳转逻辑 */
+    async onJmp(e) {
+      let customerCheckInPage = null;
+      const { needCallBack, onCallBack } = this.props;
+      const item = getIn(e, ['target', 'dataset', 'item'], {});
+      const currentScope = getIn(e, ['target', 'dataset', 'scope'], null);
+      const { index = 'N', activeIndex = 'N', accessMode } = item;
+      const isTabBar = index !== 'N' && activeIndex !== 'N';
+      /* 如果是tabBar的时候,防止重复点击 */
+      if (isTabBar && activeIndex === index) return;
+      /* 如果是会员卡,需要去检查会员卡 */
+      if (accessMode.customer && item.from !== 'webview') {
+        customerCheckInPage = this.dispatch.bind(this, 'customerCheck');
+      }
+      const jumpPara = {
+        ...item,
+        currentScope,
+        isToService: true,
+        customerCheckInPage,
+        handleTabBarChange: onCallBack,
+      };
+      if (needCallBack) return onCallBack(item);
+      navigateTo.call(this, jumpPara);
+    },
+    onAuthError() {
+      const { needHandleError, onError } = this.props;
+      if (needHandleError) onError();
+    },
+  },
+}));

+ 3 - 0
antbuilder/core/components/button-auth/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 51 - 0
antbuilder/core/components/button-auth/index.sjs

@@ -0,0 +1,51 @@
+function getAccessMode(accessMode) {
+  if (typeof accessMode !== 'string') return accessMode;
+  const oldMode = {
+    none: { none: true },
+    cert: { cert: true },
+    login: { login: true },
+    identity: { identity: true },
+    realName: { realName: true },
+    customer: { customer: true },
+  };
+  return oldMode[accessMode] || {};
+}
+
+function showButton(item, userInfo) {
+  const { accessMode = '' } = item || {};
+  const {
+    phone,
+    isLogin,
+  } = userInfo || {};
+  const {
+    login,
+    phoneNumber,
+  } = getAccessMode(accessMode);
+  /* 获取基础信息 */
+  if (login && !isLogin) {
+    return true;
+  }
+  /* 如果是获取手机号码 */
+  if (phoneNumber && !phone) {
+    return true;
+  }
+}
+
+function getScope(item, userInfo) {
+  const { accessMode = '' } = item || {};
+  const {
+    phone,
+    isLogin,
+  } = userInfo || {};
+  const {
+    login,
+    phoneNumber,
+  } = getAccessMode(accessMode);
+  if (login && !isLogin) return 'userInfo';
+  if (phoneNumber && !phone) return 'phoneNumber';
+}
+
+export default {
+  getScope,
+  showButton,
+};

+ 56 - 0
antbuilder/core/components/city-tab/index.acss

@@ -0,0 +1,56 @@
+.tab-content {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 300px;
+}
+.citylist-container .am-list-content {
+  color: #333;
+  font-size: 28rpx;
+}
+.page-box {
+  position: fixed;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  display: flex;
+  justify-content: flex-start;
+}
+.class-left {
+  width: 220rpx;
+  height: 100%;
+  background: #f5f5f5;
+}
+.class-left .cate-list {
+  height: 110rpx;
+  line-height: 110rpx;
+  font-size: 28rpx;
+  color: #333;
+  text-align: center;
+  border-left: 8rpx solid transparent;
+}
+.class-left .cate-list.on {
+  color: #108ee9;
+  border-color: #108ee9;
+  background: #fff;
+}
+.class-right {
+  width: 530rpx;
+  height: 100%;
+  background: #fff;
+}
+.class-right .cate-list {
+  font-size: 28rpx;
+  color: #333;
+  letter-spacing: 0.48rpx;
+  height: 110rpx;
+  line-height: 110rpx;
+  padding-left: 82rpx;
+}
+.class-right .cate-list:hover {
+  color: #108ee9;
+}
+.class-right .cate-list.childOn {
+  color: #108ee9;
+}

+ 36 - 0
antbuilder/core/components/city-tab/index.axml

@@ -0,0 +1,36 @@
+<view class="page-box">
+  <scroll-view 
+    scroll-y="{{true}}" 
+    class="class-left"
+  >
+    <view a:for="{{cityTabs}}" key="{{item.code}}">
+      <view 
+        data-item="{{item}}" 
+        data-index="{{index}}"
+        class="cate-list {{ index === currentCityIndex ? 'on':''}}" 
+        onTap="onChangeCity"
+      >
+        {{item.name}}
+      </view>
+    </view>
+  </scroll-view>
+  <scroll-view 
+    class="class-right" 
+    scroll-y="{{true}}"
+    scroll-with-animation="{{true}}"
+  >
+    <view 
+      a:for="{{currentCity.subRegions}}" 
+      key="{{item.code}}"
+    >
+      <view 
+        data-item="{{item}}" 
+        data-index="{{index}}"
+        class="cate-list" 
+        onTap="onChangeArea"
+      >
+        {{item.name}}
+      </view>
+    </view>
+  </scroll-view>
+</view>

+ 51 - 0
antbuilder/core/components/city-tab/index.js

@@ -0,0 +1,51 @@
+import { connect } from 'herculex';
+import { prefixPagePath } from '../../utils';
+
+Component(connect({
+  mapStateToProps: {
+    cityTabs: state => state.cityTabs,
+    currentCityIndex: (state) => {
+      const { currentCityIndex } = state;
+      return currentCityIndex;
+    },
+    currentAreaIndex: (state) => {
+      const { currentAreaIndex } = state;
+      return currentAreaIndex;
+    },
+    currentCity: (state) => {
+      const { currentCityIndex, cityTabs } = state;
+      return cityTabs[currentCityIndex];
+    },
+    noCache: state => state.$global.noCache,
+  },
+})({
+  didMount() {
+  },
+  methods: {
+    /**
+     * 改变城市选择项
+     */
+    onChangeCity(e) {
+      const { dataset } = e.target;
+      const { index } = dataset;
+      this.dispatch('updateStoreData', {
+        currentCityIndex: index,
+      });
+    },
+    /** 
+     * 区域选择
+     */
+    async onChangeArea(e) {
+      const { dataset } = e.target;
+      const { index } = dataset;
+      await this.dispatch('updateAreaData', {
+        data: dataset.item,
+        currentAreaIndex: index,
+      });
+      if (!this.data.noCache) {
+        return my.navigateBack();
+      }
+      my.reLaunch({ url: `${prefixPagePath}/home/index?noCache=true` });
+    },
+  },
+}));

+ 9 - 0
antbuilder/core/components/city-tab/index.json

@@ -0,0 +1,9 @@
+{
+  "component": true,
+  "usingComponents": {
+    "vtabs": "mini-ali-ui/es/vtabs/index",
+    "vtab-content": "mini-ali-ui/es/vtabs/vtab-content/index",
+    "list": "mini-ali-ui/es/list/index",
+    "list-item": "mini-ali-ui/es/list/list-item/index"
+  }
+}

+ 4 - 0
antbuilder/core/components/component-card-wrapper/index.acss

@@ -0,0 +1,4 @@
+.component-card-wrapper.circle {
+  overflow: hidden;
+  border-radius: 12rpx;
+}

+ 11 - 0
antbuilder/core/components/component-card-wrapper/index.axml

@@ -0,0 +1,11 @@
+<import-sjs from="./index.sjs" name="utils" />
+<view
+  a:if="{{utils.getCardMode(componentData)}}"
+  class="component-card-wrapper {{utils.getCardMode(componentData)}}"
+>
+    <slot />
+</view>
+<block a:else>
+  <slot />
+</block>
+

+ 8 - 0
antbuilder/core/components/component-card-wrapper/index.js

@@ -0,0 +1,8 @@
+Component({
+  props: {
+    componentData: {},
+  },
+  data: {},
+  didMount() {
+  },
+});

+ 6 - 0
antbuilder/core/components/component-card-wrapper/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+
+  }
+}

+ 25 - 0
antbuilder/core/components/component-card-wrapper/index.sjs

@@ -0,0 +1,25 @@
+/*
+* 获取组件是否开启开篇模式
+* */
+
+const cardModes = {
+  circle: 'circle',
+};
+
+function getCardMode(componentData) {
+  const {
+    componentExtInfo,
+  } = componentData;
+  const {
+    cardMode = '',
+    wrapperModes = 'margin\npadding\ncardMode',
+  } = componentExtInfo;
+
+  const parseWrapperModes = wrapperModes.split('\n');
+
+  return parseWrapperModes.indexOf('margin') > -1 && cardModes[cardMode] || '';
+}
+
+export default {
+  getCardMode,
+};

+ 59 - 0
antbuilder/core/components/consult-list/index.acss

@@ -0,0 +1,59 @@
+.consult-list {
+  background: #fff;
+}
+.consult-list .consult-list-content {
+  padding: 28rpx 32rpx;
+  box-sizing: border-box;
+}
+.consult-list .consult-list-content .content-title {
+  font-size: 30rpx;
+  color: #333;
+  text-align: left;
+  line-height: 48rpx;
+  min-height: 96rpx;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 2;
+  overflow: hidden;
+  letter-spacing: 1.2rpx;
+}
+.consult-list .consult-list-content .content-desc {
+  font-size: 22rpx;
+  color: #AAA;
+  padding-bottom: 9rpx;
+}
+.consult-list .consult-list-content .content-desc .publish {
+  margin-right: 24rpx;
+}
+.consult-list .consult-list-content .content-desc .amount {
+  font-family: "AlipayNumber", sans-serif;
+}
+.consult-list .consult-list-content .hasImg {
+  display: flex;
+  height: 160rpx;
+  align-items: center;
+  justify-content: space-between;
+}
+.consult-list .consult-list-content .hasImg .left {
+  display: flex;
+  flex: 1;
+  height: 100%;
+  flex-direction: column;
+  justify-content: space-between;
+}
+.consult-list .consult-list-content .hasImg .right {
+  margin-left: 28rpx;
+  width: 224rpx;
+  height: 160rpx;
+  border-radius: 4rpx;
+}
+.consult-list .consult-list-content .hasImg-reverse {
+  flex-direction: row-reverse;
+}
+.consult-list .consult-list-content .hasImg-reverse .right {
+  margin-left: 0;
+  margin-right: 28rpx;
+}
+.consult-list .consult-list-content .noHasImg .content-title {
+  margin-bottom: 25rpx;
+}

+ 29 - 0
antbuilder/core/components/consult-list/index.axml

@@ -0,0 +1,29 @@
+<view class="consult-list">
+  <button-auth 
+    a:for="{{serviceList}}"
+    className="consult-list-content" 
+    item="{{item}}"
+  >
+    <view class="hasImg {{componentData.componentExtInfo.imgPlace === 'left' ?'hasImg-reverse':''}}" a:if="{{item.icon}}">
+      <view class="left">
+        <view class="content-title">{{item.name}}</view>
+        <view class="content-desc">
+          <text class="publish" a:if="{{item.extInfo.publisher}}">{{item.extInfo.publisher}}</text>
+          <text class="amount" a:if="{{item.clickCount}}">{{item.clickCount}}阅读</text>
+        </view>
+      </view>
+      <image 
+        lazy-load="{{false}}" 
+        class="right"
+        style="width:{{componentData.componentExtInfo.imgLength}}%"
+        src="{{item.icon.length == 32 ? imgSrcPrefix + item.icon : item.icon}}" />
+    </view>
+    <view class="noHasImg" a:else>
+      <view class="content-title">{{item.name}}</view>
+      <view class="content-desc">
+        <text class="publish" a:if="{{item.extInfo.publisher}}">{{item.extInfo.publisher}}</text>
+        <text class="amount" a:if="{{item.clickCount}}">{{item.clickCount}}阅读</text>
+      </view>
+    </view>
+  </button-auth >
+</view>

+ 14 - 0
antbuilder/core/components/consult-list/index.js

@@ -0,0 +1,14 @@
+import { connect } from 'herculex';
+
+Component(connect({
+  mapStateToProps: {
+  },
+})({
+  props: {
+    componentData: [],
+    serviceList: [],
+    imgSrcPrefix: '',
+  },
+  methods: {
+  },
+}));

+ 6 - 0
antbuilder/core/components/consult-list/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "button-auth": "../button-auth/index"
+  }
+}

+ 8 - 0
antbuilder/core/components/consult-service/index.acss

@@ -0,0 +1,8 @@
+.consult-service {
+  background: #fff;
+  overflow: hidden;
+  padding: 0 24rpx;
+}
+.consult-service .consult-list .consult-list-content {
+  padding: 28rpx 0;
+}

+ 11 - 0
antbuilder/core/components/consult-service/index.axml

@@ -0,0 +1,11 @@
+<!-- 咨询组件 contentComponent -->
+<view class="consult-service" a:if="{{componentData}}">
+  <service-title
+    imgSrcPrefix="{{imgSrcPrefix}}"
+    hasMoreIcon="{{true}}"
+    componentData="{{componentData}}"/>
+  <consult-list
+    imgSrcPrefix="{{imgSrcPrefix}}"
+    serviceList="{{ componentData.whetherSetDynamicDatasource === 'Y' ? componentData.dynamicServiceList : componentData.serviceList }}"
+    componentData="{{componentData}}"/>
+</view>

+ 16 - 0
antbuilder/core/components/consult-service/index.js

@@ -0,0 +1,16 @@
+import { connect } from 'herculex';
+
+const app = getApp();
+Component(connect({
+})({
+  data: {
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+  },
+  props: {
+    componentData: {},
+  },
+  didMount() {
+  },
+  methods: {
+  },
+}));

+ 7 - 0
antbuilder/core/components/consult-service/index.json

@@ -0,0 +1,7 @@
+{
+  "component": true,
+  "usingComponents": {
+    "service-title": "../service-title/index",
+    "consult-list": "../consult-list/index"
+  }
+}

+ 9 - 0
antbuilder/core/components/contact-button/index.acss

@@ -0,0 +1,9 @@
+.contact-container {
+  position: fixed;
+  max-height: 100rpx;
+  bottom: 0;
+  top: 0;
+  right: 0;
+  margin: auto 0;
+  z-index: 9999;
+}

+ 10 - 0
antbuilder/core/components/contact-button/index.axml

@@ -0,0 +1,10 @@
+<!-- 智能客服 -->
+<view class="contact-container" a:if="{{componentData && componentData.componentExtInfo}}">
+  <contact-button 
+    tnt-inst-id="{{componentData.componentExtInfo.tntInstId}}"
+    scene="{{componentData.componentExtInfo.scene}}" 
+    color="{{componentData.componentExtInfo.btnColor}}"
+    size="{{componentData.componentExtInfo.btnSize || 50}}"
+    alipay-card-no="{{alipayUid}}"
+    icon="{{componentData.componentExtInfo.btnIcon ? (componentData.componentExtInfo.btnIcon.length==32 ? imgSrcPrefix + componentData.componentExtInfo.btnIcon : componentData.componentExtInfo.btnIcon) : icon}}" />
+</view>

+ 20 - 0
antbuilder/core/components/contact-button/index.js

@@ -0,0 +1,20 @@
+import { connect } from 'herculex';
+
+const app = getApp();
+Component(connect({
+  mapStateToProps: {
+    alipayUid: state => state.$global.getIn(['userInfo', 'alipayUid'], ''),
+  },
+})({
+  data: {
+    icon: 'https://gw.alipayobjects.com/mdn/rms_47fd3e/afts/img/A*lhtVQ6KQ8LUAAAAAAAAAAABkARQnAQ',
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+  },
+  props: {
+    componentData: {},
+  },
+  didMount() {
+  },
+  methods: {
+  },
+}));

+ 3 - 0
antbuilder/core/components/contact-button/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 25 - 0
antbuilder/core/components/core-container/index.acss

@@ -0,0 +1,25 @@
+.index-container {
+  min-height: 100vh;
+  position: relative;
+  background-color: #ffffff;
+}
+.index-container .main {
+  min-height: 100vh;
+}
+.index-container .main .components-container {
+  position: relative;
+}
+.components-container-content::after {
+  content: '';
+  display: block;
+  width: 100%;
+}
+.tabbar-add-margin {
+  padding-bottom: 100rpx;
+}
+.tabbar-add-margin:after {
+  content: '';
+  display: block;
+  height: constant(safe-area-inset-bottom);
+  height: env(safe-area-inset-bottom);
+}

+ 157 - 0
antbuilder/core/components/core-container/index.axml

@@ -0,0 +1,157 @@
+<import-sjs from="./index.sjs" name="utils" />
+<page-wrap
+  class="index-container"
+  onReloadHandle="onReloadHandle"
+  style="{{utils.getWrapperStyle(activePageExtIfo)}}"
+>
+  <block>
+    <enter-ad
+      a:if="{{isShowEnterAd}}"
+      componentData="{{enterAdComponent}}"
+    />
+    <view class="main" a:if="{{componentList && componentList.length && isRenderMain}}">
+      <header componentData="{{activePageExtIfo}}"/>
+      <view class="components-container {{hasTabBar ? 'tabbar-add-margin' : ''}}">
+        <view class="components-container-content">
+          <view
+            class="component"
+            a:for="{{utils.addTabbarInfo(componentList, hasTabBar, tabbarHeight)}}"
+            style="{{utils.getMarginStyle(item.componentData)}}"
+          >
+            <component-card-wrapper componentData="{{item.componentData}}">
+              <!-- 用户中心 -->
+                <user a:if="{{item.componentType === 'userInfoComponent'}}" componentData="{{item.componentData}}"/>
+                <!-- 功能列表 -->
+                <function-list a:if="{{item.componentType === 'functionListComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 公告 -->
+                <notice-info
+                    a:if="{{item.componentType === 'noticeComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 轮播广告 -->
+                <advert-wheel
+                    a:if="{{item.componentType === 'advertWheelComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 推荐组件 -->
+                <hot-service
+                    a:if="{{item.componentType === 'hotServiceComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 活动组件 -->
+                <activity-ad
+                    a:if="{{item.componentType === 'activityAdComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 文字四联 -->
+                <text-list
+                    a:if="{{item.componentType === 'textlistComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 图标四联导航 -->
+                <navigation-bars
+                    a:if="{{item.componentType === 'navigationbarsComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 资讯组件 -->
+                <consult-service
+                    a:if="{{item.componentType === 'contentComponent'}}"
+                    componentData="{{item.componentData}}"/>
+                <!-- 四联图片 -->
+                <four-pic
+                    a:if="{{item.componentType === 'fourpicComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 双联图标 -->
+                <two-pic
+                    a:if="{{item.componentType === 'twopicComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 双联图片 -->
+                <pic-list
+                    a:if="{{item.componentType === 'piclistComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 双联推荐栏 -->
+                <hot-bar
+                    a:if="{{item.componentType === 'hotbarComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 券组件 -->
+                <market a:if="{{item.componentType === 'voucherComponent'}}" componentData="{{item.componentData}}"/>
+                <!-- 生活号 -->
+                <life a:if="{{item.componentType === 'lifestyleComponent'}}" componentData="{{item.componentData}}"/>
+                <!-- 客服 -->
+                <contact-button
+                    a:if="{{item.componentType === 'contactComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 插件 -->
+                <plugin a:if="{{item.componentType === 'pluginComponent'}}" componentData="{{item.componentData}}"/>
+                <!-- 会员卡升级 -->
+                <member-card
+                    a:if="{{item.componentType === 'memberCardComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 二代会员卡 -->
+                <member-card-second
+                    a:if="{{item.componentType === 'memberCardComponent2'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 会员个人中心 -->
+                <member-user-center
+                    a:if="{{item.componentType === 'memberCardUserCenter'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 新会员卡组件 -->
+                <new-member-card 
+                    a:if="{{item.componentType === 'newMemberCardComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <making-plugin  a:if="{{item.componentType === 'marketingComponent'}}"
+                componentData="{{item.componentData}}" />    
+                <!-- 自定义表单 -->
+                <custom-form
+                    a:if="{{item.componentType === 'formComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 轻会员 -->
+                <light-member
+                    a:if="{{item.componentType === 'miniServiceComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- n等分 -->
+                <equal-division
+                    a:if="{{item.componentType === 'divide4NpartsComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 动态文本组件 -->
+                <dynamic-chars
+                    a:if="{{item.componentType === 'dynamicCharsComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!-- 首页活动弹框 -->
+                <advert-show
+                    a:if="{{item.componentType === 'advertShowComponent'}}"
+                    componentData="{{item.componentData}}" />
+                <!--名片banner组件-->
+                <advert-wheel-card
+                    a:if="{{item.componentType === 'businessCardBannerComponent'}}"
+                    componentData="{{item.componentData}}"/>
+                <!-- 单行按钮组件 -->
+                <one-way-button
+                  a:if="{{item.componentType === 'oneWayButtonComponent'}}"
+                  componentData="{{item.componentData}}" />
+                <!-- <owner-card a:if="{{item.componentType === 'ownerGetCardNew'}}"
+                componentData="{{item.componentData}}"/>
+                <card-right a:if="{{item.componentType === 'advertiseComponent'}}"
+                componentData="{{item.componentData}}"/> -->
+                <!--富文本组件-->
+                  <!--富文本组件-->
+                <rich-text
+                  a:if="{{item.componentType === 'richTextComponent'}}"
+                  componentData="{{item.componentData}}" />
+                  <!-- 安心充 -->
+                  <axc-member-card
+                  a:if="{{item.componentType === 'anXinChongComp'}}"
+                  componentData="{{item.componentData}}" />
+                  <!-- 行业组件 -->
+                <industry-components item="{{item}}"/>
+                <custom-container item="{{item}}" />
+            </component-card-wrapper>
+          </view>
+          <footer a:if="{{bottomTips.name || bottomTips.desc}}" componentData="{{bottomTips}}"></footer>
+        </view>
+      </view>
+      <!-- 券组件登陆时的弹窗 -->
+      <modal-login showLoginModal="{{showLoginModal}}"/>
+      <!-- 引入消息订阅插件组件 -->
+      <component is="dynamic-plugin://2021001155639035/subscribe-msg" a:if="{{isMessagePluginLoad}}"/>
+      <a-tabbar a:if="{{hasTabBar}}" cardMode="{{extInfoObj.tabbarCardMode}}"/>
+    </view>
+    <!-- 浮动刷新按钮 -->
+    <!-- <float-button a:if="{{isDebug}}"/> -->
+  </block>
+</page-wrap>

+ 47 - 0
antbuilder/core/components/core-container/index.js

@@ -0,0 +1,47 @@
+import { connect } from 'herculex';
+
+const getPageInfo = (state) => {
+  const { $global, templateUUID } = state;
+  const pageConfig = $global.pageConfig || {};
+  return pageConfig[templateUUID] || {};
+};
+
+const getTplExtInfo = (state) => {
+  const { extInfoObj } = getPageInfo(state);
+  return extInfoObj || {};
+};
+
+Component(connect({
+  mapStateToProps: {
+    isShowPageLoginModal: state => state.$getters.isShowPageLoginModal,
+    isShowEnterAd: state => state.isShowEnterAd,
+    enterAdComponent: state => state.enterAdComponent,
+    componentList: state => state.componentList,
+    isRenderMain: state => state.isRenderMain,
+    showLoginModal: state => state.showLoginModal,
+    hasTabBar: state => state.hasTabBar,
+    bottomTips: state => state.bottomTips,
+    extInfoObj: state => getTplExtInfo(state),
+    activePageExtIfo: state => state.activePageExtIfo,
+    isMessagePluginLoad: state => state.$global.isMessagePluginLoad,
+  },
+  data: {
+    tabbarHeight: 0,
+  },
+})({
+  didUpdate(prevData) {
+    if (!prevData.hasTabBar && this.data.hasTabBar) {
+      my.createSelectorQuery()
+        .select('.tabbar-box').boundingClientRect().exec((ret) => {
+          this.setData({
+            tabbarHeight: ret[0].height,
+          });
+        });
+    }
+  },
+  methods: {
+    // todo onReloadHandle
+    // eslint-disable-next-line no-empty-function
+    async onReloadHandle() {},
+  },
+}));

+ 47 - 0
antbuilder/core/components/core-container/index.json

@@ -0,0 +1,47 @@
+{
+  "component": true,
+  "usingComponents": {
+    "industry-components": "../industry-container/index",
+    "header": "../header/index",
+    "notice-info": "../notice-info/index",
+    "advert-wheel": "../advert-wheel/index",
+    "hot-service": "../hot-service/index",
+    "activity-ad": "../activity-ad/index",
+    "text-list": "../text-list/index",
+    "navigation-bars": "../navigation-bars/index",
+    "consult-service": "../consult-service/index",
+    "four-pic": "../four-pic/index",
+    "two-pic": "../two-pic/index",
+    "hot-bar": "../hot-bar/index",
+    "pic-list": "../pic-list/index",
+    "market": "../mkt/index",
+    "life": "../life-style/index",
+    "contact-button": "../contact-button/index",
+    "plugin": "../plugin/index",
+    "member-card": "../member-card/index",
+    "light-member": "../light-member/index",
+    "modal-login": "../modal-login/index",
+    "page-wrap": "../page-wrap/index",
+    "enter-ad": "../enter-ad/index",
+    "a-footer": "../a-footer/index",
+    "user": "../user-center/index",
+    "function-list": "../function-list/index",
+    "a-tabbar": "../a-tabbar/index",
+    "custom-form": "../custom-form/index",
+    "footer": "../footer/index",
+    "equal-division": "../equal-division/index",
+    "dynamic-chars": "../dynamic-chars/index",
+    "advert-show": "../advert-show/index",
+    "component-card-wrapper": "../component-card-wrapper/index",
+    "advert-wheel-card": "../advert-wheel-card/index",
+    "one-way-button": "../one-way-button/index",
+    "rich-text": "../rich-text/index",
+    "new-member-card": "../new-member-card/index",
+    "float-button": "../float-button/index",
+    "custom-container": "/custom/integration/index",
+    "making-plugin": "../making-plugin/index",
+    "member-user-center": "../member-user-center/index",
+    "axc-member-card": "../anxinchong/index",
+    "member-card-second": "../member-card-second/index"
+  }
+}

+ 74 - 0
antbuilder/core/components/core-container/index.sjs

@@ -0,0 +1,74 @@
+function replacePx(val) {
+  return +(val || '').replace('px', '');
+}
+
+function transValToRem(str) {
+  return str.split(' ').map((val) => `${(replacePx(val) / 50)}rem`).join(' ');
+}
+
+/*
+* 传入tabbar信息:高度,hasTabBar
+* */
+function addTabbarInfo(componentList, hasTabBar, height) {
+  return componentList.map(item => {
+    item.componentData.tabbarInfo = {
+      hasTabBar,
+      height,
+    };
+    return item;
+  });
+}
+
+
+/*
+* 页面背景颜色显示
+* */
+function getWrapperStyle(extInto) {
+  const {
+    backgroundColor,
+  } = extInto || {};
+  return `background-color:${backgroundColor || '#f1f1f1'}`;
+}
+
+/*
+* 增加组件的margin和padding 逻辑
+* */
+function getMarginStyle(componentData) {
+  const styles = [];
+  const {
+    componentExtInfo,
+  } = componentData;
+  const {
+    padding,
+    // customZIndex,
+    wrapperModes = 'margin\npadding\ncardMode',
+    margin = '0 0 12px 0',
+  } = componentExtInfo;
+
+  const parseWrapperModes = wrapperModes.split('\n');
+
+  if (margin && parseWrapperModes.indexOf('margin') > -1) {
+    styles.push(
+      `margin:${transValToRem(margin)}`,
+    );
+  }
+
+  if (padding && parseWrapperModes.indexOf('padding') > -1) {
+    styles.push(
+      `padding:${transValToRem(padding)}`,
+    );
+  }
+
+  // if (customZIndex) {
+  //   styles.push('position:relative');
+  //   styles.push(`z-index:${customZIndex}`);
+  // }
+
+  return styles.join(';');
+}
+
+export default {
+  getMarginStyle,
+  getWrapperStyle,
+  addTabbarInfo,
+};

+ 57 - 0
antbuilder/core/components/custom-form/index.acss

@@ -0,0 +1,57 @@
+.form-section {
+  font-size: 30rpx;
+  color: #333333;
+}
+.form-section .form-image {
+  box-sizing: border-box;
+}
+.form-section .form-image image {
+  width: 100%;
+  background-color: #ffffff;
+}
+.form-section .card-image {
+  padding: 24rpx 24rpx 0 24rpx;
+}
+.form-section .mas-infocheck-title-inline {
+  margin: 0;
+  padding: 32rpx 32rpx 16rpx 32rpx;
+  font-weight: normal;
+}
+.form-section .mas-infocheck-inline {
+  padding: 0;
+}
+.form-section .mas-infocheck-item-inline {
+  padding: 25rpx 32rpx;
+  height: 96rpx;
+  box-sizing: border-box;
+}
+.form-section .mas-infocheck-label-inline {
+  font-size: 30rpx;
+  color: #333333;
+  margin: 0;
+}
+.form-section .mas-infocheck-region-pickerplaceholder {
+  color: #808080;
+}
+.form-section .slot-tips {
+  padding: 10rpx 32rpx;
+  text-align: left;
+  background: #f5f5f5;
+  color: #f93a4a;
+}
+.form-section .submit-button {
+  margin: 44rpx 24rpx 0 24rpx;
+  border-radius: 10rpx;
+  height: 90rpx;
+  line-height: 90rpx;
+  font-size: 40rpx;
+  color: #ffffff;
+  background-color: #4169db;
+}
+.form-section .card-button {
+  margin: 44rpx 0 0 0;
+  border-radius: 0rpx;
+}
+.form-section .actived {
+  background-color: #b3c3f0;
+}

+ 18 - 0
antbuilder/core/components/custom-form/index.axml

@@ -0,0 +1,18 @@
+<!-- 表单组件 -->
+<view class="form-section"
+  a:if="{{componentData}}">
+  <view class="form-image {{isCard ? 'card-image':''}}">
+    <image a:if="{{backgroundUrl}}" mode="widthFix" src="{{backgroundUrl}}" onError="imageError" />
+  </view>
+  <mas-infocheck
+    isCard="{{isCard}}"
+    editable = "{{editable}}"
+    title="{{title}}"
+    value="{{formValue}}"
+    fields="{{formFieldList}}"
+    onChange="onChange"
+  >
+  <view a:for="{{formFieldList}}" a:if="{{item.require}}" hidden="{{!(item.require && !formValue[item.key] && !isValidate)}}" slot="field-postfix-{{item.key}}" class="slot-tips">{{item.tips}}</view>
+  </mas-infocheck>
+  <button class="submit-button {{!isCard ? 'card-button' : ''}}" a:if="{{showButton}}" onTap="onSumbit">提交</button>
+</view>

+ 172 - 0
antbuilder/core/components/custom-form/index.js

@@ -0,0 +1,172 @@
+import { connect } from 'herculex';
+import { toast } from '../../utils/jsapi';
+import request from '../../utils/request';
+import { saveFormDataUrl, getFormConfigDetailUrl } from '../../utils/constants';
+
+Component(connect({
+})({
+  data: {
+    defaultConfig: {
+      regionPicker: {
+        showAutoLocate: true,
+      },
+      datePicker: {
+        format: 'yyyy-MM-dd',
+        currentDate: '',
+        startDate: '',
+        endDate: '',
+        showIcon: true,
+      },
+      textarea: {
+        showCount: false,
+        maxlength: 140,
+      },
+      optionsSelect: {
+        optionsOne: [],
+        optionsTwo: [],
+      },
+      multiLevelSelect: {
+        multiLevelSelectItems: [],
+      },
+    },
+    //
+    cardModel: false,
+    isValidate: true,
+    editable: true,
+    title: '',
+    backgroundUrl: '',
+    showButton: false,
+    formFieldList: [],
+    formValue: {},
+  },
+  props: {
+    componentData: {},
+  },
+
+  didMount() {
+    this.getFormConfigDetail();
+  },
+
+  methods: {
+    onChange(d) {
+      this.setData({
+        formValue: d,
+      });
+    },
+
+    // 加载表单配置
+    async getFormConfigDetail() {
+      const { componentExtInfo: { formUuid } } = this.props.componentData;
+      const [err, response] = await request({
+        url: getFormConfigDetailUrl,
+        method: 'get',
+        data: { uuid: formUuid },
+      });
+      if (err) throw err;
+      // 设置默认值
+      const formValue = {}; const
+        configList = [];
+      response.formFieldList.forEach((item) => {
+        if (!item.hide) {
+          configList.push(this.getComponentConfig(item));
+          formValue[item.fieldKey] = item.fieldValue;
+          // formValue[item.fieldName] = item.fieldValue || '';
+        }
+      });
+      this.setData({
+        ...response,
+        title: configList.length > 0 ? response.formName : '',
+        showButton: response.showButton,
+        isCard: response.cardModel || false,
+        formFieldList: configList,
+        formValue,
+      });
+    },
+
+    getFormValue() {
+      const formValue = {};
+      for (const item of this.data.formFieldList) {
+        const value = this.data.formValue[item.key];
+        formValue[item.key] = '';
+        if (!value) continue;
+        if (item.mode === 'optionsSelect') {
+          formValue[item.key] = value.selectedOneOption + (value.selectedOneOption || '');
+        } else if (item.mode === 'regionPicker' || item.mode === 'dynamicMultiLevelPicker' || item.mode === 'multiLevelSelect') {
+          value.forEach((v) => {
+            formValue[item.key] += v.name;
+          });
+        } else {
+          formValue[item.key] = value;
+        }
+      }
+      return formValue;
+    },
+
+    // 提交表单
+    async onSumbit() {
+      let formValidate = true;
+      for (const item of this.data.formFieldList) {
+        if (item.require && !this.data.formValue[item.key]) {
+          formValidate = false;
+        }
+      }
+      this.setData({
+        isValidate: formValidate,
+      });
+      if (!formValidate) return;
+      //
+      my.showLoading({ content: '正在提交' });
+      const { componentExtInfo: { formUuid } } = this.props.componentData;
+      const formValue = this.getFormValue();
+      const [err, response] = await request({
+        url: saveFormDataUrl,
+        header: { 'content-type': 'application/json' },
+        data: {
+          formUuid,
+          ...formValue,
+        },
+      });
+      my.hideLoading();
+      if (err) toast(err.msg);
+      if (response) toast('提交成功');
+    },
+
+    getComponentConfig(option) {
+      const config = {
+        ...this.data.defaultConfig[option.fieldMode],
+        label: option.label,
+        key: option.fieldKey,
+        mode: option.fieldMode,
+        type: option.fieldType || 'string',
+        require: option.require,
+        allowClear: option.allowClear,
+        tips: option.tips || '',
+        placeholder: option.placeholder || '',
+        disabled: !option.editable || '',
+        password: option.hide || false,
+      };
+      if (option.fieldMode === 'optionsSelect' && option.dataSource) {
+        config.optionsOne = option.dataSource.split(',') || [];
+      } else if (option.fieldMode === 'multiLevelSelect' && option.dataSource) {
+        config.multiLevelSelectItems = this.checkJson(option.dataSource) ? JSON.parse(option.dataSource) : [];
+      }
+      return config;
+    },
+    checkJson(str) {
+      if (typeof str === 'string') {
+        try {
+          const obj = JSON.parse(str);
+          if (typeof obj === 'object' && obj) {
+            return true;
+          } else {
+            return false;
+          }
+        } catch (e) {
+          console.log(`error:${str}!!!${e}`);
+          return false;
+        }
+      }
+      return false;
+    },
+  },
+}));

+ 6 - 0
antbuilder/core/components/custom-form/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "mas-infocheck": "@mas.io/mas-infocheck/es/index"
+  }
+}

+ 36 - 0
antbuilder/core/components/custom-swiper/index.acss

@@ -0,0 +1,36 @@
+.custom-swiper-component .swiper-block {
+  background: #fff;
+  position: relative;
+  /* min-height: 100rpx; */
+}
+.custom-swiper-component .swiper-item {
+  width: 100%;
+}
+.custom-swiper-component .swiper-item-next {
+  position: absolute;
+  right: 30rpx;
+}
+.custom-swiper-component .swiper-item-prev {
+  position: absolute;
+  left: 30rpx;
+}
+.custom-swiper-component .swiper-item image {
+  width: 100%;
+  z-index: 1;
+}
+.custom-swiper-component .swiper-slot {
+  width: 100%;
+  /*overflow: hidden;*/
+}
+.custom-swiper-component .active {
+  transform: scale(1);
+  transition: all 0.5s ease-in 0s;
+  z-index: 20;
+  opacity: 1;
+}
+.custom-swiper-component .common {
+  transform: scale(0.8);
+  transition: all 0.5s ease-in 0s;
+  z-index: 0;
+  opacity: 0.4;
+}

+ 28 - 0
antbuilder/core/components/custom-swiper/index.axml

@@ -0,0 +1,28 @@
+<!-- 预览模式 -->
+<view class="custom-swiper-component">
+  <block a:if="{{mode === 'multi'}}">
+    <swiper class="swiper-block {{swiperClass}}" changing-class="{{changingClass}}" active-class="{{activeClass}}" acceleration="{{acceleration}}" disable-touch="{{disableTouch}}" swipe-ratio="{{swipeRatio}}" swipe-speed="{{swipeSpeed}}" touch-angle="{{touchAngle}}" easing-function="{{easingFunction}}" adjust-height="{{adjustHeight}}" adjust-vertical-height="{{adjustVerticalHeight}}" disable-programmatic-animation="{{disableProgrammaticAnimation}}" indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" circular="{{circular}}" snap-to-edge="{{snapToEdge}}" previous-margin="{{previousMargin}}" next-margin="{{nextMargin}}" interval="{{interval}}" current="{{current}}" indicator-color="{{indicatorColor}}" indicator-active-color="{{indicatorActiveColor}}" onChange="onChange" onAnimationEnd="onAnimationEnd" onTransition="onTransition">
+      <block a:for="{{images}}" a:index="{{index}}">
+        <swiper-item class="swiper-item">
+            <view class="swiper-slot {{current === index ? 'active' : 'common'}}">
+              <slot data="{{{item, index, current}}}">
+              </slot>
+            </view>
+          </swiper-item>
+      </block>
+    </swiper>
+  </block>
+  <!-- 普通模式 -->
+  <block a:else>
+    <swiper class="swiper-block {{swiperClass}}" changing-class="{{changingClass}}" active-class="{{activeClass}}" acceleration="{{acceleration}}" disable-touch="{{disableTouch}}" swipe-ratio="{{swipeRatio}}" swipe-speed="{{swipeSpeed}}" touch-angle="{{touchAngle}}" easing-function="{{easingFunction}}" adjust-height="{{adjustHeight}}" adjust-vertical-height="{{adjustVerticalHeight}}" disable-programmatic-animation="{{disableProgrammaticAnimation}}" indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" circular="{{circular}}" snap-to-edge="{{snapToEdge}}" previous-margin="{{perviousMargin}}" next-margin="{{nextMargin}}" interval="{{interval}}" current="{{current}}" indicator-color="{{indicatorColor}}" indicator-active-color="{{indicatorActiveColor}}" onChange="onChange" onAnimationEnd="onAnimationEnd" onTransition="onTransition">
+      <block a:for="{{images}}" a:index="{{index}}">
+        <swiper-item class="swiper-item">
+          <view class="swiper-slot">
+              <slot data="{{{item, index, current}}}">
+              </slot>
+          </view>
+        </swiper-item>
+      </block>
+    </swiper>
+  </block>
+</view>

+ 58 - 0
antbuilder/core/components/custom-swiper/index.js

@@ -0,0 +1,58 @@
+Component({
+  mixins: [],
+  data: {
+    current: 0,
+  },
+  props: {
+    images: Array,
+    changingClass: String,
+    swiperClass: String,
+    activeClass: String,
+    indicatorDots: true,
+    autoplay: false,
+    vertical: false,
+    disableProgrammaticAnimation: false,
+    circular: true,
+    snapToEdge: false,
+    acceleration: false,
+    disableTouch: false,
+    adjustVerticalHeight: false,
+    // displayMultipleItems: 1,
+    current: 0,
+    interval: 1000,
+    swipeRatio: 0.2,
+    swipeSpeed: 0.05,
+    touchAngle: 45,
+    easingFunction: 'default',
+    indicatorColor: '#888',
+    indicatorActiveColor: '#333',
+    adjustHeight: 'highest',
+    mode: 'multi',
+    previousMargin: '50rpx',
+    nextMargin: '50rpx',
+  },
+  didMount() {
+  },
+  didUpdate() {
+  },
+  didUnmount() {
+  },
+  methods: {
+    // 当前图片点击事件
+    onItemClick() {
+      this.props.onItemClick && this.props.onItemClick(this.data.current, this.props.images[this.data.current]);
+    },
+    onChange(e) {
+      this.setData({
+        current: e.detail.current,
+      });
+      this.props.onChange && this.props.onChange(e);
+    },
+    onTransition(e) {
+      this.props.onTransition && this.props.onTransition(e);
+    },
+    onAnimationEnd(e) {
+      this.props.onAnimationEnd && this.props.onAnimationEnd(e);
+    },
+  },
+});

+ 3 - 0
antbuilder/core/components/custom-swiper/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 24 - 0
antbuilder/core/components/dynamic-chars/index.acss

@@ -0,0 +1,24 @@
+.dynamic-text-container {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  box-sizing: border-box;
+  padding: 16rpx;
+}
+.dynamic-text-container .text-item {
+  display: flex;
+  flex-direction: column;
+  padding: 16rpx;
+  width: 25%;
+  text-align: center;
+  box-sizing: border-box;
+}
+.dynamic-text-container .text-item .title {
+  font-size: 40rpx;
+  color: #333;
+}
+.dynamic-text-container .text-item .subtitle {
+  font-size: 22rpx;
+  color: #999;
+  font-weight: bold;
+}

+ 9 - 0
antbuilder/core/components/dynamic-chars/index.axml

@@ -0,0 +1,9 @@
+<view class="dynamic-text-container" style="background:{{componentData.componentExtInfo.backgroundColor}}">
+  <block 
+    a:for="{{componentData.whetherSetDynamicDatasource === 'Y' ? componentData.dynamicServiceList : componentData.serviceList}}">
+    <view class="text-item"> 
+      <text class="subtitle" style="font-size:{{componentData.componentExtInfo.valueFontSize}}px;color:{{componentData.componentExtInfo.valueFontColor}}">{{item.extInfo.value}}</text>
+      <text class="title" style="font-size:{{componentData.componentExtInfo.titleFontSize}}px;color:{{componentData.componentExtInfo.titleFontColor}}">{{item.extInfo.title}}</text>
+     </view>
+  </block>
+</view>

+ 8 - 0
antbuilder/core/components/dynamic-chars/index.js

@@ -0,0 +1,8 @@
+Component({
+  props: {
+    show: false,
+    componentData: {},
+  },
+  methods: {
+  },
+});

+ 3 - 0
antbuilder/core/components/dynamic-chars/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 53 - 0
antbuilder/core/components/el-list/index.acss

@@ -0,0 +1,53 @@
+.el-list-container {
+  border-radius: 4rpx;
+  overflow: hidden;
+}
+.el-list {
+  display: flex;
+  height: 104rpx;
+  background: #fff;
+  align-items: center;
+  box-sizing: border-box;
+  justify-content: space-between;
+}
+.el-list .left {
+  display: flex;
+  align-items: center;
+  overflow: hidden;
+  flex: 1;
+}
+.el-list .left .icon {
+  width: 60rpx;
+  height: 60rpx;
+  margin-right: 32rpx;
+}
+.el-list .left .key {
+  font-size: 34rpx;
+  color: #333;
+  overflow: hidden;
+  width: 100%;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.el-list .right {
+  display: flex;
+  align-items: center;
+  max-width: 490rpx;
+}
+.el-list .right .value {
+  width: 100%;
+  font-size: 34rpx;
+  color: #333;
+}
+.el-list .right .placeholder {
+  color: #999;
+  font-size: 34rpx;
+}
+.el-list .right .img {
+  width: 60rpx;
+  height: 60rpx;
+  border-radius: 4rpx;
+}
+.el-list .right .am-icon {
+  margin-left: 16rpx;
+}

+ 31 - 0
antbuilder/core/components/el-list/index.axml

@@ -0,0 +1,31 @@
+<view class="el-list-container {{className}}">
+  <button-auth 
+    a:for="{{list}}"
+    a:if="{{controllShow || (item.value || item.canShow)}}" 
+    className="el-list border_1px_after" 
+    item="{{item}}"
+    needCallBack="{{needCallBack}}"
+    onCallBack="onCallBack"
+  >
+    <view class="left">
+      <image 
+        a:if="{{item.icon && showIcon}}" 
+        class="icon"
+        mode="aspectFit"
+        src="{{item.icon.length == 32 ? imgSrcPrefix + item.icon : item.icon}}" />
+      <text class="key">{{item.name}}</text>
+    </view>
+    <view class="right">
+      <image 
+        class="img"
+        a:if="{{item.hasImg}}"
+        src="{{item.value}}" />
+      <text
+        number-of-lines="1"
+        a:elif="{{item.value || item.placeholder}}" 
+        class="{{item.value ? 'value' : 'placeholder'}}"
+      >{{item.value || item.placeholder}}</text>
+      <am-icon a:if="{{!item.notNeedArrow}}" class="am-icon" color="#ccc" type="arrow-right" size="14" />
+    </view>
+  </button-auth >
+</view>

+ 21 - 0
antbuilder/core/components/el-list/index.js

@@ -0,0 +1,21 @@
+const fn = () => {};
+Component({
+  props: {
+    list: [],
+    onClickItem: fn,
+    showIcon: false,
+    imgSrcPrefix: '',
+    className: '',
+    needCallBack: false,
+    controllShow: true,
+  },
+  data: {
+  },
+  didMount() {
+  },
+  methods: {
+    onCallBack(e) {
+      this.props.onClickItem(e);
+    },
+  },
+});

+ 7 - 0
antbuilder/core/components/el-list/index.json

@@ -0,0 +1,7 @@
+{
+  "component": true,
+  "usingComponents": {
+    "am-icon": "mini-ali-ui/es/am-icon/index",
+    "button-auth": "../button-auth/index"
+  }
+}

+ 21 - 0
antbuilder/core/components/enter-ad/index.acss

@@ -0,0 +1,21 @@
+.enterAd-container {
+  height: 100vh;
+  width: 100vw;
+  box-sizing: border-box;
+  background-size: 100% 100%;
+  background-position: center center;
+  background-repeat: no-repeat;
+  top: 0;
+  left: 0;
+  position: fixed;
+  z-index: 99999;
+}
+.enterAd-container .mas-countdown {
+  position: absolute;
+  width: 90rpx;
+  top: 100px;
+  right: 24rpx;
+}
+.enterAd-container .mas-countdown .mas-countdown__number {
+  font-size: 36rpx;
+}

+ 13 - 0
antbuilder/core/components/enter-ad/index.axml

@@ -0,0 +1,13 @@
+<view
+  a:if="{{componentData}}"
+  class="enterAd-container" 
+  onAppear="expo"
+  style="{{`backgroundImage: url(${componentData.componentIcon.length == 32 ? imgSrcPrefix + componentData.componentIcon : componentData.componentIcon}); color: ${componentData.componentExtInfo.textcolor || '#333'}`}}">
+  <mas-countdown
+    second="{{ 5 }}"
+    secondOnly="{{true}}"
+    onTimeup="onTimeup"
+    showColon="{{false}}"
+    minDigits="{{ 1 }}"
+  />
+</view>

+ 36 - 0
antbuilder/core/components/enter-ad/index.js

@@ -0,0 +1,36 @@
+import { connect } from 'herculex';
+import { setStorage, getStorage } from '../../utils';
+
+const app = getApp();
+Component(connect({
+  mapStateToProps: {
+    indexBanner: state => state.$global.indexBanner,
+  },
+})({
+  data: {
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+  },
+  didMount() {
+  },
+  props: {
+    componentData: {},
+  },
+  methods: {
+    async expo() {
+      let adShowCount = +await getStorage('adShowCount') || 0;
+      // eslint-disable-next-line no-plusplus
+      setStorage('adShowCount', ++adShowCount);
+      this.commitGlobal({ adShowed: true });
+    },
+    onTimeup() {
+      console.log('时间到了');
+      // const { indexBanner } = this.data;
+      this.commit({
+        isShowEnterAd: false,
+      });
+      // my.setNavigationBar({
+      //   backgroundColor: indexBanner ? 'transparent' : '#fff',
+      // });
+    },
+  },
+}));

+ 6 - 0
antbuilder/core/components/enter-ad/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "mas-countdown": "@mas.io/mas-countdown/es/index"
+  }
+}

+ 102 - 0
antbuilder/core/components/equal-division/index.acss

@@ -0,0 +1,102 @@
+.equal-division-bars {
+  background: #fff;
+  padding: 0 24rpx;
+}
+.equal-division-bars .icon-type .text-desc {
+  display: flex;
+  height: 72rpx;
+  font-size: 24rpx;
+  width: 100%;
+  color: #999;
+  align-items: center;
+}
+.equal-division-bars .icon-type .text-desc text {
+  max-width: 100%;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content {
+  box-sizing: border-box;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .border-1px-right {
+  border-right: 1px solid #eeeeee;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item {
+  position: relative;
+  width: 100%;
+  padding: 32rpx 10rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  box-sizing: border-box;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item .service-icon-box {
+  position: relative;
+  margin-bottom: 16rpx;
+  max-width: 100%;
+  width: 50rpx;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item .service-icon-box .badge {
+  display: inline-block;
+  position: absolute;
+  top: -10rpx;
+  left: 50%;
+  padding: 4rpx 8rpx;
+  background-color: #ff411c;
+  border-radius: 8px 8px 8px 0;
+  font-size: 8px;
+  white-space: nowrap;
+  color: #fff;
+  z-index: 0;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item .service-icon-box .service-icon {
+  max-width: 100%;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item .service-title-section {
+  box-sizing: border-box;
+  overflow: hidden;
+  width: 100%;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item .service-title-section .service-name {
+  color: #333;
+  font-size: 26rpx;
+  font-weight: 500;
+  width: 100%;
+  text-align: center;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item .service-title-section .service-desc {
+  color: #999999;
+  font-size: 22rpx;
+  width: 100%;
+  text-align: center;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item-lr {
+  flex-direction: row;
+  padding: 32rpx 20rpx;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item-lr .service-icon-box {
+  margin-bottom: 0;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item-lr .service-title-section {
+  padding-left: 20rpx;
+  flex: 1;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item-lr .service-title-section .service-name {
+  text-align: left;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .service-item-lr .service-title-section .service-desc {
+  text-align: left;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .align-left {
+  align-items: start;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .align-left .service-title-section .service-name {
+  text-align: left;
+}
+.equal-division-bars .icon-type .service-market-icon .service-content .align-left .service-title-section .service-desc {
+  text-align: left;
+}

+ 44 - 0
antbuilder/core/components/equal-division/index.axml

@@ -0,0 +1,44 @@
+<view class="equal-division-bars" a:if="{{componentData && componentData.serviceList && componentData.serviceList.length}}">
+  <view class="icon-type">
+    <!-- 标题 -->
+    <service-title
+      imgSrcPrefix="{{imgSrcPrefix}}"
+      componentData="{{componentData}}"/>
+    <!-- 服务列表 -->
+    <view class="service-market-icon">
+      <view class="service-content">
+        <view 
+          a:for="{{badgeList}}"
+          style="width: {{100 / (componentData.componentExtInfo.lineNum || defaultColumn)}}%;"
+        >
+          <button-auth 
+            className="service-item
+              {{(componentData.componentExtInfo.place === 'LR' && componentData.componentExtInfo.lineNum === '1') ? 'border_1px_after' : ''}}
+              {{componentData.componentExtInfo.place === 'LR' ? 'service-item-lr': componentData.componentExtInfo.alignStyle === 'left' ? 'align-left':''}}" 
+            item="{{item}}"
+            a:if="{{index < (componentData.componentExtInfo.maxNum || maxNum)}}"
+            >
+            <view class="service-icon-box" style="width: {{componentData.componentExtInfo.logoSize}}%;">
+              <image
+                class="service-icon"
+                lazy-load="{{false}}" 
+                mode="widthFix"
+                src="{{ item.icon.length ==32 ? imgSrcPrefix + item.icon : item.icon}}"
+              />
+              <text 
+                a:if="{{item.extInfo.badgeText}}"
+                className="badge"
+                style="font-size: {{componentData.componentExtInfo.badgeFontSize}}px;color: {{componentData.componentExtInfo.badgeFontColor}};background: {{componentData.componentExtInfo.badgeBackgroundColor}}"
+              >{{ item.extInfo.badgeText.slice(0,4)}}</text>
+            </view>
+            <view class="service-title-section">
+              <view class="service-name" style="color: {{componentData.componentExtInfo.textColor}}; font-size: {{componentData.componentExtInfo.textFontSize}}px;">{{item.name}}</view>
+              <view class="service-desc" style="color: {{componentData.componentExtInfo.backupTextColor}}; font-size: {{componentData.componentExtInfo.backupTextFontSize}}px;">{{item.serviceDesc}}</view>
+            </view>            
+            <view a:if="{{ componentData.componentExtInfo.place === 'LR' && componentData.componentExtInfo.lineNum === '1' }}"><am-icon type="right" color="#cccccc" /></view>
+          </button-auth>
+        </view>
+      </view>
+    </view>
+  </view>
+</view>

+ 59 - 0
antbuilder/core/components/equal-division/index.js

@@ -0,0 +1,59 @@
+import { connect } from 'herculex';
+import request from './../../../core/utils/request';
+
+const app = getApp();
+Component(connect({})({
+  data: {
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+    maxNum: 8,
+    defaultColumn: 4,
+    badgeConfig: {
+      withArrow: true,
+      direction: 'left',
+    },
+    badgeList: [],
+  },
+  props: {
+    componentData: {},
+  },
+  didMount() {
+    this.getData();
+  },
+  didUpdate(preProps) {
+    if (preProps.componentData.componentUUID !== this.props.componentData.componentUUID) {
+      return this.getData();
+    }
+  },
+  methods: {
+    async getData() {
+      const {
+        componentUUID,
+        componentExtInfo,
+        serviceList,
+      } = this.props.componentData;
+      let badgeList = serviceList;
+      const { dynBadge } = componentExtInfo;
+      if (!dynBadge) return this.setData({ badgeList });
+      // 请求动态数据
+      const options = {
+        url: 'api/v1/component/dynamicBadge',
+        method: 'GET',
+        data: { componentUuid: componentUUID },
+      };
+      const [, data] = await request(options);
+      if (data && data.length) {
+        badgeList = badgeList.map(item => {
+          const dynItem = data.find(t => item.serviceCode === t.serviceCode);
+          if (dynItem && dynItem.value) {
+            item.extInfo = {
+              ...item.extInfo,
+              badgeText: dynItem.value,
+            };
+          }
+          return item;
+        });
+      }
+      this.setData({ badgeList });
+    },
+  },
+}));

+ 9 - 0
antbuilder/core/components/equal-division/index.json

@@ -0,0 +1,9 @@
+{
+    "component": true,
+    "usingComponents": {
+      "service-title": "../service-title/index",
+      "button-auth": "../button-auth/index",
+      "am-icon": "mini-ali-ui-rpx/es/am-icon/index"
+    }
+}
+  

+ 26 - 0
antbuilder/core/components/float-button/index.acss

@@ -0,0 +1,26 @@
+.float-button-component {
+  position: fixed;
+  right: 0;
+  bottom: 221rpx;
+  z-index: 9999;
+  margin: auto 0;
+  padding-bottom: constant(safe-area-inset-bottom);
+  padding-bottom: env(safe-area-inset-bottom);
+}
+.float-button-component .button {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  padding: 11rpx 9rpx 11rpx 25rpx;
+  background: #FFFFFF;
+  box-shadow: 0 5rpx 17rpx 3rpx rgba(0, 0, 0, 0.09);
+  border-radius: 100rpx 0 0 100rpx;
+  background-color: #FFFFFF;
+}
+.float-button-component .button text {
+  width: 40rpx;
+  font-family: 'PingFangSC-Regular';
+  font-size: 20rpx;
+  color: #333333;
+  text-align: right;
+}

+ 6 - 0
antbuilder/core/components/float-button/index.axml

@@ -0,0 +1,6 @@
+
+<view class="float-button-component" onTap="onClick">
+  <view class="button" catchTap="onClick">
+    <text>{{text}}</text>
+  </view>
+</view>

+ 42 - 0
antbuilder/core/components/float-button/index.js

@@ -0,0 +1,42 @@
+/* eslint-disable no-proto */
+import { connect } from 'herculex';
+
+Component(connect({
+  mapStateToProps: {
+  },
+})({
+  props: {
+    text: '应用重载',
+    onCallBack: '',
+  },
+  data: {
+  },
+  methods: {
+    async onClick() {
+      if (this.props.onCallBack) {
+        this.props.onCallBack();
+      } else {
+        // 重载应用
+        my.removeStorageSync({
+          key: 'PAGE_DATA_KEY',
+        });
+        const url = getCurrentPages()[0].__proto__.route;
+        const options = getCurrentPages()[0].options || {};
+        let params = '';
+        Object.keys(options).forEach(key => {
+          params = options[key] && (typeof (options[key]) === 'string' || typeof (options[key]) === 'number') ? `&${key}=${options[key]}` : params;
+        });
+        my.reLaunch({
+          url: `/${url}?${params}`,
+        });
+        // 页面刷新
+        // const options = getCurrentPages().pop().options || {};
+        // await this.dispatch('init', {
+        //   ...options,
+        //   noCache: true,
+        //   isPullRefresh: true,
+        // });
+      }
+    },
+  },
+}));

+ 5 - 0
antbuilder/core/components/float-button/index.json

@@ -0,0 +1,5 @@
+{
+  "component": true,
+  "usingComponents": {
+  }
+}

+ 49 - 0
antbuilder/core/components/footer/index.acss

@@ -0,0 +1,49 @@
+.bottom-tip {
+  width: 100%;
+  box-sizing: border-box;
+}
+.TB-box,
+.LR-box {
+  padding: 40rpx 32rpx;
+}
+.TB-box .code-footer,
+.LR-box .code-footer {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.TB-box .code-footer .logo,
+.LR-box .code-footer .logo {
+  width: 40rpx;
+  height: 40rpx;
+  border-radius: 50%;
+  margin-right: 15rpx;
+}
+.TB-box .code-footer .interval,
+.LR-box .code-footer .interval {
+  margin: 0 10rpx;
+}
+.TB-box .code-footer text,
+.LR-box .code-footer text {
+  font-size: 26rpx;
+  color: #ccc;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.TB-box .code-footer .line,
+.LR-box .code-footer .line {
+  width: 80rpx;
+  height: 2rpx;
+  background: #ddd;
+  margin: 25rpx;
+}
+.TB-box .code-desc,
+.LR-box .code-desc {
+  text-align: center;
+}
+.TB-box .code-desc text,
+.LR-box .code-desc text {
+  font-size: 26rpx;
+  color: #ccc;
+}

+ 21 - 0
antbuilder/core/components/footer/index.axml

@@ -0,0 +1,21 @@
+<view class="bottom-tip" style="background:{{componentData.bgColor}};">
+    <view class="TB-box" a:if="{{componentData.place === 'TB'}}">
+        <view class="code-footer" a:if="{{componentData.name}}">
+            <text class="line" style="background:{{componentData.textColor || '#999999'}}"></text>
+            <image class="logo" src="{{componentData.logo.length === 32 ? imgSrcPrefix + componentData.logo : componentData.logo}}" a:if="{{componentData.logo}}"/>
+            <text style="color:{{componentData.textColor || '#999999'}}">{{componentData.name}}</text>
+            <text class="line" style="background:{{componentData.textColor || '#999999'}}"></text>
+        </view>
+        <view class="code-desc" a:if="{{componentData.desc}}">
+            <text style="color:{{componentData.textColor || '#999999'}}">{{componentData.desc}}</text>
+        </view>
+    </view>
+    <view class="LR-box" a:else>
+        <view class="code-footer" style="color:{{componentData.textColor || '#999999'}}">
+            <image class="logo" src="{{componentData.logo.length === 32 ? imgSrcPrefix + componentData.logo : componentData.logo}}" a:if="{{componentData.logo}}" />
+            <text style="color:{{componentData.textColor || '#999999'}}">{{componentData.name}}</text>
+            <text class="interval"  a:if="{{componentData.name && componentData.desc}}" style="color:{{componentData.textColor || '#999999'}}">|</text>
+            <text style="color:{{componentData.textColor || '#999999'}}">{{componentData.desc}}</text>
+        </view>
+    </view>
+</view>

+ 19 - 0
antbuilder/core/components/footer/index.js

@@ -0,0 +1,19 @@
+import { connect } from 'herculex';
+
+const app = getApp();
+Component(connect({
+  mapStateToProps: {
+    hasTabBar: state => state.hasTabBar,
+  },
+})({
+  data: {
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+  },
+  props: {
+    componentData: {},
+  },
+  didMount() {
+  },
+  methods: {
+  },
+}));

+ 4 - 0
antbuilder/core/components/footer/index.json

@@ -0,0 +1,4 @@
+{
+    "component": true
+}
+  

+ 65 - 0
antbuilder/core/components/four-pic/index.acss

@@ -0,0 +1,65 @@
+.four-pic {
+  background: #fff;
+  overflow: hidden;
+  padding: 0 24rpx;
+  box-sizing: border-box;
+}
+.four-pic .pic {
+  padding: 24rpx 0 8rpx;
+  display: flex;
+  justify-content: space-between;
+  flex-wrap: wrap;
+}
+.four-pic .pic .pic-item {
+  position: relative;
+  margin-bottom: 16rpx;
+  padding-left: 24rpx;
+  box-sizing: border-box;
+  width: 343rpx;
+  height: 171rpx;
+  background-size: 100% 100%;
+  background-repeat: no-repeat;
+  display: flex;
+  justify-content: space-between;
+  border-radius: 10rpx;
+}
+.four-pic .pic .pic-item .text-btn {
+  position: absolute;
+  left: 0;
+  top: 0;
+}
+.four-pic .pic .pic-item .text {
+  align-self: flex-end;
+  width: 192rpx;
+  display: flex;
+  flex-direction: column;
+  margin-bottom: 9rpx;
+  justify-content: center;
+  height: 60rpx;
+}
+.four-pic .pic .pic-item .text-title {
+  max-width: 192rpx;
+  font-size: 24rpx;
+  font-weight: bold;
+}
+.four-pic .pic .pic-item .text-desc {
+  max-width: 192rpx;
+  font-size: 16rpx;
+}
+.four-pic .pic .pic-item .btn {
+  width: 72rpx;
+  height: 29rpx;
+  background-image: url('https://gw.alipayobjects.com/mdn/rms_47fd3e/afts/img/A*Y6mAT65aIlQAAAAAAAAAAABkARQnAQ');
+  align-self: flex-end;
+  background-size: 100% 100%;
+  margin: 0 29rpx 22rpx 22rpx;
+}
+.four-pic .gray {
+  width: 343rpx;
+  height: 171rpx;
+  position: absolute;
+  top: 0;
+  left: 0;
+  opacity: 0.75;
+  background-image: linear-gradient(0deg, #000 0%, rgba(60, 51, 51, 0.48) 49%, rgba(128, 90, 72, 0)) 100%;
+}

+ 22 - 0
antbuilder/core/components/four-pic/index.axml

@@ -0,0 +1,22 @@
+<view class="four-pic" a:if="{{componentData && componentData.serviceList && componentData.serviceList.length}}">
+  <service-title 
+  imgSrcPrefix="{{imgSrcPrefix}}"
+  componentData="{{componentData}}"/>
+  <view class="pic">
+    <button-auth 
+      a:for="{{componentData.serviceList}}"
+      className="pic-item" 
+      item="{{item}}"
+      style="{{`backgroundImage: url(${item.icon.length == 32 ? imgSrcPrefix + item.icon : item.icon})`}}"
+    >
+      <view class='gray'></view>
+      <view class="text-btn pic-item">
+        <view class="text">
+          <text number-of-lines="1" class="text-title" style="color: {{item.extInfo.textcolor || '#999'}}">{{item.name || ''}}</text>
+          <text number-of-lines="1" class="text-desc" style="color: {{item.extInfo.textcolor || '#FFFAD6'}}" a:if="{{item.serviceDesc}}">{{item.serviceDesc || ''}}</text>
+        </view>
+        <view class="btn"></view>
+      </view>
+    </button-auth>
+  </view>
+</view>

+ 16 - 0
antbuilder/core/components/four-pic/index.js

@@ -0,0 +1,16 @@
+import { connect } from 'herculex';
+
+const app = getApp();
+Component(connect({
+})({
+  data: {
+    imgSrcPrefix: app.globalData.imgSrcPrefix,
+  },
+  props: {
+    componentData: {},
+  },
+  didMount() {
+  },
+  methods: {
+  },
+}));

Some files were not shown because too many files changed in this diff