editTable.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. <template>
  2. <hc-sys id="app-sys" class="h-full hc-ledger-table-form" navBarUi="white">
  3. <template #navBar>
  4. <hc-nav-back-bar :title="pageNode.title + '填报'">
  5. <picker :range="pageData" :value="pageIndex" @change="bindPageChange" v-if="currentPage > 0">
  6. <view class="hc-page-bar">
  7. <text class="i-ri-arrow-down-s-line icon"/>
  8. <text class="text">第{{currentPage}}页</text>
  9. </view>
  10. </picker>
  11. </hc-nav-back-bar>
  12. </template>
  13. <view id="title-bar" class="title-bar z-24">
  14. <button type="primary" class="title-bar-btn" @click="editTypeClick">切换表单</button>
  15. <button type="primary" class="title-bar-btn" @click="linkTabClick">+ 关联工序</button>
  16. <button type="primary" class="title-bar-btn" @click="delCurrentPage" v-if="currentPage > 1">删除当前页</button>
  17. </view>
  18. <template v-if="webviewShow">
  19. <web-view :update-title="false" :webview-styles="webViewStyle" :style="webViewStyle" :src="webSrc" name="exceliframe" @message="handleMessage"/>
  20. </template>
  21. <view id="action-bar" class="action-bar">
  22. <view class="text-bar">
  23. <view class="left" @click="copyTableFormClick">复制当前表格及内容</view>
  24. <view class="right" @click="copyTimeLogModal">复制任意时间表格及内容</view>
  25. </view>
  26. <uni-row :gutter="20">
  27. <uni-col :span="6">
  28. <button class="cu-btn round c1" @click="addFormClick">新 增</button>
  29. </uni-col>
  30. <uni-col :span="6">
  31. <button class="cu-btn round c2" @click="previewTap">预 览</button>
  32. </uni-col>
  33. <uni-col :span="6">
  34. <button class="cu-btn round c3" @click="reportModalClick">上 报</button>
  35. </uni-col>
  36. <uni-col :span="6">
  37. <button class="cu-btn round c4" @click="formSaveClick">保 存</button>
  38. </uni-col>
  39. </uni-row>
  40. </view>
  41. </hc-sys>
  42. </template>
  43. <script setup>
  44. import {ref, getCurrentInstance} from "vue";
  45. import {onLoad, onReady, onShow, onUnload} from '@dcloudio/uni-app'
  46. import {errorToast, toPdfPreview, querySelect} from "@/utils/tools";
  47. import {getObjValue, isNullES} from "js-fast-way";
  48. import {getStorage} from "@/utils/storage";
  49. import mainApi from '~api/ledger/index';
  50. import {getFormApiUrl} from '@/config/envApi';
  51. const instance = getCurrentInstance().proxy
  52. let wv; //计划创建的webview
  53. //初始变量
  54. const pageNode = ref({});
  55. const webViewStyle = ref({})
  56. const webviewShow = ref(true)
  57. const tooltipRef = ref(null)
  58. onLoad((option) => {
  59. // #ifdef H5
  60. window.addEventListener('message', handleMessage);
  61. // #endif
  62. const user = encodeURIComponent(JSON.stringify(getStorage('login_user_info')))
  63. if (option.node) {
  64. uni.showLoading({title: '加载中...', mask: true});
  65. const res = JSON.parse(decodeURIComponent(option.node));
  66. uni.setNavigationBarTitle({title: res.title + '填报'})
  67. pageNode.value = res
  68. webSrc.value = `${htmlsrc}&user=${user}&node=${option.node}`
  69. checkTheLogTaskStatus()
  70. } else {
  71. errorToast('参数错误');
  72. setTimeout(() => {
  73. toBack()
  74. },1500)
  75. }
  76. })
  77. onShow(() => {
  78. webviewShow.value = true
  79. })
  80. //表格地址
  81. const webSrc = ref('');
  82. const envUrl = getFormApiUrl()
  83. const htmlsrc = `${envUrl}/#/app/table-form?date=${new Date().getTime()}&source=app&type=log-fill`
  84. //渲染完成
  85. onReady(() => {
  86. setWebViewStyle()
  87. })
  88. //获取状态
  89. const taskStatus = ref(1)
  90. const checkTheLogTaskStatus = async () => {
  91. const {projectId, contractId, pkeyId, date} = pageNode.value
  92. const { error, code, data } = await mainApi.checkTheLogTaskStatus({
  93. projectId: projectId,
  94. contractId: contractId,
  95. nodePrimaryKeyId: pkeyId,
  96. recordTime: date,
  97. })
  98. //处理数据
  99. const res = isNullES(data) ? '' : data || ''
  100. if (!error && code === 200 && res) {
  101. //1和2的时候所有按钮皆可操作,废除 除外
  102. //3和4时, 除了预览和废除 都不行
  103. taskStatus.value = data
  104. } else {
  105. taskStatus.value = 1
  106. }
  107. }
  108. const setWebViewStyle = async () => {
  109. // #ifdef APP-PLUS
  110. await initWebview()
  111. // #endif
  112. const {height: appHeight} = await querySelect(instance, 'app-sys')
  113. const {height: navHeight} = await querySelect(instance,'hc-nav-bar')
  114. const {height: titleHeight} = await querySelect(instance,'title-bar')
  115. webViewStyle.value.top = (navHeight + titleHeight) + 'px'
  116. //底部
  117. const {height: actionHeight} = await querySelect(instance,'action-bar')
  118. webViewStyle.value.height = (appHeight - navHeight - titleHeight - actionHeight - 1) + 'px'
  119. }
  120. //初始化webview
  121. const initWebview = async () => {
  122. return new Promise((resolve) => {
  123. let currentWebview = instance.$scope.$getAppWebview()
  124. //如果是页面初始化调用时,需要延时一下
  125. setTimeout(() => {
  126. wv = currentWebview.children()[0]
  127. wv.setStyle({scalable:true})
  128. // #ifdef APP-PLUS
  129. //ios 禁用缓存,测试生效!!
  130. let cache1 = plus.ios.newObject('NSURLCache');
  131. let cache = plus.ios.invoke(cache1, 'sharedURLCache');
  132. plus.ios.invoke(cache, 'removeAllCachedResponses');
  133. plus.ios.invoke(cache, 'setDiskCapacity:', 0);
  134. plus.ios.invoke(cache, 'setMemoryCapacity:', 0);
  135. //安卓端缓存清理。
  136. plus.cache.clear();
  137. // #endif
  138. resolve(true)
  139. }, 1000);
  140. })
  141. }
  142. //接收webview消息
  143. const handleMessage = (event) => {
  144. let msg = {};
  145. // #ifdef H5
  146. if (event.data && event.data.data && event.data.data.arg) {
  147. msg = event.data.data.arg
  148. }
  149. // #endif
  150. // #ifdef APP-PLUS
  151. msg = event.detail.data[0]
  152. // #endif
  153. if (msg.source === 'web') {
  154. console.log('收到web消息', msg)
  155. setMsgData(msg)
  156. }
  157. }
  158. //页数
  159. const pageData = ref([])
  160. const pageIndex = ref(0)
  161. // 处理接收到的消息
  162. const isFormRender = ref(false)
  163. const setMsgData = ({type, data}) => {
  164. //表格数量
  165. if (type === 'formRender') {
  166. uni.hideLoading();
  167. isFormRender.value = true
  168. }
  169. //表格数量
  170. if (type === 'formLength') {
  171. let pageArr = [];
  172. const index = Number(data)
  173. for (let i = 0; i < index; i++) {
  174. pageArr.push(`第${i + 1}页`)
  175. }
  176. pageData.value = pageArr
  177. }
  178. //当前表格
  179. if (type === 'formIndex') {
  180. const {id, page} = getObjValue(data)
  181. console.log('page', page)
  182. itemFormId.value = id //当前表格id
  183. currentPage.value = page //当前页码
  184. }
  185. //pdf预览
  186. if (type === 'formPdfUrl') {
  187. uni.hideLoading();
  188. previewPdf(data)
  189. }
  190. //保存结果
  191. if (type === 'saveRes') {
  192. uni.hideLoading();
  193. saveResData(data)
  194. }
  195. //消息提示
  196. if (type === 'msg') {
  197. uni.hideLoading();
  198. const { title, icon } = getObjValue(data)
  199. uni.showToast({
  200. title: title,
  201. duration: 2000,
  202. icon: icon,
  203. mask: true
  204. });
  205. }
  206. }
  207. //页码
  208. const currentPage = ref(0)
  209. const itemFormId = ref('')
  210. //切换页码
  211. const bindPageChange = ({detail}) => {
  212. const index = detail.value + 1
  213. if (index !== currentPage) {
  214. postMsg({
  215. type: 'pageTap',
  216. data: detail.value,
  217. fun: `pageTap('${detail.value}')`
  218. })
  219. }
  220. }
  221. const toBack = () => {
  222. webviewShow.value = false
  223. uni.navigateBack()
  224. }
  225. //切换显示模式
  226. const editType = ref('form')
  227. const editTypeClick = () => {
  228. if (isFormRender.value === false) {
  229. errorToast('表单未渲染完成,请稍后再试');
  230. return
  231. }
  232. const type = editType.value === 'form' ? 'table' : 'form'
  233. postMsg({
  234. type: 'editTypeClick',
  235. data: type,
  236. fun: `editTypeClick('${type}')`
  237. })
  238. editType.value = type
  239. }
  240. //关联工序
  241. const linkTabClick = () => {
  242. if (isFormRender.value === false) {
  243. errorToast('表单未渲染完成,请稍后再试');
  244. return
  245. }
  246. uni.navigateTo({
  247. url: '/pages/ledger/linkTab?id=' + itemFormId.value,
  248. events: {
  249. finish: (data) => {
  250. linkTabFinish(data)
  251. }
  252. }
  253. });
  254. }
  255. //通知更新关联工序数据
  256. const linkTabFinish = (data) => {
  257. const ids = data.length > 0 ? JSON.stringify(data) : ''
  258. postMsg({
  259. type: 'linkIds',
  260. data: ids,
  261. fun: `linkIdsTap('${ids}')`
  262. })
  263. }
  264. //新增表格
  265. const addFormClick = () => {
  266. if (isFormRender.value === false) {
  267. errorToast('表单未渲染完成,请稍后再试');
  268. return
  269. }
  270. postMsg({
  271. type: 'addForm',
  272. fun: `addFormTap()`
  273. })
  274. }
  275. //复制当前表格及内容
  276. const copyTableFormClick = () => {
  277. if (!isFormRender.value || taskStatus.value === 3 || taskStatus.value === 4) {
  278. errorToast('当前状态不可操作');
  279. return
  280. }
  281. postMsg({
  282. type: 'copyFormData',
  283. fun: `copyFormData()`
  284. })
  285. }
  286. //复制任意时间
  287. const copyTimeLogModal = () => {
  288. if (!isFormRender.value || taskStatus.value === 3 || taskStatus.value === 4) {
  289. errorToast('当前状态不可操作');
  290. return
  291. }
  292. uni.navigateTo({
  293. url: '/pages/ledger/copyTime?node=' + encodeURIComponent(JSON.stringify(pageNode.value)),
  294. events: {
  295. finish: () => {
  296. flushedPage()
  297. }
  298. }
  299. })
  300. }
  301. //删除当前页
  302. const delCurrentPage = () => {
  303. if (isFormRender.value === false) {
  304. errorToast('表单未渲染完成,请稍后再试');
  305. return
  306. }
  307. postMsg({
  308. type: 'delForm',
  309. fun: `delFormTap()`
  310. })
  311. }
  312. //预览表单PDF
  313. const previewTap = () => {
  314. if (!isFormRender.value || taskStatus.value === 1) {
  315. errorToast('当前状态不可操作');
  316. return
  317. }
  318. uni.showLoading({title: '获取数据中...', mask: true});
  319. postMsg({
  320. type: 'getPdfUrl',
  321. fun: `getPdfUrl()`
  322. })
  323. }
  324. //预览表单
  325. const previewPdf = (data) => {
  326. uni.hideLoading();
  327. if (!data) {
  328. errorToast('暂无PDF,无法预览');
  329. return
  330. }
  331. //预览文件
  332. toPdfPreview(data)
  333. }
  334. //保存
  335. const formSaveClick = () => {
  336. if (!isFormRender.value || taskStatus.value === 3 || taskStatus.value === 4) {
  337. errorToast('当前状态不可操作');
  338. return
  339. }
  340. uni.showLoading({title: '保存中...', mask: true})
  341. postMsg({
  342. type: 'formSave',
  343. fun: `formSave()`
  344. })
  345. }
  346. //保存结果
  347. const saveResData = (data) => {
  348. if (data === 'success') {
  349. uni.showLoading({title: '获取预览中...', mask: true})
  350. //flushedPage()
  351. }
  352. }
  353. //上报
  354. const reportModalClick = () => {
  355. const status = taskStatus.value
  356. if (!isFormRender.value || status === 1 || status === 3 || status === 4) {
  357. errorToast('当前状态不可操作');
  358. return
  359. }
  360. const {projectId, contractId, pkeyId, date, taskName} = pageNode.value
  361. //路由跳转
  362. uni.navigateTo({
  363. url: '/pages/report/report',
  364. events:{
  365. finish: () => {
  366. flushedPage()
  367. }
  368. },
  369. success:(res) => {
  370. res.eventChannel.emit('reportProps', {
  371. type: "log",
  372. typeData: pkeyId,
  373. projectId: projectId,
  374. contractId: contractId,
  375. taskName: taskName,
  376. url: 'contractLog/startTaskTheLog',
  377. addition: {
  378. nodePrimaryKeyId: pkeyId,
  379. recordTime: date,
  380. },
  381. })
  382. }
  383. });
  384. }
  385. //发送消息
  386. const postMsg = ({type, data, fun}) => {
  387. // #ifdef H5
  388. window.frames["exceliframe"].postMessage({
  389. type: type,
  390. source: 'app',
  391. data: data ?? {}
  392. }, envUrl);
  393. // #endif
  394. // #ifdef APP-PLUS
  395. if (fun) wv.evalJS(fun)
  396. // #endif
  397. }
  398. //刷新页面
  399. const flushedPage = () => {
  400. webviewShow.value = false
  401. checkTheLogTaskStatus()
  402. setTimeout(() => {
  403. webviewShow.value = true
  404. }, 500);
  405. }
  406. onUnload(()=>{
  407. // #ifdef H5
  408. window.removeEventListener('message', handleMessage);
  409. // #endif
  410. })
  411. </script>
  412. <style lang="scss" scoped>
  413. page {
  414. height: 100%;
  415. background: #FAFBFE;
  416. }
  417. </style>
  418. <style lang="scss">
  419. @import "@/style/ledger/edit-table.scss";
  420. </style>