editTable.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  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">
  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?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. const type = editType.value === 'form' ? 'table' : 'form'
  197. postMsg({
  198. type: 'editTypeClick',
  199. data: type,
  200. fun: `editTypeClick('${type}')`
  201. })
  202. editType.value = type
  203. }
  204. //关联工序
  205. const linkTabClick = () => {
  206. uni.navigateTo({
  207. url: '/pages/ledger/linkTab?id=' + itemFormId.value,
  208. events: {
  209. finish: (data) => {
  210. linkTabFinish(data)
  211. }
  212. }
  213. });
  214. }
  215. //通知更新关联工序数据
  216. const linkTabFinish = (data) => {
  217. const ids = data.length > 0 ? JSON.stringify(data) : ''
  218. postMsg({
  219. type: 'linkIds',
  220. data: ids,
  221. fun: `linkIdsTap('${ids}')`
  222. })
  223. }
  224. //新增表格
  225. const addFormClick = () => {
  226. postMsg({
  227. type: 'addForm',
  228. fun: `addFormTap()`
  229. })
  230. }
  231. //复制当前表格及内容
  232. const copyTableFormClick = () => {
  233. if (!isFormRender.value || taskStatus.value === 3 || taskStatus.value === 4) {
  234. errorToast('当前状态不可操作');
  235. return
  236. }
  237. postMsg({
  238. type: 'copyFormData',
  239. fun: `copyFormData()`
  240. })
  241. }
  242. //复制任意时间
  243. const copyTimeLogModal = () => {
  244. if (!isFormRender.value || taskStatus.value === 3 || taskStatus.value === 4) {
  245. errorToast('当前状态不可操作');
  246. return
  247. }
  248. uni.navigateTo({
  249. url: '/pages/ledger/copyTime?node=' + encodeURIComponent(JSON.stringify(pageNode.value)),
  250. events: {
  251. finish: () => {
  252. flushedPage()
  253. }
  254. }
  255. })
  256. }
  257. //删除当前页
  258. const delCurrentPage = () => {
  259. postMsg({
  260. type: 'delForm',
  261. fun: `delFormTap()`
  262. })
  263. }
  264. //预览表单PDF
  265. const previewTap = () => {
  266. if (!isFormRender.value || taskStatus.value === 1) {
  267. errorToast('当前状态不可操作');
  268. return
  269. }
  270. uni.showLoading({title: '获取数据中...', mask: true});
  271. postMsg({
  272. type: 'getPdfUrl',
  273. fun: `getPdfUrl()`
  274. })
  275. }
  276. //预览表单
  277. const previewPdf = (data) => {
  278. uni.hideLoading();
  279. if (!data) {
  280. errorToast('暂无PDF,无法预览');
  281. return
  282. }
  283. //预览文件
  284. toPdfPreview(data)
  285. }
  286. //保存
  287. const formSaveClick = () => {
  288. if (!isFormRender.value || taskStatus.value === 3 || taskStatus.value === 4) {
  289. errorToast('当前状态不可操作');
  290. return
  291. }
  292. uni.showLoading({title: '保存中...', mask: true})
  293. postMsg({
  294. type: 'formSave',
  295. fun: `formSave()`
  296. })
  297. }
  298. //保存结果
  299. const saveResData = (data) => {
  300. if (data === 'success') {
  301. uni.showLoading({title: '获取预览中...', mask: true})
  302. //flushedPage()
  303. }
  304. }
  305. //上报
  306. const reportModalClick = () => {
  307. const status = taskStatus.value
  308. if (!isFormRender.value || status === 1 || status === 3 || status === 4) {
  309. errorToast('当前状态不可操作');
  310. return
  311. }
  312. const {projectId, contractId, pkeyId, date, taskName} = pageNode.value
  313. //路由跳转
  314. uni.navigateTo({
  315. url: '/pages/report/report',
  316. events:{
  317. finish: () => {
  318. flushedPage()
  319. }
  320. },
  321. success:(res) => {
  322. res.eventChannel.emit('reportProps', {
  323. type: "log",
  324. typeData: pkeyId,
  325. projectId: projectId,
  326. contractId: contractId,
  327. taskName: taskName,
  328. url: 'contractLog/startTaskTheLog',
  329. addition: {
  330. nodePrimaryKeyId: pkeyId,
  331. recordTime: date,
  332. },
  333. })
  334. }
  335. });
  336. }
  337. //发送消息
  338. const postMsg = ({type, data, fun}) => {
  339. // #ifdef H5
  340. window.frames["exceliframe"].postMessage({
  341. type: type,
  342. source: 'app',
  343. data: data ?? {}
  344. }, envUrl);
  345. // #endif
  346. // #ifdef APP-PLUS
  347. if (fun) wv.evalJS(fun)
  348. // #endif
  349. }
  350. //刷新页面
  351. const flushedPage = () => {
  352. webviewShow.value = false
  353. checkTheLogTaskStatus()
  354. setTimeout(() => {
  355. webviewShow.value = true
  356. }, 500);
  357. }
  358. onUnload(()=>{
  359. // #ifdef H5
  360. window.removeEventListener('message', handleMessage);
  361. // #endif
  362. })
  363. </script>
  364. <style lang="scss" scoped>
  365. page {
  366. height: 100%;
  367. background: #FAFBFE;
  368. }
  369. </style>
  370. <style lang="scss">
  371. @import "@/style/ledger/edit-table.scss";
  372. </style>