makePoster.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. <template>
  2. <view>
  3. <view class="head">
  4. <view class="left"
  5. >海报预览
  6. <text class="text"> (请拖动到下方编辑、保存海报) </text>
  7. </view>
  8. <My_upload @uploadCallback="handleFileLink">
  9. <view class="right"> 更换背景图 </view>
  10. </My_upload>
  11. </view>
  12. <view class="painter-box">
  13. <view>
  14. <l-painter ref="painter" css="position: relative;">
  15. <!-- 背景图片 -->
  16. <l-painter-image
  17. :src="file.url"
  18. css="width: 280px; height: 500px"
  19. object-fit="fill"
  20. />
  21. <!-- 模板1 底部背景图 -->
  22. <l-painter-image
  23. v-if="mode == 'model1'"
  24. src="https://yossys06593.obs.cn-east-3.myhuaweicloud.com:443/202404101712714733820B3d50bdd4.png"
  25. css="width: 280px; height: 130px;position: absolute;bottom: 0;z-index: 1;"
  26. object-fit="fill"
  27. />
  28. <block v-if="mode == 'model1' || mode == 'model2'">
  29. <!-- 站点logo -->
  30. <l-painter-image
  31. :src="siteLogo"
  32. css="width: 60px; height:60px;position: absolute;bottom: 0px;left:10px;z-index: 2;"
  33. object-fit="cover"
  34. />
  35. <!-- 文字描述 -->
  36. <l-painter-text
  37. :text="painterText"
  38. :css="
  39. 'width: 190px; line-height:20px;position: absolute;bottom: 62px;left:10px;z-index: 2;font-size: 14px;color: #333333;line-clamp:2;' +
  40. 'color:' +
  41. textColor
  42. "
  43. />
  44. </block>
  45. <!-- 二维码 -->
  46. <l-painter-qrcode
  47. v-if="mode != 'default' && detail.isqrcode"
  48. :text="detail.qrcodecontent"
  49. css="width: 64px; height: 64px;position: absolute;bottom: 22px;right:10px;z-index: 2;"
  50. />
  51. </l-painter>
  52. </view>
  53. </view>
  54. <view class="custom">
  55. <view class="models">
  56. <view class="group">
  57. <view class="title">海报样式</view>
  58. <view class="options">
  59. <view
  60. class="option"
  61. v-for="option in ops.painter"
  62. hover-class="navigator-hover"
  63. :key="option.mode"
  64. @click="mode = option.mode"
  65. >
  66. <image v-if="option.imgUrl" class="image" :src="option.imgUrl" />
  67. <image
  68. class="current"
  69. v-if="option.mode == mode"
  70. src="https://yossys06593.obs.cn-east-3.myhuaweicloud.com:443/202404101712715614059B373541f3.png"
  71. />
  72. </view>
  73. </view>
  74. </view>
  75. <view class="group">
  76. <view class="title">文字色彩</view>
  77. <view class="options">
  78. <view
  79. class="option"
  80. v-for="option in ops.text"
  81. hover-class="navigator-hover"
  82. :key="option.name"
  83. @click="textColor = option.color"
  84. >
  85. <view class="text" :style="option.style">
  86. {{ option.name }}
  87. </view>
  88. <image
  89. class="current"
  90. v-if="option.color == textColor"
  91. src="https://yossys06593.obs.cn-east-3.myhuaweicloud.com:443/202404101712715614059B373541f3.png"
  92. />
  93. </view>
  94. </view>
  95. </view>
  96. </view>
  97. <view class="text-box">
  98. <view class="title"> 海报文案 </view>
  99. <view class="input-box">
  100. <input
  101. class="input"
  102. maxlength="16"
  103. type="text"
  104. v-model="painterText"
  105. />
  106. <view class="icon-box" @click="painterText = ''">
  107. <icon v-if="painterText" class="icon" type="clear" size="3.733vw" />
  108. </view>
  109. </view>
  110. </view>
  111. <view
  112. class="but"
  113. @click="loading ? '' : saveTheImage()"
  114. hover-class="navigator-hover"
  115. >
  116. <u-loading-icon v-if="loading" color="#fff" />
  117. <text v-else> 保存 </text>
  118. </view>
  119. </view>
  120. <view class="tips">
  121. *自定义海报区域可以选择海报样式、文字色彩等,文案部分最多可输入16个字,若留空,则不显示自定义文案。
  122. </view>
  123. <view style="height: 20px" />
  124. </view>
  125. </template>
  126. <script>
  127. import lPainter from "../../uni_modules/lime-painter/components/l-painter/l-painter.vue";
  128. import lPainterView from "../../uni_modules/lime-painter/components/l-painter-view/l-painter-view.vue";
  129. import lPainterText from "../../uni_modules/lime-painter/components/l-painter-text/l-painter-text.vue";
  130. import lPainterImage from "../../uni_modules/lime-painter/components/l-painter-image/l-painter-image.vue";
  131. import lPainterQrcode from "../../uni_modules/lime-painter/components/l-painter-qrcode/l-painter-qrcode.vue";
  132. export default {
  133. components: {
  134. lPainter,
  135. lPainterView,
  136. lPainterText,
  137. lPainterImage,
  138. lPainterQrcode,
  139. },
  140. data() {
  141. return {
  142. detail: {},
  143. file: {},
  144. siteLogo: "",
  145. painterText: "自定义海报区域可以选择海报样式",
  146. mode: "model1",
  147. textColor: "#000000",
  148. ops: {
  149. painter: [
  150. {
  151. mode: "model1",
  152. imgUrl:
  153. "https://yossys06593.obs.cn-east-3.myhuaweicloud.com:443/202404101712714638752Bc18af43.png",
  154. },
  155. {
  156. mode: "model2",
  157. imgUrl:
  158. "https://yossys06593.obs.cn-east-3.myhuaweicloud.com:443/202404101712714646946B480ca84d.png",
  159. },
  160. {
  161. mode: "model3",
  162. imgUrl:
  163. "https://yossys06593.obs.cn-east-3.myhuaweicloud.com:443/202404101712714656283B28c9d1df.png",
  164. },
  165. {
  166. mode: "default",
  167. },
  168. ],
  169. text: [
  170. {
  171. name: "灰色",
  172. color: "#999999",
  173. style:
  174. "color: #999999; background: #FFFFFF;border: 1px solid #DDDDDD;",
  175. },
  176. {
  177. name: "黑色",
  178. color: "#000000",
  179. style:
  180. "color: #000000; background: #FFFFFF; border: 1px solid #DDDDDD;",
  181. },
  182. {
  183. name: "白色",
  184. color: "#FFFFFF",
  185. style: "color: #FFFFFF;background: #CCCCCC;",
  186. },
  187. ],
  188. },
  189. loading: false,
  190. };
  191. },
  192. onLoad() {
  193. try {
  194. this.detail = this.$Http.data.detail;
  195. this.file = this.$Http.data.file;
  196. delete this.$Http.data;
  197. } catch (error) {}
  198. try {
  199. this.siteLogo = uni.getStorageSync("site").attinfos[0].url || "";
  200. } catch (error) {}
  201. },
  202. beforeDestroy() {
  203. this.deteleFiles();
  204. },
  205. methods: {
  206. saveTheImage() {
  207. let that = this;
  208. this.loading = true;
  209. this.$refs.painter.canvasToTempFilePathSync({
  210. fileType: "jpg",
  211. // 如果返回的是base64是无法使用 saveImageToPhotosAlbum,需要设置 pathType为url
  212. pathType: "url",
  213. quality: 1,
  214. success: (res) => {
  215. // 非H5 保存到相册
  216. // H5 提示用户长按图另存
  217. uni.saveImageToPhotosAlbum({
  218. filePath: res.tempFilePath,
  219. success: function (e) {
  220. uni.showModal({
  221. title: "提示",
  222. content: "图片已保存到系统相册",
  223. showCancel: false,
  224. });
  225. that.loading = false;
  226. that.$Http
  227. .basic({
  228. id: 20240319142702,
  229. content: {
  230. sat_sharematerialid: that.detail.sat_sharematerialid,
  231. type: 1,
  232. },
  233. })
  234. .then((res) => {
  235. console.log(type, "记录", res);
  236. });
  237. },
  238. fail: ({ errMsg }) => {
  239. if (errMsg == "saveImageToPhotosAlbum:fail auth deny") {
  240. uni.showModal({
  241. title: "提示",
  242. content: "请授权添加到相册权限后再试!",
  243. showCancel: false,
  244. complete: (complete) => {
  245. uni.openSetting({
  246. success: (res) => {
  247. that.loading = false;
  248. if (res.authSetting["scope.writePhotosAlbum"]) {
  249. this.saveTheImage();
  250. } else {
  251. uni.showModal({
  252. title: "提示",
  253. content: "未获取授权!已取消保存",
  254. showCancel: false,
  255. });
  256. }
  257. },
  258. });
  259. },
  260. });
  261. } else {
  262. that.loading = false;
  263. uni.showModal({
  264. title: "提示",
  265. content: "已取消保存",
  266. showCancel: false,
  267. });
  268. }
  269. },
  270. });
  271. },
  272. });
  273. },
  274. handleFileLink(attachmentids, ownertable = "temporary", ownerid = 1, data) {
  275. this.deteleFiles();
  276. this.$Http
  277. .basic({
  278. classname: "system.attachment.Attachment",
  279. method: "createFileLink",
  280. content: {
  281. ownertable,
  282. ownerid,
  283. usetype: "painter",
  284. attachmentids,
  285. },
  286. })
  287. .then((res) => {
  288. console.log("绑定附件", res);
  289. if (this.cutoff(res.msg)) return;
  290. this.file = res.data[0];
  291. });
  292. },
  293. //删除附件
  294. deteleFiles() {
  295. if (this.file.ownertable == "temporary")
  296. this.$Http
  297. .basic({
  298. classname: "system.attachment.Attachment",
  299. method: "deleteFileLink",
  300. content: {
  301. linksids: [this.file.linksid],
  302. },
  303. })
  304. .then((res) => {
  305. console.log("处理删除附件", res);
  306. if (this.cutoff(res.msg)) return;
  307. });
  308. },
  309. },
  310. };
  311. </script>
  312. <style lang="scss">
  313. .head {
  314. display: flex;
  315. align-items: center;
  316. justify-content: space-between;
  317. padding: 10px;
  318. .left {
  319. line-height: 20px;
  320. font-family: Source Han Sans SC, Source Han Sans SC;
  321. font-size: 14px;
  322. color: #333333;
  323. .text {
  324. color: #666666;
  325. }
  326. }
  327. .right {
  328. color: #c30d23;
  329. font-size: 12px;
  330. }
  331. }
  332. .custom {
  333. width: 355px;
  334. background: #ffffff;
  335. border-radius: 8px;
  336. padding: 10px;
  337. box-sizing: border-box;
  338. margin: 10px auto;
  339. .models {
  340. display: flex;
  341. justify-content: space-between;
  342. .group {
  343. .title {
  344. line-height: 20px;
  345. font-family: Source Han Sans SC, Source Han Sans SC;
  346. font-size: 14px;
  347. color: #333333;
  348. margin-bottom: 10px;
  349. }
  350. .options {
  351. display: flex;
  352. .option {
  353. position: relative;
  354. width: 40px;
  355. height: 40px;
  356. background: #cccccc;
  357. border-radius: 5px;
  358. margin-right: 5px;
  359. overflow: hidden;
  360. box-sizing: border-box;
  361. .image,
  362. .text {
  363. display: flex;
  364. align-items: center;
  365. justify-content: center;
  366. width: 100%;
  367. height: 100%;
  368. font-family: Source Han Sans SC, Source Han Sans SC;
  369. font-size: 12px;
  370. box-sizing: border-box;
  371. border-radius: 5px;
  372. }
  373. .current {
  374. position: absolute;
  375. height: 14px;
  376. width: 14px;
  377. top: 0;
  378. right: 0;
  379. }
  380. }
  381. .option:last-child {
  382. margin-right: 0;
  383. }
  384. }
  385. }
  386. }
  387. .text-box {
  388. margin-top: 20px;
  389. .title {
  390. line-height: 20px;
  391. font-family: Source Han Sans SC, Source Han Sans SC;
  392. font-size: 14px;
  393. color: #333333;
  394. }
  395. .input-box {
  396. display: flex;
  397. align-items: center;
  398. width: 335px;
  399. height: 50px;
  400. background: #ffffff;
  401. border-radius: 8px;
  402. border: 1px solid #cccccc;
  403. margin-top: 10px;
  404. padding: 10px;
  405. box-sizing: border-box;
  406. .input {
  407. flex: 1;
  408. }
  409. }
  410. .icon-box {
  411. display: flex;
  412. width: 30px;
  413. height: 30px;
  414. justify-content: center;
  415. align-items: center;
  416. }
  417. }
  418. .but {
  419. display: flex;
  420. align-items: center;
  421. justify-content: center;
  422. width: 333px;
  423. height: 45px;
  424. background: #c30d23;
  425. border-radius: 5px;
  426. margin-top: 20px;
  427. font-family: PingFang SC, PingFang SC;
  428. font-weight: bold;
  429. font-size: 16px;
  430. color: #ffffff;
  431. }
  432. }
  433. .tips {
  434. width: 355px;
  435. height: 34px;
  436. font-family: Source Han Sans SC, Source Han Sans SC;
  437. font-size: 12px;
  438. color: #666666;
  439. margin: 10px auto;
  440. }
  441. .painter-box {
  442. display: flex;
  443. justify-content: center;
  444. }
  445. </style>