index.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import { useMemo, useState, memo } from "react";
  2. import { View, Image,Text } from "@tarojs/components";
  3. import Taro from '@tarojs/taro'
  4. import PageCustom from "@/components/page-custom/index";
  5. import NavBarNormal from "@/components/NavBarNormal/index";
  6. import WemetaInput from "@/components/wemeta-input/index";
  7. import Popup from "@/components/popup/popup";
  8. import style from './index.module.less'
  9. import editorStyle from "../editor.module.less";
  10. import BottomBar from "@/components/BottomBar";
  11. import { useComponentStore } from "@/store/componentStore";
  12. import { uploadImage } from "@/utils/http";
  13. import { EComponentType } from "@/consts/enum";
  14. export default function Index() {
  15. let currentComponent = useComponentStore((state)=> state.currentComponent);
  16. if(!currentComponent){
  17. return <></>
  18. }
  19. const { saveComponent } = useComponentStore();
  20. const loading = useComponentStore((state)=> state.loading);
  21. const data = currentComponent.data;
  22. const [linkValue, setLinkValue] = useState<{
  23. name: string;
  24. shortLink: string;
  25. poster: string;
  26. }>(data.value);
  27. const [show, setShow] = useState(false);
  28. const setValueByKey = (key: string, v: string) => {
  29. setLinkValue((prev)=> {
  30. prev[key] = v;
  31. return {...prev};
  32. });
  33. };
  34. const handleSubmit = async () => {
  35. if(!data?.id){
  36. return
  37. }
  38. if(loading){
  39. return;
  40. }
  41. const c = {
  42. data: {
  43. value: linkValue,
  44. layout: 'full',
  45. id: data.id,
  46. index: data.index,
  47. },
  48. enabled: currentComponent?.enabled ?? true,
  49. type: EComponentType.miniProgram,
  50. };
  51. const result = await saveComponent(c)
  52. if(result){
  53. Taro.navigateBack()
  54. }
  55. };
  56. const RenderPoster = memo(({src}:{src: string})=> {
  57. if(src){
  58. console.log('render image')
  59. return (
  60. <View className="overflow-hidden">
  61. <Image
  62. className="w-160 h-160"
  63. mode="widthFix"
  64. style="height:auto"
  65. src={src}
  66. ></Image>
  67. </View>
  68. )
  69. }
  70. return (
  71. <>
  72. <View>
  73. <Image src='https://cdn.wehome.cn/cmn/png/100/META-H8UKVHWU-KIGP3BIL7M5AYC6XHNUA2-VDZCWI2M-O91.png' className={style.iconAdd}></Image>
  74. </View>
  75. <View className="text-gray-45 text-12 leading-20 text-center">建议上传1:1标准尺寸图</View>
  76. </>
  77. )
  78. })
  79. // useMemo 麻烦...
  80. const RenderPosterCached = useMemo(()=> {
  81. return <RenderPoster src={linkValue.poster}></RenderPoster>
  82. }, [linkValue.poster])
  83. const handleAddPoster = () => {
  84. Taro.chooseImage({
  85. count: 1,
  86. sizeType: ['original', 'compressed'],
  87. sourceType: ['album', 'camera'],
  88. async success (chooseImageRes) {
  89. const tempFilePaths = chooseImageRes.tempFilePaths
  90. Taro.cropImage({
  91. src: tempFilePaths[0],
  92. cropScale: "1:1",
  93. success: async (cropRes) => {
  94. const path = cropRes.tempFilePath;
  95. const res = await uploadImage(path);
  96. if (res?.publicUrl) {
  97. setValueByKey('poster', res.publicUrl)
  98. }
  99. },
  100. });
  101. }
  102. })
  103. };
  104. const renderTips = () => {
  105. return (
  106. <>
  107. <View>
  108. 🌟 <Text className="font-medium">小蓝本提示:</Text>
  109. <Text>打开小程序主页 - 顶部更多操作/评分入口 - 复制链接</Text>
  110. </View>
  111. <Image
  112. className="w-full"
  113. mode="widthFix"
  114. src="https://cdn.wehome.cn/cmn/png/102/META-H8UKWHWU-KIWQFXN9CWIKI7PA148U3-N5Z1UG4M-H7.png"
  115. ></Image>
  116. </>
  117. );
  118. };
  119. return (
  120. <PageCustom>
  121. <NavBarNormal>小程序链接</NavBarNormal>
  122. <View className="flex flex-col items-center w-full">
  123. <View className="px-16 pt-12 pb-120 w-full">
  124. <View className={editorStyle.formContainer}>
  125. <View className={editorStyle.formItem}>
  126. <View className={editorStyle.formItemLabel}>
  127. <View className="flex-1">小程序名称</View>
  128. </View>
  129. <WemetaInput
  130. value={linkValue.name}
  131. onInput={(value: string) => setValueByKey("name", value)}
  132. placeholder="请输入小程序名字..."
  133. maxlength={50}
  134. />
  135. </View>
  136. <View className={editorStyle.formItem}>
  137. <View className={editorStyle.formItemLabel}>
  138. <View className="flex-1">小程序链接</View>
  139. <View className="text-green" onClick={()=> setShow(true)}>
  140. 如何获取?
  141. </View>
  142. </View>
  143. <WemetaInput
  144. value={linkValue.shortLink}
  145. onInput={(value: string) => setValueByKey("shortLink", value)}
  146. placeholder="长按粘贴小程序链接..."
  147. />
  148. </View>
  149. <View className={editorStyle.formItem}>
  150. <View className={editorStyle.formItemLabel}>
  151. <View className="flex-1">封面图 <Text className="text-gray-45">(选填)</Text></View>
  152. </View>
  153. <View className={`${style.coverContainer}`} onClick={handleAddPoster}>
  154. {RenderPosterCached}
  155. </View>
  156. </View>
  157. </View>
  158. </View>
  159. </View>
  160. <BottomBar>
  161. <View className="button-rounded button-primary flex-1" onClick={handleSubmit}>保存</View>
  162. </BottomBar>
  163. <Popup
  164. title='获取小程序链接'
  165. show={show}
  166. setShow={setShow}
  167. >
  168. <View className="flex flex-col gap-16 mb-88" onClick={handleAddPoster}>
  169. <View
  170. className={`flex flex-col p-12 gap-10 text-14 rounded-20 leading-22 text-gray-65 bg-gray-f8 overflow-hidden`}
  171. >
  172. {renderTips()}
  173. </View>
  174. </View>
  175. </Popup>
  176. </PageCustom>
  177. );
  178. }