广告屏react-native项目
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 

898 rader
25 KiB

  1. import React, { Component } from 'react';
  2. import {
  3. Platform,
  4. StyleSheet,
  5. Text,
  6. View,
  7. Image,
  8. ImageBackground,
  9. PixelRatio,
  10. NativeModules
  11. } from 'react-native';
  12. //引用插件
  13. import Package from './package.json'
  14. import HttpUtils from './HttpUtils.js';
  15. import CodePush from "react-native-code-push";
  16. import DeviceInfo from "react-native-device-info";
  17. import * as Animatable from 'react-native-animatable';
  18. var testMac = 'FF:FF:FF:FF:FF:FF'
  19. var curAdIndex = 0;
  20. var errorMsg = {
  21. ERR_MAC_GET:'设备编号获取错误',
  22. ERR_START_AD:'广告播放系统错误',
  23. ERR_DATA_GET:'广告数据获取错误',
  24. ERR_HEARTBEAT:'设备心跳数据错误',
  25. ERR_NO_DATA:'暂无优惠信息'
  26. }
  27. var animationThemes = [
  28. // 滑入
  29. {
  30. first:"slideInDown",
  31. second:"slideInLeft",
  32. third:"slideInRight"
  33. },
  34. // 放大
  35. {
  36. first:"zoomInDown",
  37. second:"zoomInLeft",
  38. third:"zoomInRight"
  39. },
  40. // 翻转
  41. {
  42. first:"flipInX",
  43. second:"flipInY",
  44. third:"flipInX"
  45. },
  46. // 弹出
  47. {
  48. first:"bounceInDown",
  49. second:"bounceInLeft",
  50. third:"bounceInRight"
  51. }
  52. ]
  53. var timer = null;
  54. var hbRequestCount
  55. var getAdDataCount
  56. var pageChangeCount
  57. var adDataList = []
  58. var heartConfig = {
  59. heartbeatInterval:10,
  60. dataRefreshInterval:3600,
  61. pageChangeInterval:10,
  62. }
  63. var requestFailedCount = 0;
  64. var versionInfo = '';
  65. let codePushOptions = {
  66. //设置检查更新的频率
  67. //ON_APP_RESUME APP恢复到前台的时候
  68. //ON_APP_START APP开启的时候
  69. //MANUAL 手动检查
  70. checkFrequency : CodePush.CheckFrequency.ON_APP_START
  71. };
  72. export default class MyPage extends Component {
  73. constructor(props) {
  74. super(props);
  75. this.state = {
  76. baseInfo: null,
  77. contentItem0:null,
  78. contentItem1:null,
  79. contentItem2:null,
  80. animationTheme:{},
  81. contentDisplayStatus:false,
  82. syncMessage: "初始化..." ,
  83. errorMessage: '加载中...',
  84. progress: {
  85. receivedBytes:0,
  86. totalBytes:0
  87. },
  88. updating:true,
  89. macAddress: '',
  90. versionInfo:'未知'
  91. };
  92. }
  93. //更新函数
  94. async codePushUpdate() {
  95. CodePush.allowRestart();
  96. await CodePush.getUpdateMetadata(CodePush.UpdateState.RUNNING)
  97. .then((metadata: LocalPackage) => {
  98. this.setState({ versionInfo: metadata ? 'b'+NativeModules.BuildConfig.versionCode+"-" + metadata.label : 'b'+ NativeModules.BuildConfig.versionCode});
  99. versionInfo = this.state.versionInfo;
  100. }, (error: any) => {
  101. this.setState({ versionInfo: "Unknown"});
  102. versionInfo = this.state.versionInfo;
  103. });
  104. await CodePush.sync(
  105. { mandatoryInstallMode: CodePush.InstallMode.ON_NEXT_RESTART,
  106. installMode: CodePush.InstallMode.ON_NEXT_RESTART},
  107. this.codePushStatusDidChange.bind(this),
  108. this.codePushDownloadDidProgress.bind(this)
  109. ).then((status: SyncStatus) => {
  110. }, (error: any) => {
  111. CodePush.restartApp();
  112. });
  113. }
  114. // 监听更新状态
  115. codePushStatusDidChange(syncStatus) {
  116. switch(syncStatus) {
  117. case CodePush.SyncStatus.CHECKING_FOR_UPDATE:
  118. this.setState({ syncMessage: "检查更新" });
  119. break;
  120. case CodePush.SyncStatus.DOWNLOADING_PACKAGE:
  121. this.setState({ syncMessage: "下载更新" });
  122. break;
  123. case CodePush.SyncStatus.AWAITING_USER_ACTION:
  124. this.setState({ syncMessage: "等待用户操作" });
  125. break;
  126. case CodePush.SyncStatus.INSTALLING_UPDATE:
  127. this.setState({ syncMessage: "安装更新" });
  128. break;
  129. case CodePush.SyncStatus.UP_TO_DATE:
  130. this.setState({ syncMessage: "已更新到最新程序", updating: false });
  131. break;
  132. case CodePush.SyncStatus.UPDATE_IGNORED:
  133. this.setState({ syncMessage: "更新被取消", updating: false });
  134. break;
  135. case CodePush.SyncStatus.UPDATE_INSTALLED:
  136. this.setState({ syncMessage: "更新已安装,重启应用后生效", updating: false });
  137. break;
  138. case CodePush.SyncStatus.UNKNOWN_ERROR:
  139. this.setState({ syncMessage: "未知错误", updating: false });
  140. break;
  141. }
  142. }
  143. codePushDownloadDidProgress(progress) {
  144. this.setState({ progress });
  145. }
  146. // 列表滚动
  147. updateContent() {
  148. if (adDataList.length <=0)
  149. return false;
  150. if (curAdIndex >= adDataList.length) {
  151. curAdIndex = 0
  152. }
  153. this.setState({contentItem0:adDataList[curAdIndex]});
  154. if (curAdIndex + 1 < adDataList.length)
  155. this.setState({contentItem1:adDataList[curAdIndex+1]});
  156. else
  157. this.setState({contentItem1:null});
  158. if (curAdIndex + 2 < adDataList.length)
  159. this.setState({contentItem2:adDataList[curAdIndex+2]});
  160. else
  161. this.setState({contentItem2:null});
  162. curAdIndex+=3
  163. return true;
  164. }
  165. hbRequest() {
  166. return HttpUtils.post(NativeModules.BuildConfig.apiHost
  167. + 'api/wxDeviceScreenAd/heartbeat?deviceId='
  168. + encodeURIComponent(this.state.macAddress),
  169. {version:this.state.versionInfo})
  170. .then(result => {
  171. if (result.code == 200) {
  172. let config = JSON.parse(result.data.config);
  173. heartConfig.heartbeatInterval = config.heartbeatInterval
  174. heartConfig.dataRefreshInterval=config.dataRefreshInterval
  175. heartConfig.pageChangeInterval=config.pageChangeInterval
  176. // 动画划入
  177. if(config.animationTheme == 0){
  178. this.setState({
  179. animationTheme:animationThemes[0]
  180. })
  181. }else if(config.animationTheme == 1){
  182. // 放大
  183. this.setState({
  184. animationTheme:animationThemes[1]
  185. })
  186. }else if(config.animationTheme == 2){
  187. // 淡入
  188. this.setState({
  189. animationTheme:animationThemes[2]
  190. })
  191. }else if(config.animationTheme == 3){
  192. // 弹入
  193. this.setState({
  194. animationTheme:animationThemes[3]
  195. })
  196. }
  197. } else {
  198. //do nothing
  199. }
  200. })
  201. .catch(error => {
  202. requestFailedCount++
  203. this.setState({ versionInfo: versionInfo+`[${requestFailedCount}]`});
  204. })
  205. }
  206.  showErrMsg(errMsg) {
  207. this.setState({contentDisplayStatus: false})
  208. this.setState({errorMessage : errMsg});
  209. }
  210. getAdDataList(first) {
  211. HttpUtils.get(NativeModules.BuildConfig.apiHost
  212. + 'api/wxDeviceScreenAd/list?deviceId='
  213. + encodeURIComponent(this.state.macAddress)
  214. + '&pageNum=1&pageSize=1000')
  215. .then(result => {
  216. if (result.code != 200) {
  217. this.showErrMsg(result.message+'\n'+this.state.macAddress);
  218. } else if (result.data.list) {
  219. adDataList = result.data.list;
  220. if (this.updateContent()) {
  221. this.setState({contentDisplayStatus: true})
  222. } else {
  223. this.showErrMsg(errorMsg.ERR_NO_DATA);
  224. }
  225. } else {
  226.  this.showErrMsg(errorMsg.ERR_DATA_GET);
  227. }
  228. })
  229. .catch(error => {
  230. if (first) {
  231. this.showErrMsg(error.message);
  232. }
  233. else {
  234. requestFailedCount++
  235. this.setState({ versionInfo: versionInfo+`[${requestFailedCount}]`});
  236. }
  237. })
  238. }
  239. getBaseInfo() {
  240. HttpUtils.get(NativeModules.BuildConfig.apiHost
  241. + 'api/wxDeviceScreenAd/info?deviceId='
  242. + encodeURIComponent(this.state.macAddress))
  243. .then(result => {
  244. if (result.code != 200) {
  245. this.showErrMsg(result.message+'\n'+this.state.macAddress);
  246. } else if (result.data) {
  247. this.setState({baseInfo:result.data});
  248. } else {
  249. this.showErrMsg(errorMsg.ERR_DATA_GET);
  250. }
  251. })
  252. .catch(error => {
  253. this.showErrMsg(error.message);
  254. })
  255. }
  256. componentDidMount() {
  257. this.codePushUpdate();
  258. DeviceInfo.getMACAddress().then((mac)=>{
  259. if (mac=='' || mac==null ) {
  260. if (NativeModules.BuildConfig.buildType == 'debug') {
  261. this.setState({macAddress : this.testMac})
  262. this.startAd()
  263. } else {
  264. this.showErrMsg(errorMsg.ERR_MAC_GET);
  265. }
  266. } else {
  267. this.setState({macAddress : mac})
  268. this.startAd()
  269. }
  270. }).catch(e => {
  271. this.showErrMsg(errorMsg.ERR_START_AD);
  272. })
  273. }
  274. componentWillUnmount(){
  275. if (timer)
  276. clearTimeout(timer)
  277. }
  278. async routine() {
  279. hbRequestCount -=1;
  280. getAdDataCount -=1;
  281. pageChangeCount -=1;
  282. try {
  283. if (getAdDataCount<=0) {
  284. this.getAdDataList(false)
  285. getAdDataCount = heartConfig.dataRefreshInterval
  286. } else if (hbRequestCount<=0) {
  287. this.hbRequest()
  288. hbRequestCount = heartConfig.heartbeatInterval
  289. }
  290. if (pageChangeCount <= 0) { //页面切换间隔
  291. if (this.state.contentDisplayStatus && this.state.baseInfo) {
  292. this.setState({ contentDisplayStatus: false})
  293. if (this.updateContent()) {
  294. this.setState({ contentDisplayStatus: true})
  295. }
  296. } else {
  297. await this.getBaseInfo()
  298. await this.getAdDataList(true)
  299. getAdDataCount = heartConfig.dataRefreshInterval
  300. hbRequestCount = heartConfig.heartbeatInterval
  301. }
  302. pageChangeCount = heartConfig.pageChangeInterval
  303. }
  304. } catch(e){
  305. this.setState({ versionInfo: versionInfo+'[E]'});
  306. }
  307. timer = setTimeout(()=>{
  308. this.routine();
  309. },1000);
  310. }
  311. startAd() {
  312. hbRequestCount = 0;
  313. getAdDataCount = 0;
  314. pageChangeCount = 0;
  315. this.routine();
  316. }
  317. getContentViewItemUplayer(contentItem) {
  318. if (contentItem.type == 0) {
  319. if (contentItem.subType == 2)
  320. return (<Image source={require('./image/timed.png')} resizeMode='center' style={styles.contentItemUpLayer} /> )
  321. if (contentItem.subType == 6)
  322. return (<Image source={require('./image/discount.png')} resizeMode='center' style={styles.contentItemUpLayer} /> )
  323. if (contentItem.subType == 7)
  324. return (<Image source={require('./image/groupbuy.png')} resizeMode='center' style={styles.contentItemUpLayer} /> )
  325. return null;
  326. }
  327. }
  328. getContentViewItemActionStr(contentItem) {
  329. if (contentItem.type == 0) {
  330. if (contentItem.subType == 2)
  331. return '扫码秒杀';
  332. else if (contentItem.subType == 6)
  333. return '扫码砍价';
  334. else if (contentItem.subType == 7)
  335. return '扫码拼团';
  336. else
  337. return '扫码领取';
  338. }
  339. }
  340. getContentViewItemMerchantName(contentItem) {
  341. if (contentItem.type == 0) {
  342. if (contentItem.target.merchantVoList.length > 1)
  343. return '多商户通用';
  344. else
  345. return contentItem.target.merchantVoList[0].merchantName;
  346. }
  347. }
  348. getContentViewItem(contentItem, annomation) {
  349. if (!contentItem)
  350. return (
  351. <View style={styles.contentItem}>
  352. </View>
  353. )
  354. actionText = this.getContentViewItemActionStr(contentItem);
  355. merchantName = this.getContentViewItemMerchantName(contentItem);
  356. // console.warn(annomation)
  357. return (
  358. <Animatable.View animation={annomation} style={styles.contentItem}>
  359. <ImageBackground source={require('./image/item-background.png')} resizeMode='center' style={styles.contentItemDownLayer} >
  360. {/* 列表 */}
  361. <View style={styles.contentItemTop}>
  362. <Image source={{uri: contentItem.coverImg}} resizeMode='cover' style={styles.contentItemTopCoverImg} />
  363. <View style={styles.contentItemTopDetail}>
  364. {/* 券的title */}
  365. <Text style={styles.contentItemTopDetailTitle} numberOfLines={2} ellipsizeMode="tail">{contentItem.target.title}</Text>
  366. <View style={styles.contentItemTopDetailPrice}>
  367. {/* 售价 */}
  368. <View style={styles.contentItemTopDetailCurPrice}>
  369. <Text style={styles.contentItemTopDetailCurPriceStrUnit}>¥</Text>
  370. <Text style={styles.contentItemTopDetailCurPriceStr}>{contentItem.target.salePriceStr}</Text>
  371. </View>
  372. {/* 面额 */}
  373. <View style={styles.contentItemTopDetailSalePrice}>
  374. <Text style={styles.contentItemTopDetailSalePriceStr} >¥{contentItem.target.priceStr}</Text>
  375. </View>
  376. </View>
  377. </View>
  378. {/* <Image source={{uri:'data:image/png;base64,'+contentItem.qrcode}} resizeMode='contain' style={styles.contentItemTopQrcode} /> */}
  379. <Image source={{uri:contentItem.target.qrCode}} resizeMode='contain' style={styles.contentItemTopQrcode} />
  380. </View>
  381. {/* 优惠券底部商户名称 */}
  382. <View style={styles.contentItemBottom}>
  383. <Text style={styles.contentItemBottomMerchantName}>{merchantName}</Text>
  384. <Text style={styles.contentItemBottomPlacehold}>{contentItem.target.merchantVoList[0].buildingName}{contentItem.target.merchantVoList[0].floorName}</Text>
  385. <Text style={styles.contentItemBottomAction}>{actionText}</Text>
  386. </View>
  387. </ImageBackground>
  388. {this.getContentViewItemUplayer(contentItem)}
  389. </Animatable.View>
  390. )
  391. }
  392. getContentView() {
  393. if (this.state.contentDisplayStatus) {
  394. return (<View style={styles.content}>
  395. {this.getContentViewItem(this.state.contentItem0,this.state.animationTheme.first)}
  396. {this.getContentViewItem(this.state.contentItem1,this.state.animationTheme.second)}
  397. {this.getContentViewItem(this.state.contentItem2,this.state.animationTheme.third)}
  398. </View>)
  399. }else{
  400. return (
  401. <View style={styles.content}>
  402. <Text style={styles.updatePage}>{this.state.errorMessage}</Text>
  403. </View>)
  404. }
  405. }
  406. getUpdateView() {
  407. if (this.state.progress.totalBytes > 0)
  408. return (
  409. <Text style={styles.updatePage}>{this.state.syncMessage}{'\n'}
  410. {this.state.progress.receivedBytes} of {this.state.progress.totalBytes} bytes received{'\n'}
  411. </Text>
  412. );
  413. return (
  414. <Text style={styles.updatePage}>{this.state.syncMessage}
  415. </Text>
  416. );
  417. }
  418. getAdView(){
  419. if (this.state.baseInfo) {
  420. return (
  421. <ImageBackground style={styles.background} resizeMode='center' source={require('./image/background.png')}>
  422. {/* 头部title二维码开始 */}
  423. <View style={styles.title}>
  424. <View style={styles.titleImagePlace}>
  425. <Image source={require('./image/title.png')} resizeMode='center' style={styles.titleImage} />
  426. </View>
  427. <ImageBackground source={require('./image/title-qrcode.png') } resizeMode='center' style={styles.titleQrcodeBonder} >
  428. <View style={styles.titleQrcodePlacehold}></View>
  429. <Image source={{uri: this.state.baseInfo.imgQrcodeWeapp}} resizeMode='center' style={styles.titleQrcode} />
  430. <View style={styles.titleQrcodePlacehold}></View>
  431. </ImageBackground>
  432. </View>
  433. {/* 券列表展示列表开始 */}
  434. {this.getContentView()}
  435. {/* 底部商场信息展示开始 */}
  436. <View style={styles.bottom}>
  437. <View style={styles.bottomLogoBackground}>
  438. <Image source={{ uri: this.state.baseInfo.imgUrlH}} resizeMode='contain' style={styles.bottomLogo} />
  439. </View>
  440. <View style={styles.bottomQrcode1Background}>
  441. <Image source={{ uri: this.state.baseInfo.imgQrcodeWeapp}} resizeMode='center' style={styles.bottomQrcode1} />
  442. <Text style={styles.bottomQrcode1Str}>小程序</Text>
  443. </View>
  444. <View style={styles.bottomQrcode2Background}>
  445. <Image source={{ uri: this.state.baseInfo.imgQrcodeWemp}} resizeMode='center' style={styles.bottomQrcode2} />
  446. <Text style={styles.bottomQrcode1Str}>公众号</Text>
  447. </View>
  448. <Text style={styles.bottomPlacehold}>{this.state.versionInfo}</Text>
  449. </View>
  450. </ImageBackground>
  451. );}
  452. else {
  453. return (
  454. <ImageBackground style={styles.background} resizeMode='center' source={require('./image/background.png')}>
  455. {/* 头部title二维码开始 */}
  456. <View style={styles.title}>
  457. </View>
  458. {/* 券列表展示列表开始 */}
  459. {this.getContentView()}
  460. {/* 底部商场信息展示开始 */}
  461. <View style={styles.bottom}>
  462. <View style={styles.bottomLogoBackground}>
  463. </View>
  464. <View style={styles.bottomQrcode1Background}>
  465. </View>
  466. <View style={styles.bottomQrcode2Background}>
  467. </View>
  468. <Text style={styles.bottomPlacehold}>{this.state.versionInfo}</Text>
  469. </View>
  470. </ImageBackground>
  471. );
  472. }
  473. }
  474. render() {
  475. if (this.state.updating) {
  476. return this.getUpdateView();
  477. }
  478. return this.getAdView();
  479. }
  480. }
  481. MyPage = CodePush(codePushOptions)(MyPage);
  482. const styles = StyleSheet.create({
  483. updatePage:{
  484. flex: 2,
  485. width:'100%',
  486. height:'100%',
  487. backgroundColor:'transparent',
  488. textAlign :'center',
  489. textAlignVertical:'center',
  490. fontSize: 63/PixelRatio.get(),
  491. color: 'darkblue'
  492. },
  493. //layer background
  494. background:{
  495. flex: 1,
  496. width:'100%',
  497. height:'100%'
  498. },
  499. //layer top
  500. title:{
  501. flex: 6,
  502. flexDirection: 'row',
  503. alignItems: 'center',
  504. paddingLeft:42/PixelRatio.get(),
  505. paddingRight:42/PixelRatio.get(),
  506. backgroundColor:'transparent'
  507. },
  508. content:{
  509. flex: 18,
  510. flexDirection: 'column',
  511. alignItems: 'center',
  512. backgroundColor:'transparent'
  513. },
  514. bottom:{
  515. flex: 2,
  516. flexDirection: 'row',
  517. alignItems: 'center',
  518. paddingLeft:42/PixelRatio.get(),
  519. paddingRight:42/PixelRatio.get(),
  520. backgroundColor:'transparent'
  521. },
  522. //layer title
  523. titleImagePlace: {
  524. flex: 2,
  525. paddingTop: '20%',
  526. paddingLeft: '15%',
  527. alignItems: 'center',
  528. backgroundColor:'transparent'
  529. },
  530. titleImage: {
  531. width:'100%',
  532. height:'100%',
  533. flex: 1,
  534. backgroundColor:'transparent'
  535. },
  536. titleQrcodeBonder: {
  537. width:'100%',
  538. height:'100%',
  539. alignItems: 'center',
  540. flexDirection: 'column',
  541. flex: 1,
  542. backgroundColor:'transparent'
  543. },
  544. titleQrcodePlacehold: {
  545. flex: 5,
  546. backgroundColor:'transparent'
  547. },
  548. titleQrcode: {
  549. flex: 6,
  550. width:'100%',
  551. height:'100%',
  552. backgroundColor:'transparent'
  553. },
  554. //layer bottom
  555. bottomLogoBackground: {
  556. flex: 3,
  557. borderRadius:16/PixelRatio.get(),
  558. marginTop: 26/PixelRatio.get(),
  559. marginBottom: 26/PixelRatio.get(),
  560. backgroundColor:'transparent',//'rgba(255,255,255,0.5)',
  561. },
  562. bottomLogo: {
  563. width:'100%',
  564. height:'100%',
  565. backgroundColor:'transparent'
  566. },
  567. bottomQrcode1Background : {
  568. flex: 1,
  569. width:'100%',
  570. height:'100%',
  571. marginLeft: 21/PixelRatio.get(),
  572. paddingTop: 27/PixelRatio.get(),
  573. paddingBottom: 11/PixelRatio.get(),
  574. flexDirection: 'column',
  575. backgroundColor:'transparent'
  576. },
  577. bottomQrcode2Background : {
  578. flex: 1,
  579. width:'100%',
  580. height:'100%',
  581. marginLeft: 21/PixelRatio.get(),
  582. paddingTop: 26/PixelRatio.get(),
  583. paddingBottom: 11/PixelRatio.get(),
  584. flexDirection: 'column',
  585. backgroundColor:'transparent'
  586. },
  587. bottomQrcode1: {
  588. flex: 2,
  589. width:'100%',
  590. height:'100%',
  591. backgroundColor:'transparent'
  592. },
  593. bottomQrcode2: {
  594. flex: 2,
  595. width:'100%',
  596. height:'100%',
  597. backgroundColor:'transparent'
  598. },
  599. bottomQrcode1Str: {
  600. flex: 1,
  601. textAlign :'center',
  602. textAlignVertical:'center',
  603. fontSize: 16/PixelRatio.get(),
  604. color : 'white',
  605. backgroundColor:'transparent'
  606. },
  607. bottomQrcode2Str: {
  608. flex: 1,
  609. textAlign :'center',
  610. textAlignVertical:'center',
  611. fontSize: 16/PixelRatio.get(),
  612. color : 'white',
  613. backgroundColor:'transparent'
  614. },
  615. bottomPlacehold: {
  616. flex: 8,
  617. width:'100%',
  618. height:'100%',
  619. backgroundColor:'transparent',
  620. textAlign :'right',
  621. textAlignVertical:'bottom',
  622. fontSize: 27/PixelRatio.get(),
  623. color : 'gray'
  624. },
  625. //layer content item
  626. contentItem:{
  627. flex: 1,
  628. width:'100%',
  629. height:'100%',
  630. flexDirection: 'column',
  631. backgroundColor:'transparent'
  632. },
  633. contentItemDownLayer:{
  634. position:'absolute',
  635. width:'100%',
  636. height:'100%',
  637. flexDirection: 'column',
  638. alignItems: 'center',
  639. backgroundColor:'transparent'
  640. },
  641. contentItemUpLayer:{
  642. width:210/PixelRatio.get(),
  643. height:153/PixelRatio.get(),
  644. position:'absolute',
  645. backgroundColor:'transparent'
  646. },
  647. contentItemTop:{
  648. flex: 3,
  649. width:'100%',
  650. height:'100%',
  651. paddingLeft: 66/PixelRatio.get(),
  652. paddingRight: 53/PixelRatio.get(),
  653. paddingTop: 40/PixelRatio.get(),
  654. flexDirection: 'row',
  655. alignItems: 'center',
  656. backgroundColor:'transparent'
  657. },
  658. contentItemBottom:{
  659. flex: 1,
  660. width:'100%',
  661. height:'100%',
  662. paddingLeft: 66/PixelRatio.get(),
  663. paddingRight: 53/PixelRatio.get(),
  664. paddingBottom: 40/PixelRatio.get(),
  665. flexDirection: 'row',
  666. alignItems: 'center',
  667. backgroundColor:'transparent'
  668. },
  669. //layer content item top
  670. contentItemTopCoverImg:{
  671. flex: 5,
  672. width:'100%',
  673. height:'100%',
  674. borderRadius:27/PixelRatio.get(),
  675. backgroundColor:'transparent'
  676. },
  677. contentItemTopDetail:{
  678. flex: 6,
  679. width:'100%',
  680. height:'100%',
  681. paddingLeft: 20/PixelRatio.get(),
  682. paddingRight: 20/PixelRatio.get(),
  683. alignItems: 'center',
  684. backgroundColor:'transparent'
  685. },
  686. contentItemTopQrcode:{
  687. flex: 5,
  688. width:'100%',
  689. height:'100%',
  690. // borderStyle:"solid",
  691. // borderWidth:1,
  692. // borderColor:"red",
  693. marginLeft:18/PixelRatio.get(),
  694. backgroundColor:'transparent'
  695. },
  696. //layer content item bottom
  697. contentItemBottomMerchantName:{
  698. flex: 5,
  699. width:'100%',
  700. height:'100%',
  701. alignItems: 'center',
  702. color:"black",
  703. backgroundColor:'transparent',
  704. textAlign :'center',
  705. textAlignVertical:'center',
  706. fontSize: 27/PixelRatio.get(),
  707. fontWeight : 'bold'
  708. },
  709. contentItemBottomPlacehold:{
  710. flex: 6,
  711. fontSize: 27/PixelRatio.get(),
  712. paddingLeft: 27/PixelRatio.get(),
  713. paddingRight: 79/PixelRatio.get(),
  714. width:'100%',
  715. height:'100%',
  716. color:"black",
  717. textAlignVertical:'center',
  718. backgroundColor:'transparent',
  719. },
  720. contentItemBottomAction:{
  721. flex: 5,
  722. width:'100%',
  723. height:'100%',
  724. backgroundColor:'transparent',
  725. textAlign :'center',
  726. textAlignVertical:'center',
  727. fontSize: 36/PixelRatio.get(),
  728. color: 'black',
  729. // borderStyle:"solid",
  730. // borderWidth:1,
  731. // borderColor:"red"
  732. },
  733. // 券的title
  734. contentItemTopDetailTitle:{
  735. flex: 2,
  736. // height:'100%',
  737. width:'100%',
  738. marginTop:"2%",
  739. // borderStyle:"solid",
  740. // borderWidth:1,
  741. // borderColor:"red",
  742. backgroundColor:'transparent',
  743. textAlign :'left',
  744. color:"black",
  745. textAlignVertical:'center',
  746. fontSize: 53/PixelRatio.get(),
  747. },
  748. /*
  749. contentItemTopDetailRemark:{
  750. flex: 1,
  751. width:'100%',
  752. height:'100%',
  753. backgroundColor:'transparent',
  754. textAlign :'left',
  755. textAlignVertical:'center',
  756. fontSize: 27/PixelRatio.get(),
  757. color : 'gray'
  758. },
  759. */
  760. contentItemTopDetailPrice:{
  761. flex: 2,
  762. width:'100%',
  763. height:'100%',
  764. backgroundColor:'transparent',
  765. flexDirection: 'row',
  766. },
  767. // 售价的样式
  768. contentItemTopDetailCurPrice:{
  769. position:"absolute",
  770. bottom:10,
  771. left:0,
  772. width:'100%',
  773. height:'100%',
  774. flexDirection: 'row',
  775. backgroundColor:'transparent',
  776. },
  777. contentItemTopDetailCurPriceStr:{
  778. backgroundColor:'transparent',
  779. fontSize:96/PixelRatio.get(),
  780. fontFamily:"PingFangSC-Bold",
  781. fontWeight: "bold",
  782. textAlign :'left',
  783. textAlignVertical:'bottom',
  784. color : 'red'
  785. },
  786. contentItemTopDetailCurPriceStrUnit:{
  787. backgroundColor:'transparent',
  788. textAlign :'left',
  789. textAlignVertical:'bottom',
  790. paddingBottom: 16/PixelRatio.get(),
  791. fontSize: 48/PixelRatio.get(),
  792. color : 'red'
  793. },
  794. // 面额的样式
  795. contentItemTopDetailSalePrice:{
  796. position:"absolute",
  797. bottom:2,
  798. left:0,
  799. // flex: 1,
  800. paddingTop:50,
  801. width:'100%',
  802. // height:'100%',
  803. backgroundColor:'transparent',
  804. },
  805. contentItemTopDetailSalePriceStr:{
  806. width:'100%',
  807. height:'100%',
  808. backgroundColor:'transparent',
  809. textAlign :'left',
  810. textAlignVertical:'bottom',
  811. fontSize: 27/PixelRatio.get(),
  812. textDecorationLine: 'line-through',
  813. color : 'gray'
  814. },
  815. });