liyongle 3 years ago
parent
commit
fd8a75b896
  1. 13
      .stylelintrc.js
  2. 2
      public/static/offline/JSON/getActivityListByMall.json
  3. 26
      public/static/offline/JSON/getBrandShopListByIndustryId.json
  4. 28
      public/static/offline/JSON/getCustomerQRCodeList.json
  5. 21
      public/static/offline/JSON/getCustomersVoiceList.json
  6. 21
      public/static/offline/JSON/getMemberBenefits.json
  7. 28
      public/static/offline/JSON/getMemberQRCodes.json
  8. 36
      public/static/offline/JSON/getMemberServices.json
  9. 366
      public/static/offline/JSON/getServeList.json
  10. 3
      src/assets/images/member/icon_benefit.svg
  11. 3
      src/assets/images/member/icon_benefitSel.svg
  12. 3
      src/assets/images/member/icon_service.svg
  13. 3
      src/assets/images/member/icon_serviceSel.svg
  14. 4
      src/assets/images/search/bg_search.svg
  15. 3
      src/assets/images/search/icon_hand.svg
  16. 5
      src/assets/images/search/icon_keyboard.svg
  17. 3
      src/assets/images/search/key-del.svg
  18. 5
      src/assets/images/search/pos.svg
  19. 5
      src/assets/images/search/searchFirstIcon.svg
  20. 3
      src/assets/images/service/icon_Voice.svg
  21. 3
      src/assets/images/service/icon_VoiceSel.svg
  22. 3
      src/assets/images/service/icon_service.svg
  23. 3
      src/assets/images/service/icon_serviceSel.svg
  24. 7
      src/assets/images/stay_tuned2.svg
  25. 12
      src/components/ActivityDetail/ActivityDetail.vue
  26. 9
      src/components/PublicComponent/PublicComponent.vue
  27. 468
      src/components/SearchKeyboard/SearchKeyboard.vue
  28. 371
      src/components/SearchResultList/SearchResultList.vue
  29. 97
      src/components/SearchResultListItem/SearchResultListItem.vue
  30. 4
      src/components/ShopDetail/ShopDetail.vue
  31. 15
      src/components/ShopItem/ShopItem.vue
  32. 11
      src/components/SwitchTab/SwitchTab.vue
  33. 7
      src/components/Written/Written.vue
  34. 9
      src/composables/useActivityNav.ts
  35. 7
      src/composables/useServeNav.ts
  36. 9
      src/http/api/member/index.ts
  37. 9
      src/http/api/service/index.ts
  38. 10
      src/i18n/lang/en.json
  39. 10
      src/i18n/lang/tw.json
  40. 10
      src/i18n/lang/zh.json
  41. 18
      src/router/routes.ts
  42. 4
      src/store/root/actions.ts
  43. 2
      src/store/root/state.ts
  44. 32
      src/types/activity.d.ts
  45. 31
      src/types/member.d.ts
  46. 26
      src/types/serve.d.ts
  47. 1
      src/views/Activity/Activity.vue
  48. 170
      src/views/Member/Member.vue
  49. 199
      src/views/Member/MemberItem.vue
  50. 652
      src/views/Search/Search.vue
  51. 160
      src/views/Service/Service.vue
  52. 58
      src/views/Service/ServiceItem.vue

13
.stylelintrc.js

@ -18,12 +18,13 @@ module.exports = {
// 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
'no-descending-specificity': null,
'no-duplicate-selectors': null,
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: [':deep']
}
],
'selector-pseudo-element-no-unknown':null,
// [
// true,
// {
// ignorePseudoElements: [':deep']
// }
// ],
'selector-pseudo-class-no-unknown': [
true,
{

2
public/static/offline/JSON/getActivityListByMall.json

@ -14,7 +14,7 @@
"activityNameEn": "skdfjlk sadkfjs sdfje sidfsa osadf",
"startDate": "2023-07-11",
"endDate": "2023-07-29",
"point": "",
"point": "0_0_5",
"fileUrl": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/-zGlLfxNuSkVWjOQ3tsnc.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg",

26
public/static/offline/JSON/getBrandShopListByIndustryId.json

@ -267,7 +267,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[852, 30, -140]",
"yaxis": "33",
"doorMaterialList": [],
@ -313,7 +313,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[1094, 30, -36]",
"yaxis": "35",
"doorMaterialList": [],
@ -359,7 +359,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[1708, 30, -14]",
"yaxis": "37",
"doorMaterialList": [],
@ -405,7 +405,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[806, 30, 460]",
"yaxis": "45",
"doorMaterialList": [],
@ -451,7 +451,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[387.5, 30, 277.5]",
"yaxis": "50",
"doorMaterialList": [],
@ -497,7 +497,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[-1160, 30, 188]",
"yaxis": "63",
"doorMaterialList": [],
@ -543,7 +543,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[-2010, 30, 504]",
"yaxis": "70",
"doorMaterialList": [],
@ -589,7 +589,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[-1777, 30, -428]",
"yaxis": "70",
"doorMaterialList": [],
@ -635,7 +635,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[-1372, 30, -383]",
"yaxis": "3",
"doorMaterialList": [],
@ -681,7 +681,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[-850, 30, -461]",
"yaxis": "7",
"doorMaterialList": [],
@ -727,7 +727,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[-272, 30, -488]",
"yaxis": "10",
"doorMaterialList": [],
@ -773,7 +773,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[33, 30, -371]",
"yaxis": "13",
"doorMaterialList": [],
@ -819,7 +819,7 @@
"thirdKouCode": "",
"thirdMeiCode": "",
"thirdZhiCode": "",
"isNewShop": 0,
"isNewShop": 1,
"xaxis": "[470, 30, -188]",
"yaxis": "17",
"doorMaterialList": [],

28
public/static/offline/JSON/getCustomerQRCodeList.json

@ -0,0 +1,28 @@
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 176,
"title": "111",
"content": {
"name": "1121kldlfja付了款撒接待来访老师的咖啡机烧腊店啊打开分离焦虑肯定萨芬",
"nameEn": "enend ksdlf saldfsad sdf sasdf ",
"file_code": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230713/kW6aF3LAzSP4gXRjV2YPu.jpg"
]
}
},
{
"id": 177,
"title": "222",
"content": {
"name": "222",
"nameEn": "2321321321",
"file_code": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230713/lJumzle3ceq6X6QbmSTYW.jpg"
]
}
}
]
}

21
public/static/offline/JSON/getCustomersVoiceList.json

@ -0,0 +1,21 @@
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 175,
"title": "顾客心声介绍",
"content": {
"name": "萨迪克发链接撒离开的 数量肯定放假了肯定萨芬记录开始的",
"nameEn": "endf ksfd asdfl sdf sfoiwaf sldf sd sdfoisdf ",
"content": "Lfjsalkdfj斐林试剂地方两件事都发了可接受的佛i聚少离多咖啡机哦i哇激发莱克斯顿发记录开始的就分手了打客服就算了地方拒收到付是的",
"contentEn": "fkd kfsld slkdf jsfiaojflsakdf lskdjf oisajfsldkfs lkjsdfoiwjflksdfj oijdf sld fjsd f",
"file_code": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230713/tHv3EixQowwdP_AaqcS3F.jpg",
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230713/Kf8vNyeU1Q0fkyXbzeP6x.jpg",
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230713/6EVTskx9iJgvTAtnrZlyi.jpg"
]
}
}
]
}

21
public/static/offline/JSON/getMemberBenefits.json

@ -0,0 +1,21 @@
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 166,
"title": "会员权益列表",
"content": {
"name": "会员权益会员权益会员权益会员权益会员权益会员权益会员权益",
"nameEn": "enen enen enen enen",
"content": "介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊\n介绍接啊介绍接啊介绍接啊介绍接啊\n介绍接啊介绍接啊介绍接啊\n介绍接啊介绍接啊介绍接啊\n介绍接啊介绍接啊\n介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊\n介绍接啊介绍接啊介绍接啊\n介绍接啊介绍接啊vv介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊介绍接啊\n介绍接啊介绍接啊",
"contentEn": "sdfslkd \nsadfklsdf\nsdfkljsdfe sdfklsdf sdkfsdkfewfds sdkfjdsfiewofjdslkfsd kfdssadf \nklsdjflksadfsdfoiwfalkdf sdlkfjsdlf sldkf sldf sld fsldk fsld fds \nsadjfslkdf ",
"file_code": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230712/lI16FO1aVrU-bHiLeu0Nv.jpg",
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230712/vOD2AAX4oqxsQlnLCaHgG.jpg",
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230712/SxJ9UA3ouMC1bHg3gdU6t.jpg"
]
}
}
]
}

28
public/static/offline/JSON/getMemberQRCodes.json

@ -0,0 +1,28 @@
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 167,
"title": "二维码",
"content": {
"name": "扫码加入会员",
"nameEn": "asfdsadf sa sdf sadfsadfsa sdfsad ",
"file_code": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230712/1lnYOxTQf4mNUUCn6_aQJ.jpg"
]
}
},
{
"id": 168,
"title": "kk",
"content": {
"name": "kkjkj撒旦法撒旦法水电费水电费是的就开了记录卡颗粒剂离开",
"nameEn": "dsf sdfsfds sdfsaf sd sdfsda sd fsd ",
"file_code": [
"/iotFile/project-ey_fpaur6s6fkgvszywana/20230712/nRvdtzNDmRSZGmsc7KKrT.jpg"
]
}
}
]
}

36
public/static/offline/JSON/getMemberServices.json

@ -0,0 +1,36 @@
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 169,
"title": "服务",
"content": {
"name": "标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题标题",
"nameEn": "enenenenen afds sdfksadfs sdklf sdaf sld fdsl flkdfjlsda sfd sal kfsda f",
"content": "j内容啊舒服点撒旦法老师的发多少水电费萨达李开复 离开打扫房间莱克斯顿方式迪卢克发送六点十分拉倒烦死了地方蓝色吉林省东方律师老师的烦死了都 \n撒恐龙当家防守打法塑料袋咖啡机塑料袋就放莱克斯顿结果拉倒发了独守空房离开第三方吉林省快递费记录开始的就放离开时代峰峻\n莱克斯顿减肥路上看来是快递费来上课樊登读书\n流口水就分手了东方闪电方吉林省快递费记录开始的就放离开时代峰峻\n莱克斯顿减肥路上看来是快递费来上课樊登读书\n流口水就分手了东方闪电方吉林省快递费记录开始的就放离开时代峰峻\n莱克斯顿减肥路上看来是快递费来上课樊登读书\n流口水就分手了东方闪电方吉林省快递费记录开始的就放离开时代峰峻\n莱克斯顿减肥路上看来是快递费来上课樊登读书\n流口水就分手了东方闪电方吉林省快递费记录开始的就放离开时代峰峻\n莱克斯顿减肥路上看来是快递费来上课樊登读书\n流口水就分手了东方闪电",
"contentEn": "enn sdfjslkfjsadlf sdlkf jslkdf jsdlkfdsalk jslkfsadlsdalkfsdjfsafd\nslkadfjlsakdfsaldkfjsaldf \nsdflsakdfsadlkf sdf\n slkdfjslkdfsdaf\n lksdfjlskaf lkjdsa",
"point": "",
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/Utv2WUsWWn4hYGKLe0sHA.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/TDc5S9Z6KiVElVCqooqMj.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/4uc43wEhBVypicoGmpLlr.jpg"
]
}
},
{
"id": 170,
"title": "服务快快快",
"content": {
"name": "看见了科技离开离开里",
"nameEn": "kkk",
"content": "kjlkj",
"contentEn": "kljlkjlkjlk",
"point": "0_0_152",
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/Yjr_3RuhALV1g8vU5-Ues.jpg"
]
}
}
]
}

366
public/static/offline/JSON/getServeList.json

@ -1,73 +1,313 @@
{
"code": 200,
"msg": "操作成功",
"data": {
"serveList": [
"data": [
{
"name": "雨伞租借",
"nameEn": "978",
"logoUrl": "/iotFile/project-zert3dski8fqmgr4zhusea/20230601/XShSbsU3VEEYDkQm9rM2E.jpg",
"fileUrl": "/iotFile/project-zert3dski8fqmgr4zhusea/20230601/QpbjfkbCODU5aVNuYAli9.jpg",
"fileUrls": [
"/iotFile/project-zert3dski8fqmgr4zhusea/20230601/QpbjfkbCODU5aVNuYAli9.jpg",
"/iotFile/project-zert3dski8fqmgr4zhusea/20230607/A-CmfymHNUGm0mhGFy7CU.png",
"/iotFile/project-zert3dski8fqmgr4zhusea/20230607/bWHtYY01TIsGbiS5QVDM8.png",
"/iotFile/project-zert3dski8fqmgr4zhusea/20230607/tMBspEmPjh8_GQgNBxHKO.png"
],
"qrUrl": "/iotFile/project-zert3dski8fqmgr4zhusea/20230607/L4GB4WvBcah4iiThrFSgK.png",
"content": "租借雨伞了啊",
"contentEn": "租借雨伞了啊",
"isPoint": 2,
"building": "",
"buildingCode": "",
"buildingOrder": 0,
"floor": "",
"floorCode": "",
"floorOrder": 0,
"point": -1
"id": 108,
"title": "服务1",
"content": {
"name": "服务设施测试名称服务设施测试名称服务设施测试名称",
"nameEn": "ljgdsfl lsakjfdl\nlksadjflssadf lsadfj",
"content": "借号阿斯蒂芬拉萨客服经理手打就发了水电费吉林省就发了独守空房蓝思科技烦死了地方\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机",
"contentEn": "sklf sldfj sdfds sdfjiofldsfdsl oijffsofsfspdsnfvs fsldfjsdfowefjsdlfds sdfsafds fowi jfsldfjldsa jfoisafwofdslf jlsfdjsaofjwlfdsjf lsadfoisafj lds jldsf jsoa ",
"point": "",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/fLh_hxEjrJqd90sE3M0mh.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/ghPJXBUeW9XJBSMijOEYf.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},
{
"name": "充电宝",
"nameEn": "bao",
"logoUrl": "/iotFile/project-zert3dski8fqmgr4zhusea/20230601/TT4qvTjHO_mZ2e3gv8IgS.jpg",
"fileUrl": "/iotFile/project-zert3dski8fqmgr4zhusea/20230601/hPk5Z0Q5TRBgTt-IfPOLN.jpg",
"fileUrls": [
"/iotFile/project-zert3dski8fqmgr4zhusea/20230601/hPk5Z0Q5TRBgTt-IfPOLN.jpg"
"id": 109,
"title": "服务2",
"content": {
"name": "服务设施2",
"nameEn": "dsafljffa skldjf ",
"content": "lksadjflaj la分类了解萨克大姐夫雷克萨就发了卡萨丁就发了卡萨丁甲方拉萨到付件拉倒就发了萨达就发了撒旦法记录卡打撒金佛IE忘记发啦扩大升级弗利萨就 ",
"contentEn": "lkf lsjflksdjlkf lsf lskd flsafjlsadf jwiofjlsadfj oiajfldjsa ldisfjsldakf lkssjdlkf jsadisdf l",
"point": "0_0_14",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},{
"id": 108,
"title": "服务1",
"content": {
"name": "服务设施测试名称服务设施测试名称服务设施测试名称",
"nameEn": "ljgdsfl lsakjfdl\nlksadjflssadf lsadfj",
"content": "借号阿斯蒂芬拉萨客服经理手打就发了水电费吉林省就发了独守空房蓝思科技烦死了地方\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机",
"contentEn": "sklf sldfj sdfds sdfjiofldsfdsl oijffsofsfspdsnfvs fsldfjsdfowefjsdlfds sdfsafds fowi jfsldfjldsa jfoisafwofdslf jlsfdjsaofjwlfdsjf lsadfoisafj lds jldsf jsoa ",
"point": "",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/fLh_hxEjrJqd90sE3M0mh.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/ghPJXBUeW9XJBSMijOEYf.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},
{
"id": 109,
"title": "服务2",
"content": {
"name": "服务设施2",
"nameEn": "dsafljffa skldjf ",
"content": "lksadjflaj la分类了解萨克大姐夫雷克萨就发了卡萨丁就发了卡萨丁甲方拉萨到付件拉倒就发了萨达就发了撒旦法记录卡打撒金佛IE忘记发啦扩大升级弗利萨就 ",
"contentEn": "lkf lsjflksdjlkf lsf lskd flsafjlsadf jwiofjlsadfj oiajfldjsa ldisfjsldakf lkssjdlkf jsadisdf l",
"point": "0_0_14",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},{
"id": 108,
"title": "服务1",
"content": {
"name": "服务设施测试名称服务设施测试名称服务设施测试名称",
"nameEn": "ljgdsfl lsakjfdl\nlksadjflssadf lsadfj",
"content": "借号阿斯蒂芬拉萨客服经理手打就发了水电费吉林省就发了独守空房蓝思科技烦死了地方\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机",
"contentEn": "sklf sldfj sdfds sdfjiofldsfdsl oijffsofsfspdsnfvs fsldfjsdfowefjsdlfds sdfsafds fowi jfsldfjldsa jfoisafwofdslf jlsfdjsaofjwlfdsjf lsadfoisafj lds jldsf jsoa ",
"point": "",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/fLh_hxEjrJqd90sE3M0mh.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/ghPJXBUeW9XJBSMijOEYf.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},
{
"id": 109,
"title": "服务2",
"content": {
"name": "服务设施2",
"nameEn": "dsafljffa skldjf ",
"content": "lksadjflaj la分类了解萨克大姐夫雷克萨就发了卡萨丁就发了卡萨丁甲方拉萨到付件拉倒就发了萨达就发了撒旦法记录卡打撒金佛IE忘记发啦扩大升级弗利萨就 ",
"contentEn": "lkf lsjflksdjlkf lsf lskd flsafjlsadf jwiofjlsadfj oiajfldjsa ldisfjsldakf lkssjdlkf jsadisdf l",
"point": "0_0_14",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},{
"id": 108,
"title": "服务1",
"content": {
"name": "服务设施测试名称服务设施测试名称服务设施测试名称",
"nameEn": "ljgdsfl lsakjfdl\nlksadjflssadf lsadfj",
"content": "借号阿斯蒂芬拉萨客服经理手打就发了水电费吉林省就发了独守空房蓝思科技烦死了地方\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机",
"contentEn": "sklf sldfj sdfds sdfjiofldsfdsl oijffsofsfspdsnfvs fsldfjsdfowefjsdlfds sdfsafds fowi jfsldfjldsa jfoisafwofdslf jlsfdjsaofjwlfdsjf lsadfoisafj lds jldsf jsoa ",
"point": "",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/fLh_hxEjrJqd90sE3M0mh.jpg"
],
"qrUrl": "/iotFile/project-zert3dski8fqmgr4zhusea/20230601/Euz5BcOe5i4Ua4Tz0Cbo-.jpg",
"content": "免费充电宝",
"contentEn": "123",
"isPoint": 2,
"building": "",
"buildingCode": "",
"buildingOrder": 0,
"floor": "",
"floorCode": "",
"floorOrder": 0,
"point": -1
},
{
"name": "122312",
"nameEn": "",
"logoUrl": "/iotFile/project-zert3dski8fqmgr4zhusea/20230607/3YwrjhTZPukVbfh9YBQKX.png",
"fileUrl": "/iotFile/project-zert3dski8fqmgr4zhusea/20230607/BShONSttRX_UshFJqkrte.png",
"fileUrls": [
"/iotFile/project-zert3dski8fqmgr4zhusea/20230607/BShONSttRX_UshFJqkrte.png",
"/iotFile/project-zert3dski8fqmgr4zhusea/20230607/mbFngD46RgsP5qmc6NH80.png",
"/iotFile/project-zert3dski8fqmgr4zhusea/20230607/rNjUR4eGWQkwJ8uAKjWGl.png"
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/ghPJXBUeW9XJBSMijOEYf.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},
{
"id": 109,
"title": "服务2",
"content": {
"name": "服务设施2",
"nameEn": "dsafljffa skldjf ",
"content": "lksadjflaj la分类了解萨克大姐夫雷克萨就发了卡萨丁就发了卡萨丁甲方拉萨到付件拉倒就发了萨达就发了撒旦法记录卡打撒金佛IE忘记发啦扩大升级弗利萨就 ",
"contentEn": "lkf lsjflksdjlkf lsf lskd flsafjlsadf jwiofjlsadfj oiajfldjsa ldisfjsldakf lkssjdlkf jsadisdf l",
"point": "0_0_14",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
],
"qrUrl": "/iotFile/project-zert3dski8fqmgr4zhusea/20230607/0Undp5msC2GA1hrxqZ7VH.png",
"content": "123123",
"contentEn": "",
"isPoint": 2,
"building": "A栋",
"buildingCode": "DLvmtzN2qodUq_oYr7vyM",
"buildingOrder": 0,
"floor": "L2",
"floorCode": "7Q5J4mfRebZR_t_PKeEDJ",
"floorOrder": 3,
"point": 40
}
]
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},{
"id": 108,
"title": "服务1",
"content": {
"name": "服务设施测试名称服务设施测试名称服务设施测试名称",
"nameEn": "ljgdsfl lsakjfdl\nlksadjflssadf lsadfj",
"content": "借号阿斯蒂芬拉萨客服经理手打就发了水电费吉林省就发了独守空房蓝思科技烦死了地方\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机",
"contentEn": "sklf sldfj sdfds sdfjiofldsfdsl oijffsofsfspdsnfvs fsldfjsdfowefjsdlfds sdfsafds fowi jfsldfjldsa jfoisafwofdslf jlsfdjsaofjwlfdsjf lsadfoisafj lds jldsf jsoa ",
"point": "",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/fLh_hxEjrJqd90sE3M0mh.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/ghPJXBUeW9XJBSMijOEYf.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},
{
"id": 109,
"title": "服务2",
"content": {
"name": "服务设施2",
"nameEn": "dsafljffa skldjf ",
"content": "lksadjflaj la分类了解萨克大姐夫雷克萨就发了卡萨丁就发了卡萨丁甲方拉萨到付件拉倒就发了萨达就发了撒旦法记录卡打撒金佛IE忘记发啦扩大升级弗利萨就 ",
"contentEn": "lkf lsjflksdjlkf lsf lskd flsafjlsadf jwiofjlsadfj oiajfldjsa ldisfjsldakf lkssjdlkf jsadisdf l",
"point": "0_0_14",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},{
"id": 108,
"title": "服务1",
"content": {
"name": "服务设施测试名称服务设施测试名称服务设施测试名称",
"nameEn": "ljgdsfl lsakjfdl\nlksadjflssadf lsadfj",
"content": "借号阿斯蒂芬拉萨客服经理手打就发了水电费吉林省就发了独守空房蓝思科技烦死了地方\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机",
"contentEn": "sklf sldfj sdfds sdfjiofldsfdsl oijffsofsfspdsnfvs fsldfjsdfowefjsdlfds sdfsafds fowi jfsldfjldsa jfoisafwofdslf jlsfdjsaofjwlfdsjf lsadfoisafj lds jldsf jsoa ",
"point": "",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/fLh_hxEjrJqd90sE3M0mh.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/ghPJXBUeW9XJBSMijOEYf.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},
{
"id": 109,
"title": "服务2",
"content": {
"name": "服务设施2",
"nameEn": "dsafljffa skldjf ",
"content": "lksadjflaj la分类了解萨克大姐夫雷克萨就发了卡萨丁就发了卡萨丁甲方拉萨到付件拉倒就发了萨达就发了撒旦法记录卡打撒金佛IE忘记发啦扩大升级弗利萨就 ",
"contentEn": "lkf lsjflksdjlkf lsf lskd flsafjlsadf jwiofjlsadfj oiajfldjsa ldisfjsldakf lkssjdlkf jsadisdf l",
"point": "0_0_14",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},{
"id": 108,
"title": "服务1",
"content": {
"name": "服务设施测试名称服务设施测试名称服务设施测试名称",
"nameEn": "ljgdsfl lsakjfdl\nlksadjflssadf lsadfj",
"content": "借号阿斯蒂芬拉萨客服经理手打就发了水电费吉林省就发了独守空房蓝思科技烦死了地方\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机",
"contentEn": "sklf sldfj sdfds sdfjiofldsfdsl oijffsofsfspdsnfvs fsldfjsdfowefjsdlfds sdfsafds fowi jfsldfjldsa jfoisafwofdslf jlsfdjsaofjwlfdsjf lsadfoisafj lds jldsf jsoa ",
"point": "",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/fLh_hxEjrJqd90sE3M0mh.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/ghPJXBUeW9XJBSMijOEYf.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},
{
"id": 109,
"title": "服务2",
"content": {
"name": "服务设施2",
"nameEn": "dsafljffa skldjf ",
"content": "lksadjflaj la分类了解萨克大姐夫雷克萨就发了卡萨丁就发了卡萨丁甲方拉萨到付件拉倒就发了萨达就发了撒旦法记录卡打撒金佛IE忘记发啦扩大升级弗利萨就 ",
"contentEn": "lkf lsjflksdjlkf lsf lskd flsafjlsadf jwiofjlsadfj oiajfldjsa ldisfjsldakf lkssjdlkf jsadisdf l",
"point": "0_0_14",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},{
"id": 108,
"title": "服务1",
"content": {
"name": "服务设施测试名称服务设施测试名称服务设施测试名称",
"nameEn": "ljgdsfl lsakjfdl\nlksadjflssadf lsadfj",
"content": "借号阿斯蒂芬拉萨客服经理手打就发了水电费吉林省就发了独守空房蓝思科技烦死了地方\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机",
"contentEn": "sklf sldfj sdfds sdfjiofldsfdsl oijffsofsfspdsnfvs fsldfjsdfowefjsdlfds sdfsafds fowi jfsldfjldsa jfoisafwofdslf jlsfdjsaofjwlfdsjf lsadfoisafj lds jldsf jsoa ",
"point": "",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/fLh_hxEjrJqd90sE3M0mh.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/ghPJXBUeW9XJBSMijOEYf.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},
{
"id": 109,
"title": "服务2",
"content": {
"name": "服务设施2",
"nameEn": "dsafljffa skldjf ",
"content": "lksadjflaj la分类了解萨克大姐夫雷克萨就发了卡萨丁就发了卡萨丁甲方拉萨到付件拉倒就发了萨达就发了撒旦法记录卡打撒金佛IE忘记发啦扩大升级弗利萨就 ",
"contentEn": "lkf lsjflksdjlkf lsf lskd flsafjlsadf jwiofjlsadfj oiajfldjsa ldisfjsldakf lkssjdlkf jsadisdf l",
"point": "0_0_14",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},{
"id": 108,
"title": "服务1",
"content": {
"name": "服务设施测试名称服务设施测试名称服务设施测试名称",
"nameEn": "ljgdsfl lsakjfdl\nlksadjflssadf lsadfj",
"content": "借号阿斯蒂芬拉萨客服经理手打就发了水电费吉林省就发了独守空房蓝思科技烦死了地方\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机\n离开时间弗利萨大姐夫ls索拉卡大飞机雷克萨戴假发\n\n索拉卡范德萨解放东路吉林省\n索拉卡党风建设两地分居\n索拉卡动静分离萨克大飞机",
"contentEn": "sklf sldfj sdfds sdfjiofldsfdsl oijffsofsfspdsnfvs fsldfjsdfowefjsdlfds sdfsafds fowi jfsldfjldsa jfoisafwofdslf jlsfdjsaofjwlfdsjf lsadfoisafj lds jldsf jsoa ",
"point": "",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/fLh_hxEjrJqd90sE3M0mh.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/ghPJXBUeW9XJBSMijOEYf.jpg",
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
},
{
"id": 109,
"title": "服务2",
"content": {
"name": "服务设施2",
"nameEn": "dsafljffa skldjf ",
"content": "lksadjflaj la分类了解萨克大姐夫雷克萨就发了卡萨丁就发了卡萨丁甲方拉萨到付件拉倒就发了萨达就发了撒旦法记录卡打撒金佛IE忘记发啦扩大升级弗利萨就 ",
"contentEn": "lkf lsjflksdjlkf lsf lskd flsafjlsadf jwiofjlsadfj oiajfldjsa ldisfjsldakf lkssjdlkf jsadisdf l",
"point": "0_0_14",
"logo_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
],
"file_code": [
"/iotFile/project-odubitlp9mjy2wyuqkpfga/20230609/q8hsY2vPMJ1XNG4S1hXJV.jpg"
]
}
}
]
}

3
src/assets/images/member/icon_benefit.svg

@ -0,0 +1,3 @@
<svg width="28" height="26" viewBox="0 0 28 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.666504 23.3327H27.3332V25.9993H0.666504V23.3327ZM0.666504 4.66602L7.33317 9.33268L13.9998 0.666016L20.6665 9.33268L27.3332 4.66602V20.666H0.666504V4.66602ZM3.33317 9.78735V17.9993H24.6665V9.78735L20.1065 12.9793L13.9998 5.03935L7.89317 12.9793L3.33317 9.78602V9.78735Z" fill="#8E9090"/>
</svg>

After

Width:  |  Height:  |  Size: 402 B

3
src/assets/images/member/icon_benefitSel.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.6665 25.3327H29.3332V27.9993H2.6665V25.3327ZM2.6665 6.66602L9.33317 11.3327L15.9998 2.66602L22.6665 11.3327L29.3332 6.66602V22.666H2.6665V6.66602ZM5.33317 11.7873V19.9993H26.6665V11.7873L22.1065 14.9793L15.9998 7.03935L9.89317 14.9793L5.33317 11.786V11.7873Z" fill="#E00068"/>
</svg>

After

Width:  |  Height:  |  Size: 392 B

3
src/assets/images/member/icon_service.svg

@ -0,0 +1,3 @@
<svg width="33" height="32" viewBox="0 0 33 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.5002 2.66602C21.4365 2.66591 22.3564 2.91233 23.1674 3.38051C23.9783 3.84869 24.6517 4.52211 25.1198 5.33308C25.5879 6.14405 25.8343 7.06397 25.8341 8.00035C25.834 8.93673 25.5873 9.85656 25.1188 10.6674L31.1668 10.666V13.3327H28.5002V26.666C28.5002 27.0196 28.3597 27.3588 28.1096 27.6088C27.8596 27.8589 27.5204 27.9994 27.1668 27.9994H5.8335C5.47987 27.9994 5.14074 27.8589 4.89069 27.6088C4.64064 27.3588 4.50016 27.0196 4.50016 26.666V13.3327H1.8335V10.666L7.8815 10.6674C7.21998 9.52187 7.00775 8.17143 7.28601 6.87825C7.56427 5.58508 8.31316 4.44145 9.38727 3.66943C10.4614 2.89741 11.7841 2.55209 13.0985 2.70053C14.4129 2.84897 15.6253 3.48057 16.5002 4.47269C16.9996 3.90387 17.6149 3.44839 18.3048 3.13679C18.9947 2.8252 19.7432 2.66469 20.5002 2.66602V2.66602ZM15.1668 13.3327H7.16683V25.3327H15.1668V13.3327ZM25.8335 13.3327H17.8335V25.3327H25.8335V13.3327ZM12.5002 5.33269C11.8082 5.32959 11.1421 5.59561 10.6426 6.07453C10.1432 6.55345 9.8494 7.20778 9.82344 7.89928C9.79748 8.59077 10.0413 9.26528 10.5035 9.78031C10.9656 10.2953 11.6099 10.6106 12.3002 10.6594L12.5002 10.666H15.1668V7.99936C15.1669 7.36211 14.9387 6.74591 14.5236 6.26237C14.1086 5.77882 13.5341 5.4599 12.9042 5.36336L12.6988 5.33936L12.5002 5.33269ZM20.5002 5.33269C19.8274 5.33248 19.1794 5.58657 18.6861 6.04402C18.1928 6.50147 17.8906 7.12848 17.8402 7.79936L17.8335 7.99936V10.666H20.5002C21.1729 10.6662 21.8209 10.4121 22.3142 9.95469C22.8075 9.49724 23.1097 8.87023 23.1602 8.19936L23.1668 7.99936C23.1668 7.29211 22.8859 6.61384 22.3858 6.11374C21.8857 5.61364 21.2074 5.33269 20.5002 5.33269V5.33269Z" fill="#8E9090"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

3
src/assets/images/member/icon_serviceSel.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.0002 2.66602C20.9365 2.66591 21.8564 2.91233 22.6674 3.38051C23.4783 3.84869 24.1517 4.52211 24.6198 5.33308C25.0879 6.14405 25.3343 7.06397 25.3341 8.00035C25.334 8.93673 25.0873 9.85656 24.6188 10.6674L30.6668 10.666V13.3327H28.0002V26.666C28.0002 27.0196 27.8597 27.3588 27.6096 27.6088C27.3596 27.8589 27.0204 27.9994 26.6668 27.9994H5.3335C4.97987 27.9994 4.64074 27.8589 4.39069 27.6088C4.14064 27.3588 4.00016 27.0196 4.00016 26.666V13.3327H1.3335V10.666L7.3815 10.6674C6.71998 9.52187 6.50775 8.17143 6.78601 6.87825C7.06427 5.58508 7.81316 4.44145 8.88727 3.66943C9.96139 2.89741 11.2841 2.55209 12.5985 2.70053C13.9129 2.84897 15.1253 3.48057 16.0002 4.47269C16.4996 3.90387 17.1149 3.44839 17.8048 3.13679C18.4947 2.8252 19.2432 2.66469 20.0002 2.66602V2.66602ZM14.6668 13.3327H6.66683V25.3327H14.6668V13.3327ZM25.3335 13.3327H17.3335V25.3327H25.3335V13.3327ZM12.0002 5.33269C11.3082 5.32959 10.6421 5.59561 10.1426 6.07453C9.64315 6.55345 9.3494 7.20778 9.32344 7.89928C9.29748 8.59077 9.54133 9.26528 10.0035 9.78031C10.4656 10.2953 11.1099 10.6106 11.8002 10.6594L12.0002 10.666H14.6668V7.99936C14.6669 7.36211 14.4387 6.74591 14.0236 6.26237C13.6086 5.77882 13.0341 5.4599 12.4042 5.36336L12.1988 5.33936L12.0002 5.33269ZM20.0002 5.33269C19.3274 5.33248 18.6794 5.58657 18.1861 6.04402C17.6928 6.50147 17.3906 7.12848 17.3402 7.79936L17.3335 7.99936V10.666H20.0002C20.6729 10.6662 21.3209 10.4121 21.8142 9.95469C22.3075 9.49724 22.6097 8.87023 22.6602 8.19936L22.6668 7.99936C22.6668 7.29211 22.3859 6.61384 21.8858 6.11374C21.3857 5.61364 20.7074 5.33269 20.0002 5.33269V5.33269Z" fill="#E00068"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

4
src/assets/images/search/bg_search.svg

@ -0,0 +1,4 @@
<svg width="368" height="72" viewBox="0 0 368 72" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="368" height="72" rx="24" fill="black" fill-opacity="0.03"/>
<rect x="0.5" y="0.5" width="367" height="71" rx="23.5" stroke="black" stroke-opacity="0.1"/>
</svg>

After

Width:  |  Height:  |  Size: 272 B

3
src/assets/images/search/icon_hand.svg

@ -0,0 +1,3 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M29.7483 19.68L28.57 18.5017L12.07 35.0017H5V27.93L23.855 9.07338L33.2833 18.5017C33.5958 18.8143 33.7713 19.2381 33.7713 19.68C33.7713 20.122 33.5958 20.5458 33.2833 20.8584L21.5 32.6434L19.1417 30.2867L29.7483 19.68ZM26.2133 16.145L23.855 13.7884L8.33333 29.31V31.6684H10.69L26.2133 16.145ZM30.9267 4.36005L35.6417 9.07338C35.9541 9.38593 36.1296 9.80977 36.1296 10.2517C36.1296 10.6937 35.9541 11.1175 35.6417 11.43L33.2833 13.7884L26.2133 6.71671L28.57 4.36005C28.8825 4.0476 29.3064 3.87207 29.7483 3.87207C30.1903 3.87207 30.6141 4.0476 30.9267 4.36005Z" fill="#8E9090"/>
</svg>

After

Width:  |  Height:  |  Size: 690 B

5
src/assets/images/search/icon_keyboard.svg

@ -0,0 +1,5 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="&#229;&#138;&#159;&#232;&#131;&#189;/&#233;&#148;&#174;&#231;&#155;&#152;">
<path id="icons" d="M6.66683 8.33333V31.6667H33.3335V8.33333H6.66683ZM5.00016 5H35.0002C35.4422 5 35.8661 5.17559 36.1787 5.48816C36.4912 5.80072 36.6668 6.22464 36.6668 6.66667V33.3333C36.6668 33.7754 36.4912 34.1993 36.1787 34.5118C35.8661 34.8244 35.4422 35 35.0002 35H5.00016C4.55814 35 4.13421 34.8244 3.82165 34.5118C3.50909 34.1993 3.3335 33.7754 3.3335 33.3333V6.66667C3.3335 6.22464 3.50909 5.80072 3.82165 5.48816C4.13421 5.17559 4.55814 5 5.00016 5ZM10.0002 11.6667H13.3335V15H10.0002V11.6667ZM10.0002 18.3333H13.3335V21.6667H10.0002V18.3333ZM10.0002 25H30.0002V28.3333H10.0002V25ZM18.3335 18.3333H21.6668V21.6667H18.3335V18.3333ZM18.3335 11.6667H21.6668V15H18.3335V11.6667ZM26.6668 11.6667H30.0002V15H26.6668V11.6667ZM26.6668 18.3333H30.0002V21.6667H26.6668V18.3333Z" fill="#8E9090"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 988 B

3
src/assets/images/search/key-del.svg

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.44584 2.5H17.5C17.721 2.5 17.933 2.5878 18.0893 2.74408C18.2455 2.90036 18.3333 3.11232 18.3333 3.33333V16.6667C18.3333 16.8877 18.2455 17.0996 18.0893 17.2559C17.933 17.4122 17.721 17.5 17.5 17.5H5.44584C5.30868 17.5 5.17363 17.4662 5.05268 17.4015C4.93174 17.3368 4.82863 17.2433 4.7525 17.1292L0.308338 10.4625C0.216972 10.3256 0.168213 10.1646 0.168213 10C0.168213 9.83538 0.216972 9.67444 0.308338 9.5375L4.7525 2.87083C4.82863 2.75674 4.93174 2.66319 5.05268 2.5985C5.17363 2.53381 5.30868 2.49998 5.44584 2.5ZM5.89167 4.16667L2.00334 10L5.89167 15.8333H16.6667V4.16667H5.89167ZM10.8333 8.82167L13.19 6.46417L14.3692 7.64333L12.0117 10L14.3692 12.3567L13.19 13.5358L10.8333 11.1783L8.47667 13.5358L7.2975 12.3567L9.655 10L7.2975 7.64333L8.47667 6.46417L10.8333 8.82167Z" fill="#8E9090"/>
</svg>

After

Width:  |  Height:  |  Size: 909 B

5
src/assets/images/search/pos.svg

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon/&#229;&#138;&#159;&#232;&#131;&#189;/&#231;&#187;&#136;&#231;&#130;&#185;_&#231;&#153;&#189;">
<path id="icons" d="M10 17.4169L14.125 13.2919C14.9408 12.4761 15.4963 11.4367 15.7213 10.3052C15.9463 9.17362 15.8308 8.00076 15.3892 6.93489C14.9477 5.86902 14.2 4.95802 13.2408 4.31707C12.2815 3.67612 11.1537 3.33401 10 3.33401C8.8463 3.33401 7.71851 3.67612 6.75924 4.31707C5.79997 4.95802 5.05229 5.86902 4.61076 6.93489C4.16923 8.00076 4.05368 9.17362 4.27871 10.3052C4.50374 11.4367 5.05926 12.4761 5.875 13.2919L10 17.4169ZM10 19.7736L4.69667 14.4703C3.64779 13.4214 2.93349 12.085 2.64411 10.6301C2.35473 9.17528 2.50326 7.66729 3.07092 6.29685C3.63858 4.9264 4.59987 3.75507 5.83324 2.93096C7.0666 2.10686 8.51665 1.66699 10 1.66699C11.4834 1.66699 12.9334 2.10686 14.1668 2.93096C15.4001 3.75507 16.3614 4.9264 16.9291 6.29685C17.4968 7.66729 17.6453 9.17528 17.3559 10.6301C17.0665 12.085 16.3522 13.4214 15.3033 14.4703L10 19.7736ZM10 10.8336C10.442 10.8336 10.866 10.658 11.1785 10.3454C11.4911 10.0329 11.6667 9.60896 11.6667 9.16693C11.6667 8.7249 11.4911 8.30098 11.1785 7.98842C10.866 7.67586 10.442 7.50026 10 7.50026C9.55798 7.50026 9.13405 7.67586 8.82149 7.98842C8.50893 8.30098 8.33334 8.7249 8.33334 9.16693C8.33334 9.60896 8.50893 10.0329 8.82149 10.3454C9.13405 10.658 9.55798 10.8336 10 10.8336ZM10 12.5003C9.11595 12.5003 8.2681 12.1491 7.64298 11.524C7.01786 10.8988 6.66667 10.051 6.66667 9.16693C6.66667 8.28287 7.01786 7.43503 7.64298 6.80991C8.2681 6.18478 9.11595 5.83359 10 5.83359C10.8841 5.83359 11.7319 6.18478 12.357 6.80991C12.9821 7.43503 13.3333 8.28287 13.3333 9.16693C13.3333 10.051 12.9821 10.8988 12.357 11.524C11.7319 12.1491 10.8841 12.5003 10 12.5003Z" fill="#615C59"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

5
src/assets/images/search/searchFirstIcon.svg

@ -0,0 +1,5 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="&#229;&#159;&#186;&#231;&#161;&#128;/&#229;&#138;&#159;&#232;&#131;&#189;/&#230;&#144;&#156;&#231;&#180;&#162;">
<path id="&#231;&#159;&#162;&#233;&#135;&#143;" d="M18.3334 3.33301C26.6134 3.33301 33.3334 10.053 33.3334 18.333C33.3334 26.613 26.6134 33.333 18.3334 33.333C10.0534 33.333 3.33337 26.613 3.33337 18.333C3.33337 10.053 10.0534 3.33301 18.3334 3.33301ZM18.3334 29.9997C24.7784 29.9997 30 24.778 30 18.333C30 11.8863 24.7784 6.66634 18.3334 6.66634C11.8867 6.66634 6.66671 11.8863 6.66671 18.333C6.66671 24.778 11.8867 29.9997 18.3334 29.9997ZM32.475 30.118L37.19 34.8313L34.8317 37.1897L30.1184 32.4747L32.475 30.118Z" fill="#8E9090"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 763 B

3
src/assets/images/service/icon_Voice.svg

@ -0,0 +1,3 @@
<svg width="33" height="32" viewBox="0 0 33 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M25.8332 29.3327H7.1665C6.10564 29.3327 5.08822 28.9113 4.33808 28.1611C3.58793 27.411 3.1665 26.3935 3.1665 25.3327V3.99935C3.1665 3.64573 3.30698 3.30659 3.55703 3.05654C3.80708 2.80649 4.14622 2.66602 4.49984 2.66602H23.1665C23.5201 2.66602 23.8593 2.80649 24.1093 3.05654C24.3594 3.30659 24.4998 3.64573 24.4998 3.99935V19.9993H29.8332V25.3327C29.8332 26.3935 29.4117 27.411 28.6616 28.1611C27.9115 28.9113 26.894 29.3327 25.8332 29.3327ZM24.4998 22.666V25.3327C24.4998 25.6863 24.6403 26.0254 24.8904 26.2755C25.1404 26.5255 25.4795 26.666 25.8332 26.666C26.1868 26.666 26.5259 26.5255 26.776 26.2755C27.026 26.0254 27.1665 25.6863 27.1665 25.3327V22.666H24.4998ZM21.8332 26.666V5.33268H5.83317V25.3327C5.83317 25.6863 5.97365 26.0254 6.2237 26.2755C6.47374 26.5255 6.81288 26.666 7.1665 26.666H21.8332ZM8.49984 9.33268H19.1665V11.9993H8.49984V9.33268ZM8.49984 14.666H19.1665V17.3327H8.49984V14.666ZM8.49984 19.9993H15.1665V22.666H8.49984V19.9993Z" fill="#8E9090"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

3
src/assets/images/service/icon_VoiceSel.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M25.3332 29.3327H6.6665C5.60564 29.3327 4.58822 28.9113 3.83808 28.1611C3.08793 27.411 2.6665 26.3935 2.6665 25.3327V3.99935C2.6665 3.64573 2.80698 3.30659 3.05703 3.05654C3.30708 2.80649 3.64622 2.66602 3.99984 2.66602H22.6665C23.0201 2.66602 23.3593 2.80649 23.6093 3.05654C23.8594 3.30659 23.9998 3.64573 23.9998 3.99935V19.9993H29.3332V25.3327C29.3332 26.3935 28.9117 27.411 28.1616 28.1611C27.4115 28.9113 26.394 29.3327 25.3332 29.3327ZM23.9998 22.666V25.3327C23.9998 25.6863 24.1403 26.0254 24.3904 26.2755C24.6404 26.5255 24.9795 26.666 25.3332 26.666C25.6868 26.666 26.0259 26.5255 26.276 26.2755C26.526 26.0254 26.6665 25.6863 26.6665 25.3327V22.666H23.9998ZM21.3332 26.666V5.33268H5.33317V25.3327C5.33317 25.6863 5.47365 26.0254 5.7237 26.2755C5.97374 26.5255 6.31288 26.666 6.6665 26.666H21.3332ZM7.99984 9.33268H18.6665V11.9993H7.99984V9.33268ZM7.99984 14.666H18.6665V17.3327H7.99984V14.666ZM7.99984 19.9993H14.6665V22.666H7.99984V19.9993Z" fill="#E00068"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

3
src/assets/images/service/icon_service.svg

@ -0,0 +1,3 @@
<svg width="28" height="25" viewBox="0 0 28 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.0012 2.03864C17.1332 -0.77336 21.9732 -0.680027 24.9905 2.34264C28.0065 5.36664 28.1105 10.1826 25.3052 13.324L13.9985 24.6466L2.69451 13.324C-0.110821 10.1826 -0.00548778 5.35864 3.00918 2.34264C6.02918 -0.676027 10.8598 -0.77736 14.0012 2.03864V2.03864ZM23.1025 4.22664C21.1025 2.22397 17.8758 2.14264 15.7825 4.02264L14.0025 5.61997L12.2212 4.02397C10.1212 2.14131 6.90118 2.22397 4.89585 4.22931C2.90918 6.21597 2.80918 9.39597 4.63985 11.4973L13.9998 20.872L23.3598 11.4986C25.1918 9.39597 25.0918 6.21997 23.1025 4.22664V4.22664Z" fill="#8E9090"/>
</svg>

After

Width:  |  Height:  |  Size: 670 B

3
src/assets/images/service/icon_serviceSel.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.0012 6.03864C19.1332 3.22664 23.9732 3.31997 26.9905 6.34264C30.0065 9.36664 30.1105 14.1826 27.3052 17.324L15.9985 28.6466L4.69451 17.324C1.88918 14.1826 1.99451 9.35864 5.00918 6.34264C8.02918 3.32397 12.8598 3.22264 16.0012 6.03864V6.03864ZM25.1025 8.22664C23.1025 6.22397 19.8758 6.14264 17.7825 8.02264L16.0025 9.61997L14.2212 8.02397C12.1212 6.14131 8.90118 6.22397 6.89585 8.22931C4.90918 10.216 4.80918 13.396 6.63985 15.4973L15.9998 24.872L25.3598 15.4986C27.1918 13.396 27.0918 10.22 25.1025 8.22664V8.22664Z" fill="#E00068"/>
</svg>

After

Width:  |  Height:  |  Size: 653 B

7
src/assets/images/stay_tuned2.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

12
src/components/ActivityDetail/ActivityDetail.vue

@ -28,10 +28,11 @@
}}</MarqueesVue>
</div>
</div>
<div class="bg-left"></div>
<div class="bg-left" :class="{ 'no-date-address': !actInfo.startDate && !actInfo.activityAddress }"></div>
<scroll-view
ref="introScrollRef"
class="intro-scroll"
:class="{ 'no-date-address': !actInfo.startDate && !actInfo.activityAddress }"
:list="[switchLanguage(actInfo, 'activityName')]"
:scrollbar="true"
:observe-image="true"
@ -198,6 +199,9 @@ function handleGo() {
left: 48px;
width: 790px;
height: 112px;
&.no-date-address {
height: 200px;
}
}
.go {
display: none;
@ -207,6 +211,9 @@ function handleGo() {
bottom: 0;
width: 100%;
height: 90px;
&.no-date-address {
display: none;
}
}
.pos-container {
top: 794px;
@ -398,6 +405,9 @@ function handleGo() {
height: 80px;
margin-right: 0;
// margin: auto;
img {
width: inherit;
}
}
}
</style>

9
src/components/PublicComponent/PublicComponent.vue

@ -8,6 +8,7 @@
<!-- 菜单 -->
<Menu />
<Search v-if="showSearch"></Search>
<!-- 推荐弹窗 -->
<RecommendDialog v-if="showColumnList" />
@ -31,6 +32,7 @@ import Map from '@/components/Map/Map.vue'
import Header from '@/components/Header/Header.vue'
import Menu from '../Menu/Menu.vue'
import shopdetail from '@/components/ShopDetail/ShopDetail.vue'
import Search from '@/views/Search/Search.vue'
const AutoBackNotification = defineAsyncComponent(() => import('@/base/AutoBackNotification/AutoBackNotification.vue'))
const RecommendDialog = defineAsyncComponent(() => import('@/components/Recommend/Recommend.vue'))
const router = useRouter()
@ -55,6 +57,13 @@ function handleDetail() {
onMounted(() => {
!window.Map_QM && useInitMap()
window.addEventListener('touchend', checkHandleScreen)
window.addEventListener('resize', () => {
const retinaList = [2160 * 3840, 3840 * 2160]
const width = window.screen.width
const height = window.screen.height
store.SET_IS4K(retinaList.includes(width * height))
})
// map
store.SET_SHOP_MAP(createShopListMap(shopList.value))
})

468
src/components/SearchKeyboard/SearchKeyboard.vue

@ -0,0 +1,468 @@
<template>
<div class="keyborad-container">
<!-- <TypeBtnList class="btn-group" :list="list" @change-type="change" /> -->
<!-- <switchTab
class="btn-group"
:width="276"
:height="82"
:wrapper-width="560"
:wrapper-height="90"
:list="list"
@click="change"
></switchTab> -->
<transition
enter-active-class="animate__animated animate__zoomIn animate__faster"
leave-active-class="animate__animated animate__zoomOut animate__faster"
>
<ul v-if="mode === 'keyboard'" key="keyboard" class="keyboard">
<li v-for="(item, index) in letterNum" :key="index" class="item" :data-key="item" @click="handleKeyLetter(item)">
{{ item }}
</li>
<li class="empty item" @click="handleKeyLetter(' ')">空格</li>
<li class="keyboard-del item" @click="delLetter">
<img src="@/assets/images/search/key-del.svg" alt="" />
</li>
<li class="switch-mode item" @click="handleChangeKeyboardMode('hand')">
<img src="@/assets/images/search/icon_hand.svg" alt="" />
<p class="switchhand-txt">{{ $t('search.switchHand') }}</p>
</li>
</ul>
<div v-else class="hand">
<div class="change-keyboard" @click="handleChangeKeyboardMode('keyboard')">
<img src="@/assets/images/search/icon_keyboard.svg" alt="" />
<p class="switchhand-txt">{{ $t('search.switchKeyboard') }}</p>
</div>
<li class="keyboard-del" @click="delLetter">
<img src="@/assets/images/search/key-del.svg" alt="" />
</li>
<scroll-view
ref="wordsScrollRef"
:class="{ active: wordsList && wordsList.length }"
class="words-scroll"
:scroll-x="true"
:refresh-delay="100"
:list="wordsList"
>
<ul class="words-list" :style="{ width: getWidth }">
<li
v-for="(item, index) of wordsList"
:key="item"
class="word"
:class="{ active: isPress === index }"
@mousedown="() => (isPress = index)"
@mouseup="() => (isPress = -1)"
@touchstart="() => (isPress = index)"
@touchend="() => (isPress = -1)"
@click="handleWord(item)"
>
{{ item }}
</li>
</ul>
</scroll-view>
<div class="hand-wrapper">
<handWriting
v-if="is4K"
ref="handWritingRef"
lang="CN"
:style="styles"
fill-text="手写输入区域"
fill-font-size="48px"
background-color="rgba(0, 0, 0, 0.03)"
border-radius="48px"
stroke-style="#534F46"
fill-style="rgba(0, 0, 0, 0.03)"
:width="1088"
:height="700"
@result="result"
/>
<handWriting
v-else
ref="handWritingRef"
lang="CN"
:style="styles"
fill-text="手写输入区域"
fill-font-size="24px"
background-color="rgba(0, 0, 0, 0.03)"
border-radius="24px"
stroke-style="#534F46"
fill-style="rgba(0, 0, 0, 0.03)"
:width="544"
:height="350"
@result="result"
/>
</div>
</div>
</transition>
</div>
</template>
<script setup lang="ts">
import scrollView from '@/base/ScrollView/ScrollView.vue'
import handWriting from '@/components/Written/Written.vue'
import { ref, reactive, watch, nextTick, computed } from 'vue'
import { storeToRefs } from 'pinia'
import { useRootStore } from '@/store/root'
// import TypeBtnList from '@/components/TypeBtnList/TypeBtnList.vue'
// import switchTab from '@/components/SwitchTab/SwitchTab.vue'
const store = useRootStore()
const { is4K } = storeToRefs(store)
const emit = defineEmits(['letterKey', 'mode'])
const isPress = ref(-1)
const handWritingRef = ref()
const styles = reactive({
// background: '#fff',
borderRadius: '24px'
// marginTop: '0px'
})
const letterNum = ref('1234567890QWERTYUIOPASDFGHJKLZXCVBNM')
const letters = ref('')
const mode = ref('keyboard')
const INPUT_MAX_LEN = computed(() => (mode.value === 'hand' ? 5 : 7))
const wordsList = ref([])
const wordsScrollRef = ref()
// const list = [
// {
// title: '',
// titleEn: 'Keyboard'
// },
// {
// title: '',
// titleEn: 'Handwriting'
// }
// ]
// const list = [
// {
// name: '',
// nameEn: 'KEYBOARD INPUT',
// icon: require('../../assets/images/search/icon_normal.svg'),
// iconSel: require('../../assets/images/search/icon_sel.svg'),
// fun: () => {
// 1
// }
// },
// {
// name: '',
// nameEn: 'HANDWRITING INPUT',
// icon: require('../../assets/images/search/icon_hand.svg'),
// iconSel: require('../../assets/images/search/icon_handSel.svg')
// }
// ]
const getWidth = computed(() => wordsList.value?.length * (66 + 5) + 'px')
defineExpose({
handleChangeKeyboardMode,
clear
})
function clear() {
letters.value = ''
wordsList.value = []
}
function delLetter() {
letters.value = letters.value.substring(0, letters.value.length - 1)
if (letters.value.length === 0) {
wordsList.value = []
}
}
function result(words: []) {
console.log('words :>> ', words)
wordsList.value = words
}
function handleChangeKeyboardMode(val: 'keyboard' | 'hand') {
mode.value = val
}
function handleKeyLetter(letter: string) {
if (letters.value.length > INPUT_MAX_LEN.value) {
return
}
letters.value += letter
}
function handleWord(word: string) {
if (letters.value.length > INPUT_MAX_LEN.value) {
return
}
letters.value += word
}
// function change(params: any) {
// if (params === 0) {
// //params.order === 0
// handleChangeKeyboardMode('keyboard')
// } else {
// handleChangeKeyboardMode('hand')
// }
// }
watch(letters, newVal => {
emit('letterKey', newVal)
})
watch(mode, newVal => {
letters.value = ''
// this.$emit('letterKey', this.letters)
emit('mode', newVal)
if (newVal === 'hand') {
wordsList.value = []
setTimeout(() => {
handWritingRef.value.setCanvasSize()
handWritingRef.value.updateBound()
handWritingRef.value.reload()
}, 200)
}
})
watch(wordsList, () => {
nextTick(() => {
if (wordsScrollRef.value) {
wordsScrollRef.value?.refresh()
}
})
})
</script>
<style lang="scss" scoped>
.keyborad-container {
position: absolute;
top: 320px;
right: 56px;
z-index: 1;
display: flex;
// justify-content: center;
align-items: center;
width: 544px;
// padding: 48px 64px;
background: rgb(255 255 255 / 0%);
border-radius: 0;
.btn-group {
position: absolute;
top: 0;
right: 0;
left: 0;
width: 560px;
// margin: 0 auto;
}
.keyboard {
position: absolute;
top: 0;
left: 0;
display: flex;
width: 544px;
height: 190px;
background: rgb(255 255 255 / 0%);
border-radius: 0;
animation-duration: 50ms;
// padding: 33px;
// justify-content: center;
flex-wrap: wrap;
.item {
width: 40px;
height: 40px;
margin-right: 16px;
margin-bottom: 10px;
font-size: 16px;
font-family: 'font_bold';
text-align: center;
color: #8e9090;
background: #f5f5f5;
border-radius: 22px;
box-shadow: 0 4px 8px rgb(0 0 0 / 0%), inset 0 -1px 0 rgb(177 189 220 / 0%);
line-height: 40px;
&:active {
color: #fff;
background: #e00068;
}
&[data-key='0'] {
margin-right: 0;
}
&[data-key='P'] {
margin-right: 0;
}
&[data-key='Q'] {
margin-left: 0;
}
&[data-key='A'] {
margin-left: 25px;
}
&[data-key='L'] {
margin-right: 30px;
}
}
.keyboard-del {
// position: absolute;
// right: 16px;
// top: 33px;
display: flex;
justify-content: center;
align-items: center;
width: 40px;
margin-right: 0;
img {
width: 20px;
object-fit: scale-down;
}
}
.empty {
width: 96px;
font-size: 16px;
font-family: 'font_bold';
}
.switch-mode {
position: absolute;
top: 230px;
left: 0;
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
width: 544px;
height: 120px;
font-size: 14px;
font-family: 'font_bold';
text-align: center;
color: #8e9090;
background: #f5f5f5;
border-radius: 24px;
// .switchhand-txt {
// }
img {
width: 40px;
margin-right: 16px;
object-fit: scale-down;
}
&::before {
position: absolute;
left: -50px;
width: 0;
height: 164px;
// background: #f4f4f4;
background-repeat: 4px;
content: '';
}
}
}
.hand {
position: absolute;
top: 0;
left: 0;
width: 544px;
height: 350px;
padding-top: 0;
padding-left: 0;
background: rgb(0 0 0 / 3%);
border-radius: 24px;
opacity: 1;
animation-duration: 50ms;
.keyboard-del {
position: absolute;
right: 8px;
bottom: 8px;
z-index: 10;
display: none;
justify-content: center;
align-items: center;
width: 150px;
height: 50px;
padding: 8px;
font-size: 14px;
font-family: 'font_regular';
text-align: center;
color: #4d4846;
background: rgb(0 0 0 / 6%);
border-radius: 8px;
box-shadow: 0 -1px 0 0 rgb(177 189 220 / 10%) inset;
line-height: 48px;
&:active {
color: #fff;
background: linear-gradient(180deg, #c7a77b 0%, #d6bb97 100%);
}
img {
flex-shrink: 0;
width: 25px;
// object-fit: scale-down;
}
}
.change-keyboard {
position: absolute;
right: 8px;
bottom: 8px;
display: flex;
justify-content: center;
align-items: center;
width: 168px;
height: 72px;
padding: 16px;
background: rgb(0 0 0 / 3%);
border-radius: 24px;
img {
width: 40px;
margin-right: 16px;
object-fit: scale-down;
}
}
.words-scroll {
position: absolute;
top: 0;
right: 0;
left: 0;
overflow: hidden;
height: 40px;
padding-top: 0;
background: rgb(0 0 0 / 3%);
box-shadow: 0 8px 16px 0 rgb(0 0 0 / 0%);
border-top-left-radius: 24px;
border-top-right-radius: 24px;
&.active {
background: rgb(0 0 0 / 3%);
&::after {
position: absolute;
top: 0;
right: 0;
width: 66px;
width: 3px;
height: 40px;
border-radius: 8px;
opacity: 0.37;
// background: #eb7736;
box-shadow: 2px 4px 16px rgb(255 171 124 / 40%);
content: '';
// filter: blur(4px);
border-top-left-radius: 24px;
}
}
.words-list {
display: flex;
align-items: center;
height: 40px;
.word {
display: inline-block;
width: 66px;
height: 40px;
margin-right: 5px;
font-size: 20px;
font-family: 'font_regular';
text-align: center;
color: #8e9090;
border-radius: 8px;
opacity: 1;
// flex-shrink: 0;
line-height: 40px;
// background: #fff;
&.active {
color: #fff;
background: #e0006893;
}
}
}
}
.hand-wrapper {
width: 544px;
height: 350px;
}
}
}
</style>

371
src/components/SearchResultList/SearchResultList.vue

@ -0,0 +1,371 @@
<template>
<div class="search-list-wrapper">
<!-- 标题 -->
<div class="title-tip">
{{ $t('search.num') }}
</div>
<!-- <scroll-view :refresh-delay="200" class="result-scroll" :list="[...list, ...activities]" :scrollbar="true"> -->
<div class="result-scroll-all">
<!-- 店铺 -->
<div class="scroll-list">
<div class="title-content">
<p class="title">{{ $t('search.brand') }}</p>
<p class="title">
<i>{{ list.length }}</i>
<span>{{ language === 'en' ? $t('search.num') : '个' + $t('search.num') }}</span>
</p>
</div>
<scroll-view :refresh-delay="200" class="result-scroll" :list="[...list]" :scrollbar="true" :scroll-x="false">
<!-- 店铺 -->
<ul class="results">
<searchResultListItem v-for="item of list" :key="item.shopCode" :shop="item" @click="handleClick" />
</ul>
<!-- <img
v-show="list.length > 15"
src="../../common/images/Union.png"
class="union animate__animated animate__fadeInUp animate__infinite"
alt=""
/> -->
</scroll-view>
<img v-if="list.length === 0" src="@/assets/images/stay_tuned2.svg" class="no-data" alt="" />
</div>
<!-- 活动无 -->
<!-- <scroll-view
:refresh-delay="200"
class="resultact-scroll"
:class="{ first: !activities.length }"
:list="[...activities]"
:scrollbar="true"
> -->
<div v-if="false" class="scroll-list">
<template v-if="activities.length">
<div class="title-content">
<p class="title">{{ $t('search.act') }}</p>
<p class="title">
<span>{{ $t('search.num') }}</span>
<i>{{ activities.length }}</i>
</p>
</div>
<!-- 活动 -->
<scroll-view class="result-scroll" :scrollbar="true" :list="activities" :scroll-x="true">
<ul class="results-act">
<li v-for="item of activities" :key="item.id" class="result-item" @click="handleActivity(item)">
<img v-lazy="item.fileUrl" alt="" />
<p class="title">{{ switchLanguage(item, 'activityName') }}</p>
<div class="act-intro">{{ switchLanguage(item, 'activityContent') }}</div>
<h5>
{{ $t('shopDetail.actTip') }}
<svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M4.76978 2.28394C4.46672 2.54912 4.436 3.00978 4.70119 3.31285L8.36438 7.49936L4.70119 11.6859C4.436 11.9889 4.46672 12.4496 4.76978 12.7148C5.07285 12.98 5.53351 12.9493 5.7987 12.6462L9.71397 8.17158C10.0507 7.7867 10.0507 7.21202 9.71397 6.82714L5.7987 2.35253C5.53351 2.04946 5.07285 2.01875 4.76978 2.28394Z"
fill="#D0B186"
/>
</svg>
</h5>
</li>
</ul>
</scroll-view>
</template>
</div>
<!-- </scroll-view> -->
</div>
<!-- </scroll-view> -->
</div>
</template>
<script setup lang="ts">
import scrollView from '@/base/ScrollView/ScrollView.vue'
import { computed } from 'vue'
import searchResultListItem from '@/components/SearchResultListItem/SearchResultListItem.vue'
import { storeToRefs } from 'pinia'
import { useRootStore } from '@/store/root'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
const store = useRootStore()
const { language } = storeToRefs(store)
const { switchLanguage } = useSwitchLanguage()
type PropsType = {
list: Shop[]
}
const props = withDefaults(defineProps<PropsType>(), {
list: () => []
})
const emit = defineEmits(['handle-shop', 'handle-activity'])
const activities = computed(() => {
// return props.list.map(item => item.activityList).flat(Infinity)
let arr: Activity[] = []
props.list.forEach(item => {
arr = arr.concat(item.activityList ?? [])
})
return arr
})
// function getShop(act: Shop) {
// return shopList.value.find(item => item.shopCode === act.shopCode)
// }
function handleClick(item: Shop) {
console.log('item :>> ', item)
emit('handle-shop', item)
}
function handleActivity(item: Activity) {
emit('handle-activity', item)
}
</script>
<style lang="scss" scoped>
:deep(.bscroll-vertical-scrollbar) {
background: rgb(0 0 0 / 3%);
border-radius: 4px;
// opacity: 1 !important;
.bscroll-indicator {
background: rgb(0 0 0 / 6%) !important;
border: none !important;
border-radius: 4px !important;
}
}
:deep(.bscroll-horizontal-scrollbar) {
background: rgb(0 0 0 / 3%);
border-radius: 4px;
// opacity: 1 !important;
.bscroll-indicator {
background: rgb(0 0 0 / 6%) !important;
border: none !important;
border-radius: 4px !important;
}
}
.search-list-wrapper {
position: absolute;
top: 48px;
left: 64px;
height: 770px;
.title-tip {
margin-bottom: 40px;
font-size: 32px;
font-family: 'font_bold';
color: #615c59;
// line-height: 0px;
}
//
.result-scroll-all {
.scroll-list {
padding-right: 0;
&:nth-child(2) {
.title-content {
margin-top: 24px;
margin-bottom: 0;
}
}
.title-content {
display: flex;
justify-content: space-between;
align-items: flex-start;
width: 792px;
padding-bottom: 0;
padding-left: 0;
margin-top: 0;
margin-bottom: 24px;
border-bottom: 0 solid rgb(0 0 0 / 5%);
.title {
font-size: 20px;
font-family: 'font_bold';
color: #615c59;
&:last-child {
width: 110px;
height: 30px;
padding: 0;
margin-left: 0;
text-align: right;
background: rgb(0 0 0 / 0%);
border-radius: 0;
}
i {
font-size: 36px;
color: #8e9090;
}
span {
margin-left: 8px;
font-size: 14px;
font-family: 'font_bold';
color: #8e9090;
}
}
}
.result-scroll {
position: relative;
overflow: hidden;
width: 822px;
height: 683px;
padding-right: 24px;
}
.results {
display: grid;
width: fit-content;
width: 792px;
padding-bottom: 0;
margin-bottom: 0;
grid-template-columns: repeat(1, 792px);
// grid-auto-flow: column;
gap: 8px 0;
}
.no-data {
position: absolute;
top: 50%;
left: 50%;
z-index: 2;
height: 200px;
// filter: grayscale(1) brightness(200%);
transform: translate(-50%, -50%);
opacity: 0.5;
}
}
.results-act {
position: relative;
display: grid;
width: fit-content;
grid-template-columns: repeat(auto-fill, 592px);
grid-auto-flow: column;
gap: 0 16px;
height: 110px;
.result-item {
position: relative;
display: inline-block;
width: 592px;
height: 98px;
padding: 15px 42px 15px 188px;
margin-right: 0;
background: #fff;
border-radius: 4px;
img {
position: absolute;
top: 4px;
left: 4px;
width: 161px;
height: 90px;
object-fit: scale-down;
}
.title {
width: 80%;
height: 24px;
margin-bottom: 8px;
font-size: 20px;
font-family: 'font_bold';
color: rgb(0 0 0 / 90%);
font-style: normal;
font-weight: 700;
line-height: inherit;
@include no-wrap();
}
.act-intro {
font-size: 12px;
font-family: 'font_medium';
color: rgb(0 0 0 / 60%);
font-style: normal;
font-weight: 400;
line-height: 150%;
@include more-wrap(2);
}
h5 {
position: absolute;
top: 15px;
right: 33px;
display: flex;
align-items: center;
font-size: 12px;
font-family: 'font_medium';
color: #d0b186;
font-style: normal;
font-weight: 400;
svg {
margin-left: 4px;
}
}
}
}
//
// .result-scroll {
// position: relative;
// overflow: hidden;
// width: 972px;
// height: 780px;
// padding-right: 20px;
// margin-bottom: 0;
// &.first {
// // height: 793px;
// }
// .scroll-list {
// padding-right: 14px;
// .title-content {
// display: flex;
// justify-content: flex-start;
// align-items: flex-start;
// padding-bottom: 0;
// padding-left: 5px;
// margin-top: 40px;
// margin-bottom: 24px;
// border-bottom: 0 solid rgb(0 0 0 / 5%);
// // &:nth-child(2) {
// // margin-top: 48px;
// // }
// .title {
// font-size: 24px;
// font-family: 'font_bold';
// color: rgb(0 0 0 / 90%);
// &:last-child {
// width: 132px;
// height: 30px;
// padding: 0;
// margin-left: 20px;
// text-align: left;
// background: rgb(255 255 255 / 0%);
// border-radius: 0;
// }
// i {
// font-size: 16px;
// color: #d7ba92;
// }
// span {
// margin-right: 8px;
// font-size: 14px;
// font-family: 'font_bold';
// color: rgb(0 0 0 / 60%);
// }
// }
// }
// .results {
// display: grid;
// padding-bottom: 100px;
// margin-bottom: 16px;
// grid-template-columns: repeat(4, 220px);
// gap: 24px 24px;
// }
// }
// .no-data {
// position: absolute;
// top: 200px;
// left: 50%;
// height: 160px;
// transform: translateX(-50%);
// }
// }
}
}
</style>

97
src/components/SearchResultListItem/SearchResultListItem.vue

@ -0,0 +1,97 @@
<template>
<li class="result-item" @click="emits('click', shop)">
<div class="banner-wrapper">
<img :src="shop.logoUrl ? shop.logoUrl : require('@/assets/images/empty_small.svg')" class="logo" alt="" />
</div>
<div class="bottom">
<span class="name">{{ switchLanguage(shop, 'shopName') }}</span>
<span class="floor-name">
<img v-if="shop.industryUrl" :src="shop.industryUrl" alt="" />
<span class="format-name">{{ switchLanguage(shop, 'industryFatherName') }}</span>
<img src="@/assets/images/search/pos.svg" alt="" />
{{ shop.floor }}
</span>
</div>
</li>
</template>
<script setup lang="ts">
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
const { switchLanguage } = useSwitchLanguage()
type PropsType = {
shop: Shop
}
defineProps<PropsType>()
const emits = defineEmits(['click'])
</script>
<style lang="scss" scoped>
.result-item {
position: relative;
display: flex;
align-items: center;
width: 792px;
height: 92px;
padding: 6px;
background: rgb(255 255 255 / 100%);
border-radius: 12px;
.banner-wrapper {
position: relative;
overflow: hidden;
width: 80px;
height: 80px;
background-color: #fff;
border-radius: 6px;
img {
position: absolute;
top: 50%;
left: 50%;
width: 64px;
height: 64px;
object-fit: scale-down;
transform: translate(-50%, -50%);
}
}
.bottom {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 28px;
padding-right: 40px;
padding-left: 32px;
font-family: 'font_bold';
line-height: 28px;
.name {
max-width: 460px;
font-size: 24px;
color: #8e9090;
@include no-wrap();
}
.floor-name {
display: flex;
align-items: center;
height: 20px;
font-size: 14px;
color: #8e9090;
img {
display: inline-block;
width: 20px;
height: 20px;
margin-right: 8px;
}
.format-name {
width: 96px;
@include no-wrap();
}
.floor-txt {
display: inline-block;
vertical-align: middle;
}
}
}
}
</style>

4
src/components/ShopDetail/ShopDetail.vue

@ -388,8 +388,8 @@ useStatistics({ tag: 'shop', shopCode: shop.value.shopCode })
width: 100px;
height: 100px;
padding: 26px;
background: var(--w-60, rgb(255 255 255 / 60%));
border: 2px solid var(--w-100, #fff);
background: rgb(255 255 255 / 60%);
border: 2px solid #fff;
border-radius: 50px;
backdrop-filter: blur(20px);
// margin: auto;

15
src/components/ShopItem/ShopItem.vue

@ -10,12 +10,17 @@
<div class="ins">{{ shop.floor }}</div>
</div>
</div>
<div class="label-container">
<img v-if="shop.isNewShop && language === 'en'" src="@/assets/images/brand/label_newEn.svg" alt="" />
<img v-else-if="shop.isNewShop" src="@/assets/images/brand/label_newZh.svg" alt="" />
</div>
</div>
</template>
<script setup lang="ts">
import { useRootStore } from '@/store/root'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
import { storeToRefs } from 'pinia'
interface Prop {
shop: Shop
}
@ -23,6 +28,7 @@ interface Prop {
defineProps<Prop>()
const { switchLanguage } = useSwitchLanguage()
const store = useRootStore()
const { language } = storeToRefs(store)
function showDetail(shop: Shop) {
store.SET_SHOP(shop)
store.SET_SHOW_DETAIL(true)
@ -31,6 +37,7 @@ function showDetail(shop: Shop) {
<style lang="scss" scoped>
.shop-container {
position: relative;
width: 212px;
height: 176px;
background: #fff;
@ -86,5 +93,13 @@ function showDetail(shop: Shop) {
}
}
}
.label-container {
position: absolute;
top: 2px;
left: 2px;
img {
width: 60px;
}
}
}
</style>

11
src/components/SwitchTab/SwitchTab.vue

@ -64,7 +64,10 @@ import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
import { computed, ref, onMounted, watch, nextTick } from 'vue'
const { switchLanguage } = useSwitchLanguage()
const is4K = computed(() => window.screen.width === 3840 && window.screen.height === 2160)
import { storeToRefs } from 'pinia'
import { useRootStore } from '@/store/root'
const store = useRootStore()
const { is4K } = storeToRefs(store)
type ListItem = {
name: string
en: string
@ -125,8 +128,10 @@ const ulRef = ref()
const scrollBoxRef = ref()
function switchTab(index: number) {
copyTabIdx.value = index
emit('click', index)
if (index !== copyTabIdx.value) {
copyTabIdx.value = index
emit('click', index)
}
}
watch(

7
src/components/Written/Written.vue

@ -139,8 +139,8 @@ function _getHandWriting() {
lpCis: state.clickC
}
getHandWriting(params)
.then(({ data }) => {
state.list = data
.then(res => {
state.list = res
})
.catch(err => {
console.log(err)
@ -165,7 +165,8 @@ function setCanvasSize() {
defineExpose({
reload,
updateBound
updateBound,
setCanvasSize
})
watch(

9
src/composables/useActivityNav.ts

@ -14,13 +14,16 @@ export const useActivityNav = () => {
let shop
if (activity.shopCode.length) {
shop = shopList.value.find(item => item.shopCode === activity?.shopCode)
} else if (activity.point > NO_POINT_TYPE) {
const { activityName, floorOrder, floor, point, fileUrl, id } = activity
} else if (activity.point.length) {
const { activityName, point, fileUrl, id } = activity
const logoUrl = fileUrl.at(0) ?? ''
const floorOrder = +activity.point.split('_')[1]
const floor = store.currentBuildingFloorsList.find(item => item.floorOrder === floorOrder)?.floor ?? ''
shop = new Brand({
shopName: activityName,
floorOrder,
floor,
logoUrl: fileUrl.length > 0 ? fileUrl.at(0)! : '',
logoUrl: logoUrl,
yaxis: point,
shopCode: id
})

7
src/composables/useServeNav.ts

@ -6,7 +6,12 @@ export const useServeNav = () => {
const router = useRouter()
const store = useRootStore()
function nav({ floor, floorOrder, name, nameEn, point, logoUrl }: ServeItem) {
function nav({ name, nameEn, point, logo_code }: ServeItem) {
const logoUrl = logo_code.at(0) ?? ''
const floorOrder = +point.split('_')[1]
const floor = store.currentBuildingFloorsList.find(item => item.floorOrder === floorOrder)?.floor ?? ''
const shop = new Brand({ shopName: name, shopNameEn: nameEn, floor, floorOrder, logoUrl, yaxis: point, shopCode: logoUrl })
store.SET_SHOP(shop)
router.push('/nav')

9
src/http/api/member/index.ts

@ -0,0 +1,9 @@
import { request } from '@/http/http'
import { PREFIX } from '@/enums'
//获取商场活动
export const getMemberBenefits = () => request({ url: `${PREFIX.STATIC_URL}/JSON/getMemberBenefits.json` })
//获取店铺活动
export const getMemberQRCodes = () => request({ url: `${PREFIX.STATIC_URL}/JSON/getMemberQRCodes.json` })
//获取会员活动
export const getMemberServices = () => request({ url: `${PREFIX.STATIC_URL}/JSON/getMemberServices.json` })

9
src/http/api/service/index.ts

@ -0,0 +1,9 @@
import { request } from '@/http/http'
import { PREFIX } from '@/enums'
//获取商场活动
export const getServeList = () => request({ url: `${PREFIX.STATIC_URL}/JSON/getServeList.json` })
//获取店铺活动
export const getCustomerQRCodeList = () => request({ url: `${PREFIX.STATIC_URL}/JSON/getCustomerQRCodeList.json` })
//获取会员活动
export const getCustomerVoiceList = () => request({ url: `${PREFIX.STATIC_URL}/JSON/getCustomerVoiceList.json` })

10
src/i18n/lang/en.json

@ -30,5 +30,15 @@
"qrTip": "Scan the code",
"btn": "View",
"actGo": "GO"
},
"search": {
"brand": "Brand",
"act": "Activity",
"num": "Result",
"valueTipHand": "Please enter your Chinese name by hand",
"valueTip": "Please enter initial letters in English and Chinese",
"btnName": "Search",
"switchKeyboard": "Alphabetic search",
"switchHand": "Handwriting search"
}
}

10
src/i18n/lang/tw.json

@ -17,5 +17,15 @@
"qrTip": "掃碼了解更多",
"btn": "查看大圖",
"actGo": "GO"
},
"search": {
"brand": "品牌",
"act": "活動",
"num": "搜索結果",
"valueTipHand": "請手寫輸入中文名查詢",
"valueTip": "請輸入中英文首字母",
"btnName": "搜索",
"switchKeyboard": "字母搜索",
"switchHand": "手寫搜索"
}
}

10
src/i18n/lang/zh.json

@ -29,5 +29,15 @@
"address": "活动地点:",
"qrTip": "扫码了解更多",
"actGo": "GO"
},
"search": {
"brand": "品牌",
"act": "活动",
"num": "搜索結果",
"valueTipHand": "请手写输入中文名查询",
"valueTip": "请输入中英文首字母",
"btnName": "搜索",
"switchKeyboard": "字母搜索",
"switchHand": "手写搜索"
}
}

18
src/router/routes.ts

@ -63,6 +63,24 @@ export const routes: RouteRecordRaw[] = [
},
component: () => import(/* webpackChunkName: "art" */ '@/views/Art/Art.vue')
},
{
path: '/member',
name: 'Member',
meta: {
showMap: false,
showMenu: true
},
component: () => import(/* webpackChunkName: "member" */ '@/views/Member/Member.vue')
},
{
path: '/service',
name: 'Service',
meta: {
showMap: false,
showMenu: true
},
component: () => import(/* webpackChunkName: "service" */ '@/views/Service/Service.vue')
},
{
path: '/transfer',
name: 'Transfer',

4
src/store/root/actions.ts

@ -21,6 +21,7 @@ export interface Actions {
SET_SHOW_SEARCH(flag: boolean): void
SET_COLUMN_LIST(list: Featured[]): void
SET_SHOW_COLUMNLIST(flag: boolean): void
SET_IS4K(flag: boolean): void
SET_SHOP_MAP(shopMap: ShopMap): void
SET_ART_PLACE_LIST(list: ArtPlace[]): void
}
@ -79,6 +80,9 @@ export const actions: GenActions = {
SET_SHOW_COLUMNLIST(flag) {
this.showColumnList = flag
},
SET_IS4K(flag: boolean) {
this.is4K = flag
},
SET_SHOP_MAP(shopMap) {
this.shopMap = shopMap
},

2
src/store/root/state.ts

@ -17,6 +17,7 @@ export interface State {
shop: Shop //店铺信息
columnList: Featured[] //推荐页的卡片
showColumnList: boolean //是否显示专栏
is4K: boolean //是否4K
shopMap: ShopMap // 店铺code与店铺信息集合
artPlaceList: ArtPlace[] // 艺术装置集合
}
@ -38,6 +39,7 @@ export const state = (): State => ({
shop: {} as Shop,
columnList: [],
showColumnList: false,
is4K: true,
shopMap: {} as ShopMap,
artPlaceList: []
})

32
src/types/activity.d.ts

@ -1,22 +1,22 @@
declare interface Activity {
activityAddress: string //活动地址
activityAddressEn: string //活动地址英文
activityContent: string //活动内容
activityContentEn: string //活动内容英文
activityAddress?: string //活动地址
activityAddressEn?: string //活动地址英文
activityContent?: string //活动内容
activityContentEn?: string //活动内容英文
id: number | string //活动ID
activityName: string
activityNameEn: string //活动名称英文
activityType: 1 | 2 | 3 //活动类型,1商场活动;2品牌活动;3会员活动
building: string //楼栋
buildingCode: string
startDate: string //开始日期
endDate: string //结束日期
limitStartDate: string //上线开始日期
limitEndDate: string //下线结束日期
activityNameEn?: string //活动名称英文
activityType?: 1 | 2 | 3 //活动类型,1商场活动;2品牌活动;3会员活动
building?: string //楼栋
buildingCode?: string
startDate?: string //开始日期
endDate?: string //结束日期
limitStartDate?: string //上线开始日期
limitEndDate?: string //下线结束日期
fileUrl: string[] //封面
fileUrls: string[] //活动详情图片列表
floor: string //楼层
floorOrder: number
point: number // 导航点
fileUrls?: string[] //活动详情图片列表
floor?: string //楼层
floorOrder?: number
point: string // 导航点
shopCode: string //关联店铺code
}

31
src/types/member.d.ts

@ -0,0 +1,31 @@
//会员权益
declare interface MmeberBenefit {
id: number
title: string //额外标题无实际作用
name: string //标题
nameEn: string //标题英文
content: string //介绍
contentEn: string //介绍英文
file_code: string[] //图片列表
}
//会员二维码
declare interface MmeberQRCode {
id: number
title: string //额外标题无实际作用
name: string //标题
nameEn: string //标题英文
file_code: string[] //图片列表
}
//会员服务
declare interface MmeberService {
id: number
title: string //额外标题无实际作用
name: string //标题
nameEn: string //标题英文
content: string //介绍
contentEn: string //介绍英文
point: string //'0_0_15'//导航点
file_code: string[] //图片列表
}

26
src/types/serve.d.ts

@ -1,18 +1,20 @@
declare interface ServeItem {
name: string
nameEn: string
logoUrl: string
fileUrl: string
fileUrls: string[]
qrUrl: string
logo_code: string[]
file_code: string[]
qrUrl?: string
content: string
contentEn: string
isPoint: 0 | 1 | 2 //是否关联点位 0无关联点位,1服务台设施,2地图选点
building: string
buildingCode: string
buildingOrder: number
floor: string
floorCode: string
floorOrder: number
point: number | string
point: string
}
//会员权益
declare interface CustomerVoice {
id: number
title: string //额外标题无实际作用
name: string //标题
nameEn: string //标题英文
content: string //介绍
contentEn: string //介绍英文
file_code: string[] //图片列表
}

1
src/views/Activity/Activity.vue

@ -74,7 +74,6 @@ import { getMallActivity, getShopActivity } from '@/http/api/activity'
import { ref } from 'vue'
// import switchTab from '@/components/SwitchTab/SwitchTab.vue'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
import { identity } from '@vueuse/core'
const { switchLanguage } = useSwitchLanguage()
const modules = [Autoplay, FreeMode, Pagination]

170
src/views/Member/Member.vue

@ -0,0 +1,170 @@
<template>
<div class="member-container">
<!-- 切换按钮 -->
<switchTab
class="btn-group"
:width="364"
:height="68"
:wrapper-width="728"
:wrapper-height="68"
:list="list"
@click="handleSwitch"
></switchTab>
<transition
enter-active-class="animate__faster animate__animated animate__fadeInUp"
leave-active-class="animate__animated animate__fadeOutDown"
>
<!-- 会员权益 -->
<PictureText v-if="switchIdx === 0" :ac-list="memberBenefitList" :qr-list="memberQRCodeList" />
<!-- 会员服务 -->
<ScrollView
v-else
ref="actScroll"
:list="memberServiceList"
:refresh-delay="200"
:scroll-x="true"
:scrollbar="true"
class="member-scroll"
>
<ul class="act-list">
<memberItem v-for="(item, index) in memberServiceList" :key="index" :act-info="item" @click="clickItem"></memberItem>
</ul>
</ScrollView>
</transition>
<activityDetail v-if="showDetail" :act-info="currentItem" @close="showDetail = false"></activityDetail>
</div>
</template>
<script setup lang="ts">
import { Autoplay, FreeMode, Pagination } from 'swiper'
import { Swiper, SwiperSlide } from 'swiper/vue'
import 'swiper/css'
import 'swiper/css/free-mode'
import { useStatisticsModel } from '@/composables/useStatistics'
import activityDetail from '@/components/ActivityDetail/ActivityDetail.vue'
import ScrollView from '@/base/ScrollView/ScrollView.vue'
import memberItem from './MemberItem.vue'
import { getMemberBenefits, getMemberQRCodes, getMemberServices } from '@/http/api/member'
import { nextTick, ref } from 'vue'
import switchTab from '@/components/SwitchTab/SwitchTab.vue'
import PictureText from '@/components/PictureText/PictureText.vue'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
const { switchLanguage } = useSwitchLanguage()
const modules = [Autoplay, FreeMode, Pagination]
const list = [
{
name: '会员权益',
en: 'MEMBER BENEFITS',
icon: require('@/assets/images/member/icon_benefit.svg'),
iconSel: require('@/assets/images/member/icon_benefitSel.svg')
},
{
name: '会员服务',
en: 'MEMBERSHIP SERVICE',
icon: require('../../assets/images/member/icon_service.svg'),
iconSel: require('../../assets/images/member/icon_serviceSel.svg')
}
]
const memberServiceList = ref<Activity[]>([]) //
const memberQRCodeList = ref<MmeberQRCode[]>([]) //
const memberBenefitList = ref<MmeberBenefit[]>([]) //
const switchIdx = ref(0)
const currentItem = ref<Activity>()
const showDetail = ref(false)
const actScroll = ref()
function clickItem(item: Activity) {
// useStatisticsModel({ recordType: 2, moduleName: item.activityName, activityCode: item.id })
currentItem.value = item
showDetail.value = true
}
/**
*
* @param index 点击分类
*/
function handleSwitch(index: number) {
if (switchIdx.value === index) {
return
}
switchIdx.value = index
if (switchIdx.value === 1) {
nextTick(() => {
actScroll.value.refresh()
})
}
}
function getData() {
getMemberServices().then(res => {
for (let t = 0; t < res.data.length; t++) {
const { name, nameEn, content, contentEn, file_code, point } = res.data[t].content
memberServiceList.value.push({
id: res.data[t].id,
activityContent: content,
activityContentEn: contentEn,
activityName: name,
activityNameEn: nameEn,
point,
fileUrl: file_code ?? [],
shopCode: ''
})
}
})
getMemberQRCodes().then(res => {
for (let t = 0; t < res.data.length; t++) {
const ele = res.data[t]
memberQRCodeList.value.push({ id: ele.id, ...ele.content })
}
})
getMemberBenefits().then(res => {
for (let t = 0; t < res.data.length; t++) {
const ele = res.data[t]
memberBenefitList.value.push({ id: ele.id, ...ele.content })
}
})
}
getData()
</script>
<style lang="scss" scoped>
:deep(.bscroll-horizontal-scrollbar) {
z-index: 3 !important;
width: 500px !important;
background: rgb(0 0 0 / 10%);
border-radius: 6px;
opacity: 1 !important;
.bscroll-indicator {
background: #e00068 !important;
border: none !important;
border-radius: 6px !important;
}
}
.member-container {
overflow: hidden;
padding-top: 152px;
padding-left: 56px;
--animate-duration: 0.5s;
.member-scroll {
position: relative;
width: 1864px;
height: 610px;
margin-top: 40px;
margin-left: 0;
:deep(.swiper-slide) {
width: 880px !important;
height: 575px;
}
.act-list {
// display: flex;
width: fit-content;
white-space: nowrap;
}
}
}
</style>

199
src/views/Member/MemberItem.vue

@ -0,0 +1,199 @@
<template>
<div v-if="showThis" :key="actInfo.id" class="act-item animate__faster animate__animated animate__fadeInUp">
<!-- 图片 -->
<div class="img-container" @click="clickActItem">
<img :style="{ backgroundImage: `url(${getBackGround()})` }" alt="" />
</div>
<!-- 标题 -->
<div class="marquee-wrapper">
<Marquees class="name" :speed="40" :delay="0.8" :content="switchLanguage(actInfo, 'activityName')">{{
switchLanguage(actInfo, 'activityName')
}}</Marquees>
</div>
<!-- 介紹无 -->
<scroll-view
v-if="false"
ref="introScrollRef"
class="intro-scroll"
:style="{ height: actInfo.point !== -1 || actInfo.shopCode ? '499px' : null }"
:list="[switchLanguage(actInfo, 'activityContent')]"
:scrollbar="true"
:observe-image="true"
:refresh-delay="500"
>
<p class="intro" v-text="switchLanguage(actInfo, 'activityContent')"></p>
</scroll-view>
<!-- 导航无 -->
<div
v-if="false"
class="attr-container"
:style="{
justifyContent: actInfo.startDate === '' && actInfo.activityAddress === '' ? 'flex-end' : ''
}"
>
<p class="time-tip">
<span v-if="actInfo.startDate" class="act-time">{{ $t('activity.time') + actInfo.startDate + '' + actInfo.endDate }}</span>
<span v-if="actInfo.activityAddress" class="act-time">{{
$t('activity.address') + switchLanguage(actInfo, 'activityAddress')
}}</span>
</p>
<!-- go -->
<div v-if="actInfo.point !== -1 || actInfo.shopCode" class="go" @click="handleGo">
<span>{{ $t('activity.actGo') }}</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useStatisticsModel } from '@/composables/useStatistics'
import Marquees from '@/base/Marquees/Marquees.vue'
import scrollView from '@/base/ScrollView/ScrollView.vue'
import { useActivityNav } from '@/composables/useActivityNav'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
interface AItem {
actInfo: Activity
}
const props = defineProps<AItem>()
const emits = defineEmits(['click', 'clickImg'])
const { nav } = useActivityNav()
const { switchLanguage } = useSwitchLanguage()
const showThis = ref(false)
function clickActItem() {
useStatisticsModel({ recordType: 2, moduleName: props.actInfo.activityName, activityCode: props.actInfo.activityId })
emits('click', props.actInfo)
}
function handleGo() {
nav(props.actInfo)
useStatisticsModel({ recordType: 2, moduleName: props.actInfo.activityName, activityCode: props.actInfo.activityId })
// emits('clickGo', props.actInfo)
}
function getBackGround() {
if (props.actInfo.fileUrl && props.actInfo.fileUrl.length) {
return props.actInfo.fileUrl[0]
}
return require('@/assets/images/empty_big.svg')
}
onMounted(() => {
showThis.value = true
})
</script>
<style lang="scss" scoped>
:deep(.bscroll-vertical-scrollbar) {
z-index: 3 !important;
background: rgb(0 0 0 / 3%);
border-radius: 6px;
opacity: 1 !important;
.bscroll-indicator {
background: rgb(0 0 0 / 6%) !important;
border: none !important;
border-radius: 6px !important;
}
}
.act-item {
position: relative;
display: inline-flex;
overflow: hidden;
width: 880px;
height: 575px;
padding-bottom: 0;
margin-right: 32px;
background-color: #fff;
border-radius: 16px;
flex-direction: column;
--animate-duration: 0.5s;
.img-container {
position: relative;
width: inherit;
height: 495px;
background: #ebebeb;
img {
width: inherit;
height: inherit;
background-size: cover;
border-radius: 16px;
}
}
.marquee-wrapper {
flex-shrink: 0;
overflow: hidden;
width: 800px;
height: 32px;
margin-top: 24px;
margin-left: 40px;
white-space: nowrap;
.name {
display: inline-block;
font-weight: 700;
font-size: 24px;
line-height: inherit;
font-family: 'font_bold';
color: rgb(0 0 0 / 70%);
}
}
.intro-scroll {
position: relative;
overflow: hidden;
width: 544px;
height: 100%;
padding: 0;
padding-right: 20px;
margin-top: 5px;
margin-left: 48px;
border-radius: 0;
.intro {
font-size: 14px;
font-family: 'font_medium';
text-align: justify;
white-space: pre-wrap;
color: rgb(0 0 0 / 60%);
line-height: 200%;
:deep(img) {
width: 100%;
}
}
}
.attr-container {
display: flex;
justify-content: space-between;
align-items: flex-end;
height: 44px;
padding: 0 48px;
margin-top: 16px;
.time-tip {
display: flex;
flex-direction: column;
justify-content: flex-end;
width: 415px;
height: 48px;
margin-bottom: 0;
font-size: 14px;
font-family: 'font_regular';
color: #d0b186;
.act-time {
&:nth-child(2) {
@include no-wrap();
margin-top: 5px;
}
}
}
.go {
width: 115px;
height: 38px;
font-size: 20px;
font-family: 'font_bold';
text-align: center;
color: #fff;
background: linear-gradient(180deg, #c7a77b 0%, #d6bb97 100%);
border-radius: 90px;
line-height: 38px;
}
}
}
</style>

652
src/views/Search/Search.vue

@ -0,0 +1,652 @@
<template>
<transition appear enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__zoomOut">
<masker @click="close">
<div class="search-container animate__animated animate__fadeInUp">
<!-- 背景区域 -->
<div class="bg"></div>
<!-- <div class="line"></div> -->
<!-- bigtitle -->
<div class="title">
<span>{{ switchLanguage({ name: '快捷搜索' }, 'name') }}</span>
<span>/</span>
<span class="title-en">{{ 'GLOBAL\nSEARCH' }}</span>
</div>
<!-- 关闭 -->
<div class="close-btn animate__animated animate__fadeInLeft" @click="close">
<img :src="require('@/assets/images/shopDetail/close.svg')" alt="" />
</div>
<div class="search-btn">
{{ $t('search.btnName') }}
</div>
<!-- 公共设施 -->
<div v-if="input.length === 0" class="fac-container animate__animated animate__fadeInUp">
<div class="fac-title">
<p v-if="language === 'zh' || language === 'tw'" class="fac-zh">{{ switchLanguage({ name: '快捷入口' }, 'name') }}</p>
<p v-else class="fac-en">QUICK ENTERANCE</p>
<!-- {{ $t('search.fac') }} -->
</div>
<scroll-view
ref="facScroll"
:scroll-x="true"
:list="facilityList"
class="fac-scroll"
:class="{ center: facilityList.length < 14 }"
>
<ul class="facilities">
<li v-for="(item, index) of facilityList" :key="index" class="facility" @click="clickFacility(item)">
<img :src="item.filePath" class="facility-icon" alt="" />
<span class="facility-name">{{ getFacName(item) }}</span>
</li>
</ul>
</scroll-view>
</div>
<!-- 搜索框 -->
<div class="search-wrapper animate__animated animate__fadeInRight">
<div class="search-bg">
<img class="bg-search" src="@/assets/images/search/bg_search.svg" alt="" />
<img src="@/assets/images/search/searchFirstIcon.svg" class="first-icon" />
</div>
<div v-if="input?.length" class="saw" v-text="input"></div>
<!-- :placeholder="" -->
<input v-model="input" readonly type="text" :class="{ istip: input?.length === 0 }" />
<h4 v-if="input?.length === 0" class="search-tip">{{ mode === 'hand' ? $t('search.valueTipHand') : $t('search.valueTip') }}</h4>
<div v-if="input?.length" class="close" @click="del">
<svg width="40" height="40" class="icon" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="40" height="40" rx="20" fill="white" />
<path
d="M20 18.1146L26.6 11.5146L28.4853 13.4L21.8853 20L28.4853 26.6L26.6 28.4853L20 21.8853L13.4 28.4853L11.5146 26.6L18.1146 20L11.5146 13.4L13.4 11.5146L20 18.1146Z"
fill="#E00068"
/>
</svg>
</div>
</div>
<!-- 热搜无 -->
<div v-if="hotSearchList?.length" class="hot-container animate__animated animate__fadeInUp">
<ul class="hot">
<p v-if="language === 'zh'" class="hot-name">热门搜索</p>
<p v-else-if="language === 'tw'" class="hot-name">熱門搜索</p>
<p v-else class="hot-nameEn">TOP SEARCHES</p>
<!-- <img width="42px" height="23px" src="~common/images/search/hot.png" alt="" /> -->
</ul>
<scroll-view ref="hotScroll" :scroll-x="true" :list="hotSearchList" :refresh-delay="600" class="hot-scroll">
<ul class="hot-brands">
<li v-for="item of hotSearchList" :key="item.shopCode" class="brand" @click="handleHotSearch(item)">
{{ switchLanguage(item, 'shopName') }}
</li>
</ul>
</scroll-view>
</div>
<!-- 结果 这个只有品牌没有活动-->
<!-- <scroll-view class="search-brand-scroll" v-if="searchShopList.length" :list="searchShopList">
<ul class="brands-list" >
<li
@click="handleSearchShop(item)"
:key="item.code"
v-for="item of searchShopList"
class="brand"
>
<div class="logo-wrapper">
<img :src="config.baseUrl + item.logoPath" class="logo" alt="" />
</div>
<p class="right">
<span class="name">{{ item | switchLanguage("name") }}</span>
<span class="floor-house">{{ item.floorName }}</span>
</p>
</li>
</ul>
</scroll-view> -->
<!-- <switchTab
class="btn-group"
:width="276"
:height="82"
:wrapper-width="560"
:wrapper-height="90"
:list="list"
@click="handleSwitch"
></switchTab> -->
<searchResultList
v-if="input.length !== 0"
class="animate__animated animate__fadeInUp"
:list="searchShopList"
@handle-activity="handleActivity"
@handle-shop="handleSearchShop"
/>
<!-- 键盘 -->
<search-keyboard ref="keyboardRef" class="keyboard" @letter-key="getLetterKey" @mode="handleMode" />
</div>
</masker>
</transition>
</template>
<script setup lang="ts">
import masker from '@/base/Masker/Masker.vue'
// import switchTab from '@/components/SwitchTab/SwitchTab.vue'
import scrollView from '@/base/ScrollView/ScrollView.vue'
import searchKeyboard from '@/components/SearchKeyboard/SearchKeyboard.vue'
import { useStatistics } from '@/composables/useStatistics'
import searchResultList from '@/components/SearchResultList/SearchResultList.vue'
import { useSearchShop } from '@/composables/useSearchShop'
import { ref, computed } from 'vue'
// import { useRoute } from 'vue-router'
import { useFacilityNav } from '@/composables/useFacilityNav'
import { storeToRefs } from 'pinia'
import { useRootStore } from '@/store/root'
import { useSwitchLanguage } from '@/composables/useSwitchLanguage'
const { switchLanguage } = useSwitchLanguage()
const { handleFacility } = useFacilityNav()
const store = useRootStore()
const hotSearchList = ref([])
const { shopList, facilityList, language } = storeToRefs(store)
// const route = useRoute()
const INPUT_MAX_LEN = computed(() => (mode.value === 'hand' ? 5 : 7))
const input = ref('')
const mode = ref('keyboard')
const keyboardRef = ref()
const actDetailItem = ref<Activity>() //
const switchIdx = ref<0 | 1>(0)
const info = ref({}) //
const showInfo = ref(false) //
const { searchShopList } = useSearchShop(input, switchIdx)
// searchShopList() {
// if (this.mode === 'keyboard') {
// if (this.input.length === 0) {
// return []
// } else if (this.input.length === 1) {
// return this.shopList.filter(shop => shop.initials.startsWith(this.input) || shop.name.startsWith(this.input) || shop.nameEn.startsWith(this.input))
// } else if (this.input.length > 1) {
// const value = this.input.substr(1)
// return this.shopList.filter(shop => shop.initials.includes(value) || shop.name.includes(this.input) || shop.nameEn.includes(this.input))
// } else {
// return []
// }
// } else {
// if (this.input.length === 0) {
// return []
// } else {
// return this.shopList.filter(shop => shop.name.includes(this.input))
// }
// }
// }
//
function getFacName(item: Facility) {
if (language.value === 'zh') {
return item.customFacilityName ? item.customFacilityName : item.name
} else if (language.value === 'tw') {
return switchLanguage(item, 'customFacilityName') ? switchLanguage(item, 'customFacilityName') : switchLanguage(item, 'name')
} else if (language.value === 'en') {
if (item.customFacilityNameEn) {
return item.customFacilityNameEn
} else if (item.nameEn) {
return item.nameEn
}
return item.name
}
}
function clickFacility(item: Facility) {
handleFacility(item)
close()
}
//
function close() {
store.SET_SHOW_SEARCH(false)
}
//
function handleActivity(item: Activity) {
info.value = item
actDetailItem.value = item
showInfo.value = true
// const timeId = setTimeout(() => {
// clearTimeout(timeId)
// showDetail.value = true
// }, 10)
// store.SET_SELECTED_MODULE({
// iconName: 'icon-act',
// img: require('@/assets/images/home/icon-act-sel.svg'),
// name: '',
// nameEn: 'SELECTION',
// url: '/activity'
// })
// router.push('/activity')
}
//
/* function handleFacilities(item) {
const nearestPoint = window.Map_QM.pathIcon({ type: item.type })
// this.name = item.name
// this.logoPath = item.imgUrl
// console.log('nearestPoint :>> ', item)
store.SET_SHOP({
yaxis: nearestPoint.node,
floorOrder: nearestPoint.floor,
name: item.title,
nameEn: item.titleEn,
logoPath: item.imgUrl,
isFacility: true,
facType: item.type,
floorName: currentBuildingFloorsList.value.filter(itd => itd.order === nearestPoint.floor)[0].name
})
useSearchStatistics(item.title, 0)
router.push('/nav')
} */
//
function handleSearchShop(val: Shop) {
store.SET_SHOP(val)
store.SET_SHOW_DETAIL(true)
useStatistics({ tag: 'brandSearch', shopCode: val.shopCode })
// router.push('/search/detail')
}
//
function getLetterKey(letter: string) {
if (letter.length > INPUT_MAX_LEN.value) {
return
}
input.value = letter
}
//
function handleMode(val: string) {
mode.value = val
}
function del() {
keyboardRef.value.clear()
}
//
function handleHotSearch(item: Shop) {
const val = shopList.value.find(cc => cc.shopCode === item.shopCode)
if (!val) {
return
}
store.SET_SHOP(val)
store.SET_SHOW_DETAIL(true)
// router.push('/search/detail')
}
//
// function handleSwitch(index: 0 | 1) {
// switchIdx.value = index
// switch (index) {
// case 0:
// keyboardRef.value?.handleChangeKeyboardMode('keyboard')
// break
// case 1:
// keyboardRef.value?.handleChangeKeyboardMode('hand')
// break
// default:
// break
// }
// }
/* function back() {
if (selectedModule.value) {
router.push(selectedModule.value.url)
} else {
router.push('/home')
}
} */
</script>
<style lang="scss" scoped>
.search-container {
position: absolute;
top: 0;
z-index: 100;
width: 1600px;
height: 856px;
margin-top: 112px;
margin-left: 160px;
background: #f5f5f5;
border-radius: 16px;
--animate-duration: 700ms;
.bg {
position: absolute;
top: 0;
right: 0;
z-index: 0;
width: 680px;
height: 856px;
background-color: rgb(255 255 255 / 100%);
border-radius: 0 16px 16px 0;
}
.line {
position: absolute;
top: 433px;
left: 64px;
z-index: 2;
width: 1008px;
height: 1px;
background: rgb(255 255 255 / 20%);
}
.title {
position: absolute;
top: 48px;
right: 285px;
z-index: 1;
font-size: 48px;
font-family: 'font_bold';
color: #534f46;
span:nth-child(2) {
margin-right: 20px;
margin-left: 20px;
font-family: 'font_light';
opacity: 0.5;
}
.title-en {
display: inline-block;
width: 70px;
font-size: 18px;
font-family: 'font_regular';
color: #615c59;
line-height: 24px;
}
}
.close-btn {
position: absolute;
top: -40px;
right: -40px;
z-index: 1;
width: 100px;
height: 100px;
padding: 26px;
background: rgb(255 255 255 / 60%);
border: 2px solid #fff;
border-radius: 50px;
backdrop-filter: blur(20px);
// margin: auto;
img {
width: 48px;
}
}
.search-btn {
position: absolute;
top: 184px;
right: 68px;
width: 156px;
height: 72px;
padding: 16px 0;
font-size: 28px;
font-family: 'font_regular';
text-align: center;
color: #fff;
background: #e00068;
border-radius: 24px;
line-height: 37px;
}
.fac-container {
position: absolute;
top: 64px;
left: 48px;
// margin: 0px auto 0;
z-index: 1;
.fac-title {
z-index: 1;
display: flex;
justify-content: flex-start;
flex-direction: column;
margin-bottom: 24px;
font-size: 20px;
font-family: 'font_bold';
text-align: left;
color: #615c59;
.fac-zh {
font-size: 20px;
}
.fac-en {
font-size: 20px;
font-family: 'font_rugular';
}
}
.fac-scroll {
overflow: hidden;
width: 856px;
height: 90px;
margin-top: 0;
margin-left: -64px;
// text-align: center;
// &.center {
// display: flex;
// justify-content: center;
// }
.facilities {
display: flex;
width: fit-content;
padding-left: 64px;
// justify-content: center;
// flex-wrap: nowrap;
// grid-template-rows: repeat(1, 100%);
// grid-template-columns: repeat(1, 44px);
gap: 0 24px;
.facility {
display: inline-block;
// height: 62px;
// margin-right: 40px;
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
width: 44px;
// white-space: nowrap;
flex-direction: column;
.facility-icon {
width: 100%;
height: 44px;
object-fit: scale-down;
margin-bottom: 8px;
// box-shadow: 2px 4px 16px rgba(142, 142, 142, 0.16);
border-radius: 0;
}
.facility-name {
height: 32px;
font-size: 12px;
font-family: 'font_regular';
text-align: center;
color: #8e9090;
}
}
}
}
}
.search-wrapper {
position: absolute;
top: 184px;
right: 244px;
z-index: 3;
// margin: 40px auto;
display: flex;
justify-content: flex-start;
align-items: center;
width: 368px;
height: 72px;
padding-left: 32px;
background: #0000;
border-radius: 24px;
opacity: 1;
// box-shadow: 0 1px 0 rgb(255 255 255 / 30%), inset 0 4px 30px rgb(0 0 0 / 2%);
.search-bg {
.first-icon {
position: absolute;
top: 16px;
left: 32px;
z-index: 1;
}
.bg-search {
position: absolute;
top: 0;
left: 0;
z-index: 0;
}
}
.saw {
position: absolute;
top: 27px;
left: 95px;
width: fit-content;
height: 24px;
padding-right: 10px;
font-size: 36px;
font-family: 'font_regular';
color: #534f4600;
transition: border-right 0.3s linear;
border-right: 1px solid #e00068;
animation: shadow 1.5s ease-in-out infinite;
@keyframes shadow {
0% {
border-right-color: #e00068;
}
100% {
border-right-color: #f175b300;
}
}
}
input {
position: absolute;
top: 16px;
left: 95px;
z-index: 4;
width: 70%;
height: 44px;
margin-top: 0;
margin-left: 0;
font-size: 36px;
font-family: 'font_regular';
text-align: left;
color: #534f46;
background-color: #fff0;
border: none;
outline: none;
// line-height: px;
vertical-align: middle;
&.istip {
height: 40px;
margin-top: 10px;
}
&::input-placeholder,
&::input-placeholder {
position: absolute;
top: 45%;
/* placeholder字体大小 */
font-size: 18px;
font-family: 'font_regular';
/* placeholder颜色 */
color: rgb(0 0 0 / 20%);
transform: translateY(-50%);
}
}
.search-tip {
position: absolute;
top: 50%;
left: 96px;
font-size: 18px;
font-family: 'font_regular';
color: #8e9090;
transform: translateY(-50%);
}
.close {
position: relative;
z-index: 5;
width: 40px;
height: 40px;
margin-top: 0;
margin-left: 280px;
background: #fff0;
border: 0 solid #cdaa7f;
border-radius: 50%;
opacity: 1;
.icon {
position: absolute;
top: 50%;
left: 50%;
width: 40px;
height: 40px;
object-fit: scale-down;
transform: translate(-50%, -50%);
}
}
}
.hot-container {
position: absolute;
top: 262px;
left: 64px;
width: 1008px;
.hot {
font-size: 24px;
font-family: 'font_bold';
text-align: left;
color: rgb(255 255 255 / 100%);
.hot-name {
margin-bottom: 0;
}
.hot-nameEn {
font-size: 19px;
font-family: 'font_medium';
color: rgb(255 255 255 / 100%);
}
img {
vertical-align: bottom;
}
}
.hot-scroll {
overflow: hidden;
width: 1136px;
height: 62px;
margin-top: 24px;
margin-left: -64px;
}
.hot-brands {
// display: flex;
width: fit-content;
padding-left: 64px;
// flex-wrap: wrap;
white-space: nowrap;
.brand {
display: inline-block;
flex-shrink: 0;
width: fit-content;
padding: 20px 32px;
margin-right: 16px;
margin-bottom: 0;
font-size: 16px;
font-family: 'font_bold';
text-align: center;
color: rgb(255 255 255 / 100%);
background: rgb(0 0 0 / 10%);
border: 1px solid rgb(0 0 0 / 10%);
border-radius: 50px;
// line-height: 19px;
opacity: 1;
// line-height: 56px;
// @include no-wrap();
}
}
}
.btn-group {
position: absolute;
top: 430px;
right: 56px;
}
.act-item {
margin-left: 50%;
transform: translateX(-50%);
}
}
</style>

160
src/views/Service/Service.vue

@ -0,0 +1,160 @@
<template>
<div class="service-container">
<!-- 切换按钮 -->
<switchTab
class="btn-group"
:width="364"
:height="68"
:wrapper-width="728"
:wrapper-height="68"
:list="list"
@click="handleSwitch"
></switchTab>
<transition
enter-active-class="animate__faster animate__animated animate__fadeInUp"
leave-active-class="animate__animated animate__fadeOutDown"
>
<!-- 顧客心聲 -->
<PictureText v-if="switchIdx === 1" :ac-list="customerVoiceList" :qr-list="qrCodeList" />
<!-- 服务 -->
<ScrollView v-else ref="actScroll" :list="serviceList" :refresh-delay="200" :scrollbar="true" class="service-scroll">
<ul class="act-list">
<serviceItem v-for="(item, index) in serviceList" :key="index" :service-item="item" @click="clickItem"></serviceItem>
</ul>
</ScrollView>
</transition>
<activityDetail v-if="showDetail" :act-info="currentItem" @close="showDetail = false"></activityDetail>
</div>
</template>
<script setup lang="ts">
// import { Autoplay, FreeMode, Pagination } from 'swiper'
// import { Swiper, SwiperSlide } from 'swiper/vue'
// import 'swiper/css'
// import 'swiper/css/free-mode'
// const modules = [Autoplay, FreeMode, Pagination]
import activityDetail from '@/components/ActivityDetail/ActivityDetail.vue'
import ScrollView from '@/base/ScrollView/ScrollView.vue'
import serviceItem from './ServiceItem.vue'
import { getServeList, getCustomerQRCodeList, getCustomerVoiceList } from '@/http/api/service'
import { nextTick, ref } from 'vue'
import switchTab from '@/components/SwitchTab/SwitchTab.vue'
import PictureText from '@/components/PictureText/PictureText.vue'
const list = [
{
name: '商场服务',
en: 'INTIMATE SERVICE',
icon: require('@/assets/images/service/icon_service.svg'),
iconSel: require('@/assets/images/service/icon_serviceSel.svg')
},
{
name: '顾客心声',
en: 'VOICE OF CUSTOMERS',
icon: require('../../assets/images/service/icon_Voice.svg'),
iconSel: require('../../assets/images/service/icon_VoiceSel.svg')
}
]
const serviceList = ref<Activity[]>([]) //
const qrCodeList = ref<MmeberQRCode[]>([]) //
const customerVoiceList = ref<CustomerVoice[]>([]) //
const switchIdx = ref(0)
const currentItem = ref<Activity>()
const showDetail = ref(false)
const actScroll = ref()
function clickItem(item: Activity) {
// useStatisticsModel({ recordType: 2, moduleName: item.activityName, activityCode: item.id })
currentItem.value = item
showDetail.value = true
}
/**
*
* @param index 点击分类
*/
function handleSwitch(index: number) {
if (switchIdx.value === index) {
return
}
switchIdx.value = index
if (switchIdx.value === 0) {
nextTick(() => {
actScroll.value.refresh()
})
}
}
function getData() {
getServeList().then(res => {
for (let t = 0; t < res.data.length; t++) {
const { name, nameEn, content, contentEn, file_code, point, logo_code } = res.data[t].content
serviceList.value.push({
id: res.data[t].id,
activityContent: content,
activityContentEn: contentEn,
activityName: name,
activityNameEn: nameEn,
point,
logo_code,
fileUrl: file_code ?? [],
shopCode: ''
})
}
})
getCustomerQRCodeList().then(res => {
for (let t = 0; t < res.data.length; t++) {
const ele = res.data[t]
qrCodeList.value.push({ id: ele.id, ...ele.content })
}
})
getCustomerVoiceList().then(res => {
for (let t = 0; t < res.data.length; t++) {
const ele = res.data[t]
customerVoiceList.value.push({ id: ele.id, ...ele.content })
}
})
}
getData()
</script>
<style lang="scss" scoped>
:deep(.bscroll-vertical-scrollbar) {
z-index: 3 !important;
// width: 500px !important;
background: rgb(0 0 0 / 10%);
border-radius: 6px;
opacity: 1 !important;
.bscroll-indicator {
background: #e0006891 !important;
border: none !important;
border-radius: 6px !important;
}
}
.service-container {
overflow: hidden;
padding-top: 152px;
padding-left: 56px;
--animate-duration: 0.5s;
.service-scroll {
position: relative;
overflow: hidden;
width: 1828px;
height: 615px;
margin-top: 40px;
margin-left: 0;
:deep(.swiper-slide) {
width: 880px !important;
height: 575px;
}
.act-list {
// display: flex;
display: grid;
grid-template-columns: repeat(6, 288px);
gap: 16px 16px;
}
}
}
</style>

58
src/views/Service/ServiceItem.vue

@ -0,0 +1,58 @@
<template>
<li class="service-item" @click="clickItem(serviceItem)">
<img :src="serviceItem.logo_code[0]" class="service-icon" alt="" />
<ul>
<li class="text">{{ serviceItem.activityName }}</li>
<li class="text">{{ serviceItem.activityNameEn }}</li>
</ul>
</li>
</template>
<script setup lang="ts">
type SItem = {
serviceItem: Activity
}
const props = withDefaults(defineProps<SItem>(), {})
const $emit = defineEmits(['click'])
function clickItem(item: Activity) {
$emit('click', item)
}
</script>
<style lang="scss" scoped>
.service-item {
position: relative;
width: 288px;
height: 288px;
padding-top: 52px;
padding-left: 48px;
background-color: rgb(255 255 255 / 40%);
border: 2px solid white;
border-radius: 16px;
.service-icon {
width: 64px;
height: 64px;
object-fit: scale-down;
margin-bottom: 76px;
}
ul {
font-size: 24px;
font-family: 'font_regular';
color: #534f46;
.text {
&:nth-child(1) {
max-width: 196px;
@include no-wrap();
}
&:nth-child(2) {
overflow: hidden;
max-width: 96px;
height: 28px;
margin-top: 6px;
font-size: 12px;
line-height: 14px;
}
}
}
}
</style>
Loading…
Cancel
Save