editTable.vue 12 KB

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