result.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. <template>
  2. <div class="resout-container AI-Design-container">
  3. <header-online pagetitle="生成结果"></header-online>
  4. <!-- <div class="header">
  5. <van-nav-bar title="生成结果" left-arrow @click-left="returnPage" @click-right="toHome">
  6. <template #right>
  7. <van-icon name="wap-home-o" color="#333" size="26" />
  8. </template>
  9. </van-nav-bar>
  10. </div> -->
  11. <div class="container">
  12. <!-- 房屋效果图 -->
  13. <div class="image-container">
  14. <div v-if="imageUrl" class="comparisonWrapper">
  15. <div class="imgbox-t">
  16. <div>
  17. <p class="tit">原图</p>
  18. </div>
  19. <div>
  20. <p class="tit">AI效果图</p>
  21. </div>
  22. </div>
  23. <div class="imgbox-b">
  24. <div class="image-wrapper" @click="imgClick(UserFilePathUrl)">
  25. <img :src="UserFilePathUrl" alt="房屋效果图" class="house-image" />
  26. <div></div>
  27. </div>
  28. <div class="image-wrapper" @click="imgClick(imageUrl)">
  29. <img :src="imageUrlSmall" alt="房屋效果图" class="house-image" />
  30. <div></div>
  31. </div>
  32. </div>
  33. </div>
  34. <div v-else class="loading-state">
  35. <img v-if="StateCode != 3 && StateCode != 4" src="@/assets/AIDesign/loding.gif" style="width: 100px;">
  36. <p class="loading-text">{{ type || StateCode ? (StateCode == 3 ? '生成失败' : (StateCode == 4 ?
  37. '生成失败,\n' + StateInfo :
  38. '正在为您加速生成中,先喝杯茶吧~\n退出本页不影响生成')) : '加载中...' }}</p>
  39. </div>
  40. </div>
  41. <!-- 保存按钮 -->
  42. <!-- <button class="save-button" :disabled="!imageUrl" :class="{ 'save-button-disabled': !imageUrl }"
  43. @click="saveImageToAlbum">保存图片</button> -->
  44. <!-- 功能按钮组 -->
  45. <div class="button-group">
  46. <!--<button class="action-button" :disabled="!imageUrl" :class="{ 'save-button-disabled': !imageUrl }"-->
  47. <button class="action-button" :disabled="regenerateDisable"
  48. :class="regenerateDisable == true ? 'save-button-disabled' : ''" @click="regenerate">
  49. <van-icon class="icon" name="replay" />
  50. <span class="text">重新生成</span>
  51. </button>
  52. <button class="action-button" @click="viewHistory">
  53. <van-icon class="icon" name="clock-o" />
  54. <span class="text">历史生图</span>
  55. <span v-if="!readState" class="badge-dot"></span>
  56. </button>
  57. <!-- 服务商随身邦和部分经销商展示转人工 -->
  58. <button class="action-button" @click="manualDesign" v-if="showArtificial" :disabled="projectDisableFlag"
  59. :class="projectDisableFlag == true ? 'save-button-disabled' : ''">
  60. <van-icon class="icon" name="user-o" />
  61. <span class="text">转人工设计(原别墅之星小程序)</span>
  62. </button>
  63. </div>
  64. </div>
  65. </div>
  66. </template>
  67. <script lang="ts">
  68. import { ImagePreview, Dialog } from 'vant';
  69. import { Component, Vue } from "vue-property-decorator";
  70. import { GetEntity, GetReadState, UpdateReadState, insideGetEntity, insideGetReadState, insideUpdateReadState, GetProjectlist, GetDictList } from "@/api/indexAI";
  71. import { getWecomType ,toLBHome } from '@/utils/index';
  72. import axios from "axios";
  73. declare let wx: any;
  74. @Component
  75. export default class extends Vue {
  76. private readState = true;
  77. // 数据属性
  78. private imageUrl = ''; // 替换为实际图片路径
  79. private imageUrlSmall = '';
  80. private UserFilePathUrl = '';//用户原图
  81. private pollingTimer: number | null = null; // 轮询定时器引用
  82. private timer = null;
  83. private StateCode = null;
  84. private projectId = null;
  85. private regenerateDisable = true;
  86. private StateInfo = '';
  87. private type = '';
  88. private wallType = '';
  89. // 处理内外墙api
  90. private GetEntityToApi = {
  91. outside: GetEntity,
  92. inside: insideGetEntity
  93. };
  94. private GetReadStateToApi = {
  95. outside: GetReadState,
  96. inside: insideGetReadState
  97. };
  98. private UpdateReadStateToApi = {
  99. outside: UpdateReadState,
  100. inside: insideUpdateReadState
  101. };
  102. private designPageApi = {
  103. outside: '/AIDesign/design',
  104. inside: '/AIDesign/insideDesign'
  105. };
  106. private designTimer = {
  107. outside: 50000,
  108. inside: 20000
  109. };
  110. private showArtificial = false;
  111. private agentFrom = window.localStorage.getItem('agentFromAI');
  112. private outsideDesignCount = 0;//项目下设计已用数量-接口获取
  113. private isNeedProjectFlag = true;//是否需要项目-接口获取
  114. private projectDisableFlag = true;//转人工不可点击
  115. private serviceCodeArray = [];
  116. created() {
  117. this.getWxconfig();
  118. // this.getServiceCode();
  119. }
  120. activated() {
  121. this.initialize();
  122. this.wallType = this.$route.query.wallType || 'outside';
  123. const userInfo: any = JSON.parse(window.localStorage.getItem("userInfoV1")!);
  124. const customerCode = userInfo && userInfo.sysUserExt ? userInfo.sysUserExt.customerCode : '';
  125. const salesLevel = userInfo && userInfo.sysUserExt ? userInfo.sysUserExt.salesLevel : '';
  126. // 外墙-服务商随身邦
  127. if (this.agentFrom === 'stoneLikePaint' && this.wallType === 'outside') {
  128. this.showArtificial = true;
  129. this.getIsNeedProjectFlag();//获取是否关联了项目
  130. }
  131. // 和部分经销商展示转人工
  132. // else if(customerCode && (salesLevel === 'customer_level' || salesLevel === 'reseller_level')){
  133. // this.showArtificial = true;
  134. // }
  135. // 从经销商随身邦进入的,显示转人工按钮,没有次数限制
  136. if (this.agentFrom === 'ssb' && this.wallType === 'outside') {
  137. this.showArtificial = true;
  138. this.projectDisableFlag = false;
  139. }
  140. this.type = window.localStorage.getItem('type');
  141. this.GetReadStateFn();
  142. this.GetEntityDataFirst()
  143. }
  144. // 离开页面时清除定时器
  145. deactivated() {
  146. // console.log('resule页面销毁1')
  147. window.localStorage.removeItem('type');
  148. clearInterval(this.pollingTimer);
  149. clearTimeout(this.timer);
  150. this.pollingTimer = null;
  151. this.timer = null;
  152. }
  153. initialize() {
  154. clearInterval(this.pollingTimer);
  155. clearTimeout(this.timer);
  156. this.readState = true;
  157. this.imageUrl = ''; // 替换为实际图片路径
  158. this.imageUrlSmall = '';
  159. this.UserFilePathUrl = '';//用户原图
  160. this.pollingTimer = null; // 轮询定时器引用
  161. this.timer = null;
  162. this.StateCode = null;
  163. this.projectId = null;
  164. this.regenerateDisable = true;
  165. this.StateInfo = '';
  166. this.type = '';
  167. this.wallType = '';
  168. this.outsideDesignCount = 0;
  169. this.isNeedProjectFlag = true;
  170. this.projectDisableFlag = true;
  171. this.showArtificial = false;
  172. }
  173. // 是否关联了项目
  174. getIsNeedProjectFlag() {
  175. let that = this;
  176. const formData = new FormData();
  177. // const userInfo: any = JSON.parse(window.localStorage.getItem("userInfoV1")!);
  178. // let roleIdArray = [];
  179. // if (userInfo.roles.length > 0) {
  180. // userInfo.roles.forEach(item => {
  181. // roleIdArray.push(item.roleId);
  182. // })
  183. // }
  184. // formData.append('roleIds', roleIdArray.join(','));
  185. // formData.append('WXuserid', userInfo.loginName);
  186. formData.append('baseType', 0);//0外墙--这里只用查询外墙
  187. const agentFrom = window.localStorage.getItem('agentFromAI');
  188. const wecomType = getWecomType(agentFrom);
  189. formData.append('wecomType', 5);
  190. GetDictList(formData).then(response => {
  191. if (response.StatusCode == 200) {
  192. if (that.serviceCodeArray.length == 0) {
  193. that.isNeedProjectFlag = false; //是否需要项目
  194. } else {
  195. that.isNeedProjectFlag = response.Data.isNeedProject;
  196. }
  197. if (that.isNeedProjectFlag) {
  198. that.updateCheckedProjectLastNum();
  199. } else {
  200. that.projectDisableFlag = false;//没有项目就可点击
  201. }
  202. }
  203. })
  204. }
  205. //获取选中关联项目已用数量
  206. private updateCheckedProjectLastNum() {
  207. let that = this;
  208. const formData = new FormData();
  209. // formData.append('ServiceCode', that.serviceCodeArray.join(','));
  210. formData.append('projectid', this.$route.query.projectid);
  211. GetProjectlist(formData).then(response => {
  212. if (response.StatusCode == 200 && response.Data && response.Data[0]) {
  213. that.outsideDesignCount = response.Data[0].DesignCount || 0;
  214. // 单一关联项目下设计了1~3套,转人工设计均置灰不可点。从第4套起等转人工设计均可点
  215. if (that.outsideDesignCount > 3) {
  216. that.projectDisableFlag = false;//有项目判断>3可点击
  217. }
  218. }
  219. });
  220. }
  221. private getServiceCode() {
  222. let that = this;
  223. const userInfo: any = JSON.parse(window.localStorage.getItem("userInfoV1")!);
  224. let serviceCodeArray = [];
  225. if (userInfo.loginTypeList.length > 0) {
  226. userInfo.loginTypeList.forEach(item => {
  227. if (item.shopType == 'stoneLikePaint') {
  228. item.shopList.forEach(childItem => {
  229. serviceCodeArray.push(childItem.shop_code);
  230. })
  231. }
  232. })
  233. }
  234. that.serviceCodeArray = serviceCodeArray;
  235. }
  236. GetReadStateFn() {
  237. const formData = new FormData();
  238. // const userInfo: any = JSON.parse(window.localStorage.getItem("userInfoV1")!);
  239. // formData.append('WXuserid', userInfo.loginName);
  240. this.GetReadStateToApi[this.wallType](formData).then(response => {
  241. if (response.StatusCode == 200) {
  242. this.readState = response.Data.readState;
  243. }
  244. });
  245. }
  246. UpdateReadStateFn() {
  247. const formData = new FormData();
  248. // const userInfo: any = JSON.parse(window.localStorage.getItem("userInfoV1")!);
  249. // formData.append('WXuserid', userInfo.loginName);
  250. this.UpdateReadStateToApi[this.wallType](formData).then(response => { });
  251. }
  252. returnPage() {
  253. this.$router.push({ path: '/AIDesign' });
  254. }
  255. toHome() {
  256. toLBHome()
  257. }
  258. imgClick(url) {
  259. ImagePreview([url]);
  260. }
  261. private startPolling(): void {
  262. // 立即执行一次检查
  263. this.GetEntityData();
  264. // 设置定时器每秒执行一次检查
  265. this.pollingTimer = window.setInterval(() => {
  266. if (!this.imageUrl) {
  267. if (this.StateCode == 3 || this.StateCode == 4) {
  268. clearInterval(this.pollingTimer);
  269. this.pollingTimer = null;
  270. } else {
  271. this.GetEntityData();
  272. }
  273. } else {
  274. // 当 imageUrl 有值时,清除定时器
  275. if (this.pollingTimer) {
  276. clearInterval(this.pollingTimer);
  277. this.pollingTimer = null;
  278. }
  279. }
  280. }, 3000);
  281. }
  282. //进入页面首次调用获取状态
  283. GetEntityDataFirst() {
  284. let that = this;
  285. const F_ID = this.$route.query.F_id || "";
  286. const formData = new FormData();
  287. formData.append('F_id', F_ID);
  288. this.GetEntityToApi[this.wallType](formData).then(response => {
  289. // console.log(response);
  290. if (response.StatusCode == 200) {
  291. if (response.Data == null) {
  292. that.regenerateDisable = true;
  293. if (that.timer) {
  294. clearTimeout(that.timer);
  295. that.timer = null;
  296. }
  297. that.timer = setTimeout(() => {
  298. that.startPolling();
  299. }, that.designTimer[that.wallType]);
  300. } else {
  301. this.StateCode = response.Data.StateCode;
  302. this.StateInfo = response.Data.Description;
  303. this.projectId = response.Data.ProjectID;
  304. if (response.Data.F_ResultFilePath || response.Data.F_ResultlargeFilePath) {
  305. const high_Definition_img = response.Data.F_ResultFilePath || response.Data.F_ResultlargeFilePath || response.Data.F_ResultSmallFilePath;
  306. that.imageUrl = response.Data.BaseUrl + high_Definition_img;
  307. that.imageUrlSmall = response.Data.BaseUrl + response.Data.F_ResultSmallFilePath;
  308. that.UserFilePathUrl = response.Data.BaseUrl + response.Data.F_UserFilePath;
  309. }
  310. if (response.Data.StateCode == 1) {
  311. let createTime = new Date(response.Data.CreateDate);
  312. let currentTime = new Date().getTime();
  313. if (currentTime - createTime > that.designTimer[that.wallType]) {
  314. that.startPolling();
  315. } else {
  316. if (that.timer) {
  317. clearTimeout(that.timer);
  318. that.timer = null;
  319. }
  320. that.timer = setTimeout(() => {
  321. that.startPolling();
  322. }, currentTime - createTime);
  323. }
  324. } else {
  325. if (response.Data.StateCode == 2 || response.Data.StateCode == 3 || response.Data.StateCode == 4) {
  326. that.regenerateDisable = false;
  327. } else {
  328. that.regenerateDisable = true;
  329. }
  330. }
  331. }
  332. } else {
  333. this.$toast.fail(response.Info);
  334. }
  335. })
  336. }
  337. GetEntityData() {
  338. let that = this;
  339. const F_ID = this.$route.query.F_id || "";
  340. const formData = new FormData();
  341. formData.append('F_id', F_ID);
  342. this.GetEntityToApi[this.wallType](formData).then(response => {
  343. // console.log(response);
  344. if (response.StatusCode == 200) {
  345. if (response.Data) {
  346. this.StateCode = response.Data.StateCode;
  347. this.StateInfo = response.Data.Description;
  348. if (response.Data.F_ResultFilePath || response.Data.F_ResultlargeFilePath) {
  349. const high_Definition_img = response.Data.F_ResultFilePath || response.Data.F_ResultlargeFilePath || response.Data.F_ResultlargeFilePath;
  350. that.imageUrl = response.Data.BaseUrl + high_Definition_img;
  351. that.imageUrlSmall = response.Data.BaseUrl + response.Data.F_ResultSmallFilePath;
  352. that.UserFilePathUrl = response.Data.BaseUrl + response.Data.F_UserFilePath;
  353. }
  354. if (response.Data.StateCode == 2 || response.Data.StateCode == 3 || response.Data.StateCode == 4) {
  355. that.regenerateDisable = false;
  356. } else {
  357. that.regenerateDisable = true;
  358. }
  359. } else {
  360. that.regenerateDisable = true;
  361. }
  362. } else {
  363. this.$toast.fail(response.Info);
  364. }
  365. })
  366. }
  367. // 获取微信API授权信息
  368. getWxconfig() {
  369. const jsApiList = ['getSetting', 'authorize', 'showModal', 'openSetting', 'downloadFile', 'saveImageToPhotosAlbum'];
  370. let url = window.location.href.split("#")[0];
  371. axios.get(`${process.env.VUE_APP_BASE_API}wx/ticket`, {
  372. params: {
  373. url: url,
  374. agent: 1
  375. }
  376. }).then(response => {
  377. if (response.status == 200) {
  378. let qiyeData = response.data.data;
  379. wx.agentConfig({
  380. debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  381. corpid: qiyeData.appId, // 必填,企业微信的corpid,必须与当前登录的企业一致
  382. agentid: qiyeData.agentId, // 必填,企业微信的应用id (e.g. 1000247)
  383. timestamp: qiyeData.timestamp, // 必填,生成签名的时间戳
  384. nonceStr: qiyeData.nonceStr, // 必填,生成签名的随机串
  385. signature: qiyeData.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
  386. jsApiList: [...jsApiList], //必填,传入需要使用的接口名称
  387. success: function (res) {
  388. console.log('获取签名成功');
  389. },
  390. fail: function (res) {
  391. console.log(res);
  392. if (res.errMsg.indexOf('function not exist') > -1) {
  393. alert('版本过低请升级');
  394. }
  395. },
  396. });
  397. }
  398. });
  399. }
  400. // 点击保存图片按钮
  401. saveImageToAlbum() {
  402. const that = this;
  403. wx.ready(function () {
  404. // 1. 检查用户是否授权保存图片到相册
  405. wx.getSetting({
  406. success: (res) => {
  407. // 2. 如果未授权,请求授权
  408. if (!res.authSetting['scope.writePhotosAlbum']) {
  409. wx.authorize({
  410. scope: 'scope.writePhotosAlbum',
  411. success: () => {
  412. // 授权成功,执行保存逻辑
  413. that.downloadAndSaveImage();
  414. },
  415. fail: () => {
  416. // 用户拒绝授权,引导手动开启
  417. wx.showModal({
  418. title: '授权提示',
  419. content: '需要你的授权才能保存图片到相册,请在设置中开启授权',
  420. confirmText: '去设置',
  421. success: (modalRes) => {
  422. if (modalRes.confirm) {
  423. // 打开设置页面
  424. wx.openSetting({
  425. success: (settingRes) => {
  426. if (settingRes.authSetting['scope.writePhotosAlbum']) {
  427. that.downloadAndSaveImage();
  428. } else {
  429. that.$toast.fail('未授权,无法保存图片');
  430. }
  431. }
  432. });
  433. }
  434. }
  435. });
  436. }
  437. });
  438. } else {
  439. // 已授权,直接执行保存逻辑
  440. that.downloadAndSaveImage();
  441. }
  442. },
  443. fail: (err) => {
  444. console.error('获取设置失败', err);
  445. that.$toast.fail('获取授权状态失败,请重试');
  446. }
  447. });
  448. });
  449. }
  450. // 下载图片并保存到相册
  451. downloadAndSaveImage() {
  452. const that = this;
  453. const imageUrl = this.imageUrl;
  454. wx.ready(function () {
  455. // 1. 下载OSS图片到本地临时路径
  456. wx.downloadFile({
  457. url: imageUrl,
  458. success: (downloadRes) => {
  459. // 检查下载是否成功(临时文件路径存在)
  460. if (downloadRes.statusCode === 200 && downloadRes.tempFilePath) {
  461. // 2. 保存图片到相册
  462. wx.saveImageToPhotosAlbum({
  463. filePath: downloadRes.tempFilePath,
  464. success: () => {
  465. // 提示用户
  466. that.$toast.success('图片已成功保存到相册');
  467. },
  468. fail: (saveErr) => {
  469. console.error('保存图片失败', saveErr);
  470. that.$toast.fail('保存失败,请重试');
  471. }
  472. });
  473. } else {
  474. console.error('图片下载失败', downloadRes);
  475. that.$toast.fail('图片下载失败,请检查URL');
  476. }
  477. },
  478. fail: (downloadErr) => {
  479. console.error('下载请求失败', downloadErr);
  480. that.$toast.fail('下载图片失败,请重试');
  481. }
  482. });
  483. });
  484. }
  485. // 方法
  486. private saveImage(): void {
  487. if (!this.imageUrl) {
  488. this.$toast.fail('图片尚未生成完成');
  489. return;
  490. }
  491. // // 创建一个临时的下载链接
  492. // const link = document.createElement('a');
  493. // link.href = this.imageUrl;
  494. // link.download = `ai-design-${new Date().getTime()}.png`;
  495. // link.style.display = 'none';
  496. // // 将链接添加到页面并触发点击事件
  497. // document.body.appendChild(link);
  498. // link.click();
  499. // // 清理DOM元素
  500. // document.body.removeChild(link);
  501. fetch(this.imageUrl).then(response => response.blob()).then(blob => {
  502. const blobUrl = URL.createObjectURL(blob);
  503. // 创建一个临时的下载链接
  504. const link = document.createElement('a');
  505. link.href = blobUrl;
  506. link.download = `ai-design-${new Date().getTime()}.png`;
  507. link.style.display = 'none';
  508. // 将链接添加到页面并触发点击事件
  509. document.body.appendChild(link);
  510. link.click();
  511. // 清理DOM元素
  512. document.body.removeChild(link);
  513. // 释放Blob URL
  514. URL.revokeObjectURL(blobUrl);
  515. // this.$toast.success('图片保存成功');
  516. }).catch(error => {
  517. console.error('图片下载失败:', error);
  518. this.$toast.fail('图片下载失败');
  519. });
  520. }
  521. private regenerate(): void {
  522. // console.log('重新生成');
  523. let that = this;
  524. // 实现重新生成逻辑
  525. const F_ID = this.$route.query.F_id || "";
  526. this.$router.push({
  527. path: this.designPageApi[this.wallType],
  528. query: {
  529. F_id: F_ID,
  530. projectId: that.projectId
  531. }
  532. });
  533. }
  534. private viewHistory(): void {
  535. this.UpdateReadStateFn();
  536. // console.log('查看历史生成');
  537. // 实现查看历史生成逻辑
  538. this.$router.push({ path: '/AIDesign/history', query: { wallType: this.wallType } });
  539. }
  540. private manualDesign(): void {
  541. let that = this;
  542. debugger
  543. // console.log('转人工设计');
  544. // 实现转人工设计逻辑
  545. that.$magnetlogadd.setLog('AI外墙设计-转人工设计', function () {
  546. that.toXiaoChengxu(`${process.env.VUE_APP_BASE_DISID6}`);
  547. })
  548. }
  549. //跳转微信小程序
  550. toXiaoChengxu(appid) {
  551. let url = window.location.href.split("#")[0];
  552. wx.ready(function () {
  553. wx.checkJsApi({
  554. jsApiList: ["agentConfig", "launchMiniprogram"], // 需要检测的JS接口列表
  555. success: function (res) {
  556. axios.get(`${process.env.VUE_APP_BASE_API}wx/ticket`, {
  557. params: {
  558. url: url,
  559. agent: 1
  560. }
  561. }).then(response => {
  562. if (response.status == 200) {
  563. let yingyongData = response.data.data;
  564. wx.agentConfig({
  565. corpid: yingyongData.appId, // 必填,企业微信的corpid,必须与当前登录的企业一致
  566. agentid: yingyongData.agentId, // 必填,企业微信的应用id (e.g. 1000247)
  567. timestamp: yingyongData.timestamp, // 必填,生成签名的时间戳
  568. nonceStr: yingyongData.nonceStr, // 必填,生成签名的随机串
  569. signature: yingyongData.signature, // 必填,签名,见附录-JS-SDK使用权限签名算法
  570. jsApiList: ["launchMiniprogram"], //必填,传入需要使用的接口名称
  571. success: function (res) {
  572. wx.invoke(
  573. "launchMiniprogram",
  574. {
  575. appid: appid, // 需跳转的小程序appid
  576. path: "" // 所需跳转的小程序内页面路径及参数。非必填
  577. },
  578. function (res) {
  579. if (res.err_msg == "launchMiniprogram:ok") {
  580. // 正常
  581. console.log("正常");
  582. } else {
  583. // 错误处理
  584. }
  585. }
  586. );
  587. },
  588. fail: function (res) {
  589. if (res.errMsg.indexOf("function not exist") > -1) {
  590. alert("版本过低请升级");
  591. }
  592. }
  593. });
  594. }
  595. });
  596. }
  597. });
  598. });
  599. }
  600. }
  601. </script>
  602. <style scoped lang="scss">
  603. .resout-container {
  604. background-color: #f8f9fa;
  605. min-height: 100vh;
  606. flex-direction: column;
  607. }
  608. .header {
  609. /*height: 50px;*/
  610. /*line-height: 50px;*/
  611. /*text-align: center;*/
  612. /*background: #fff;*/
  613. border-bottom: 1px solid #f8f8f8;
  614. .van-nav-bar__title {
  615. font-size: 20px;
  616. color: #333;
  617. }
  618. .van-icon {
  619. font-size: 20px;
  620. color: #333 !important;
  621. }
  622. }
  623. .container {
  624. padding: 0 20px;
  625. }
  626. .image-container {
  627. position: relative;
  628. width: 100%;
  629. border-radius: 10px;
  630. overflow: hidden;
  631. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  632. margin-top: 20px;
  633. .comparisonWrapper {
  634. display: flex;
  635. flex-direction: column;
  636. padding: 35px 6px;
  637. .imgbox-t {
  638. display: flex;
  639. justify-content: space-between;
  640. align-items: center;
  641. >div {
  642. .tit {
  643. width: fit-content;
  644. padding: 0 5px;
  645. height: 17px;
  646. line-height: 17px;
  647. border-radius: 32px;
  648. font-size: 10px;
  649. }
  650. }
  651. >div:first-child {
  652. width: 36%;
  653. .tit {
  654. background: rgba(204, 204, 204, 1);
  655. }
  656. }
  657. >div:last-child {
  658. width: 58%;
  659. .tit {
  660. color: #fff;
  661. background: rgba(244, 155, 125, 1);
  662. }
  663. }
  664. }
  665. .imgbox-b {
  666. display: flex;
  667. justify-content: space-between;
  668. align-items: center;
  669. >div:first-child {
  670. width: 36%;
  671. }
  672. >div:last-child {
  673. width: 58%;
  674. }
  675. .image-wrapper {
  676. position: relative;
  677. width: 100%;
  678. margin: 5px 0;
  679. display: flex;
  680. align-items: center;
  681. justify-content: flex-start;
  682. .house-image {
  683. border-radius: 10px;
  684. display: block;
  685. width: 100%;
  686. height: auto;
  687. }
  688. .house-image+div {
  689. position: absolute;
  690. top: 0;
  691. left: 0;
  692. width: 100%;
  693. height: 100%;
  694. background: transparent;
  695. z-index: 2;
  696. }
  697. }
  698. }
  699. }
  700. }
  701. .loading-state {
  702. position: relative;
  703. width: 100%;
  704. height: 300px;
  705. display: flex;
  706. flex-direction: column;
  707. align-items: center;
  708. justify-content: center;
  709. color: #666;
  710. text-align: center;
  711. // background-color: rgba(0, 0, 0, 0.7);
  712. background-image: url('../../assets/AIDesign/bg.png');
  713. background-size: 100% 100%;
  714. /* 添加半透明黑色背景 */
  715. // border-radius: 16px;
  716. /* 圆角边框 */
  717. }
  718. .loading-text {
  719. margin-top: 10px;
  720. font-size: 14px;
  721. color: white;
  722. white-space: pre-line
  723. /* 文字颜色改为白色以提高对比度 */
  724. }
  725. .address-info {
  726. position: absolute;
  727. bottom: 10px;
  728. left: 10px;
  729. right: 10px;
  730. background-color: rgba(0, 0, 0, 0.5);
  731. color: white;
  732. padding: 8px;
  733. border-radius: 8px;
  734. font-size: 14px;
  735. text-align: center;
  736. }
  737. .project-name {
  738. margin: 0;
  739. font-weight: bold;
  740. }
  741. .address {
  742. margin: 4px 0 0;
  743. font-size: 12px;
  744. }
  745. .save-button {
  746. width: 100%;
  747. padding: 16px;
  748. margin-top: 20px;
  749. background-color: #E96337;
  750. color: white;
  751. border: none;
  752. border-radius: 12px;
  753. font-size: 16px;
  754. font-weight: bold;
  755. cursor: pointer;
  756. transition: background-color 0.3s ease;
  757. }
  758. .save-button-disabled {
  759. background-color: #cccccc !important;
  760. cursor: not-allowed !important;
  761. color: white !important;
  762. }
  763. /* .save-button:hover {
  764. background-color: #e04a1d;
  765. } */
  766. .button-group {
  767. margin-top: 20px;
  768. }
  769. .action-button {
  770. width: 100%;
  771. padding: 14px;
  772. margin-bottom: 12px;
  773. background-color: white;
  774. border: 1px solid #e0e0e0;
  775. border-radius: 12px;
  776. font-size: 15px;
  777. color: #333;
  778. cursor: pointer;
  779. display: flex;
  780. align-items: center;
  781. justify-content: flex-start;
  782. transition: background-color 0.3s ease;
  783. }
  784. .action-button:hover {
  785. background-color: #f5f5f5;
  786. }
  787. .badge-dot {
  788. margin-left: 10px;
  789. width: 5px;
  790. height: 5px;
  791. background-color: #ff4d4f;
  792. border-radius: 50%;
  793. }
  794. .icon {
  795. margin-right: 10px;
  796. font-size: 18px;
  797. }
  798. .text {
  799. font-weight: 500;
  800. }
  801. .van-nav-bar__title {
  802. font-size: 20px;
  803. color: #333;
  804. }
  805. </style>