editTable.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  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 :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. resolve(true)
  129. }, 1000);
  130. })
  131. }
  132. //接收webview消息
  133. const handleMessage = (event) => {
  134. let msg = {};
  135. // #ifdef H5
  136. if (event.data && event.data.data && event.data.data.arg) {
  137. msg = event.data.data.arg
  138. }
  139. // #endif
  140. // #ifdef APP-PLUS
  141. msg = event.detail.data[0]
  142. // #endif
  143. if (msg.source === 'web') {
  144. console.log('收到web消息', msg)
  145. setMsgData(msg)
  146. }
  147. }
  148. //页数
  149. const pageData = ref([])
  150. const pageIndex = ref(0)
  151. // 处理接收到的消息
  152. const isFormRender = ref(false)
  153. const setMsgData = ({type, data}) => {
  154. //表格数量
  155. if (type === 'formRender') {
  156. uni.hideLoading();
  157. isFormRender.value = true
  158. }
  159. //表格数量
  160. if (type === 'formLength') {
  161. let pageArr = [];
  162. const index = Number(data)
  163. for (let i = 0; i < index; i++) {
  164. pageArr.push(`第${i + 1}页`)
  165. }
  166. pageData.value = pageArr
  167. }
  168. //当前表格
  169. if (type === 'formIndex') {
  170. const {id, page} = getObjValue(data)
  171. itemFormId.value = id //当前表格id
  172. currentPage.value = page //当前页码
  173. }
  174. //pdf预览
  175. if (type === 'formPdfUrl') {
  176. uni.hideLoading();
  177. previewPdf(data)
  178. }
  179. //保存结果
  180. if (type === 'saveRes') {
  181. uni.hideLoading();
  182. saveResData(data)
  183. }
  184. //消息提示
  185. if (type === 'msg') {
  186. uni.hideLoading();
  187. const { title, icon } = getObjValue(data)
  188. uni.showToast({
  189. title: title,
  190. duration: 2000,
  191. icon: icon,
  192. mask: true
  193. });
  194. }
  195. }
  196. //页码
  197. const currentPage = ref(0)
  198. const itemFormId = ref('')
  199. //切换页码
  200. const bindPageChange = ({detail}) => {
  201. const index = detail.value + 1
  202. if (index !== currentPage) {
  203. postMsg({
  204. type: 'pageTap',
  205. data: index -1,
  206. fun: `pageTap('${index - 1}')`
  207. })
  208. }
  209. }
  210. const toBack = () => {
  211. webviewShow.value = false
  212. uni.navigateBack()
  213. }
  214. //切换显示模式
  215. const editType = ref('form')
  216. const editTypeClick = () => {
  217. if (isFormRender.value === false) {
  218. errorToast('表单未渲染完成,请稍后再试');
  219. return
  220. }
  221. const type = editType.value === 'form' ? 'table' : 'form'
  222. postMsg({
  223. type: 'editTypeClick',
  224. data: type,
  225. fun: `editTypeClick('${type}')`
  226. })
  227. editType.value = type
  228. }
  229. //关联工序
  230. const linkTabClick = () => {
  231. if (isFormRender.value === false) {
  232. errorToast('表单未渲染完成,请稍后再试');
  233. return
  234. }
  235. uni.navigateTo({
  236. url: '/pages/ledger/linkTab?id=' + itemFormId.value,
  237. events: {
  238. finish: (data) => {
  239. linkTabFinish(data)
  240. }
  241. }
  242. });
  243. }
  244. //通知更新关联工序数据
  245. const linkTabFinish = (data) => {
  246. const ids = data.length > 0 ? JSON.stringify(data) : ''
  247. postMsg({
  248. type: 'linkIds',
  249. data: ids,
  250. fun: `linkIdsTap('${ids}')`
  251. })
  252. }
  253. //新增表格
  254. const addFormClick = () => {
  255. if (isFormRender.value === false) {
  256. errorToast('表单未渲染完成,请稍后再试');
  257. return
  258. }
  259. postMsg({
  260. type: 'addForm',
  261. fun: `addFormTap()`
  262. })
  263. }
  264. //复制当前表格及内容
  265. const copyTableFormClick = () => {
  266. if (!isFormRender.value || taskStatus.value === 3 || taskStatus.value === 4) {
  267. errorToast('当前状态不可操作');
  268. return
  269. }
  270. postMsg({
  271. type: 'copyFormData',
  272. fun: `copyFormData()`
  273. })
  274. }
  275. //复制任意时间
  276. const copyTimeLogModal = () => {
  277. if (!isFormRender.value || taskStatus.value === 3 || taskStatus.value === 4) {
  278. errorToast('当前状态不可操作');
  279. return
  280. }
  281. uni.navigateTo({
  282. url: '/pages/ledger/copyTime?node=' + encodeURIComponent(JSON.stringify(pageNode.value)),
  283. events: {
  284. finish: () => {
  285. flushedPage()
  286. }
  287. }
  288. })
  289. }
  290. //删除当前页
  291. const delCurrentPage = () => {
  292. if (isFormRender.value === false) {
  293. errorToast('表单未渲染完成,请稍后再试');
  294. return
  295. }
  296. postMsg({
  297. type: 'delForm',
  298. fun: `delFormTap()`
  299. })
  300. }
  301. //预览表单PDF
  302. const previewTap = () => {
  303. if (!isFormRender.value || taskStatus.value === 1) {
  304. errorToast('当前状态不可操作');
  305. return
  306. }
  307. uni.showLoading({title: '获取数据中...', mask: true});
  308. postMsg({
  309. type: 'getPdfUrl',
  310. fun: `getPdfUrl()`
  311. })
  312. }
  313. //预览表单
  314. const previewPdf = (data) => {
  315. uni.hideLoading();
  316. if (!data) {
  317. errorToast('暂无PDF,无法预览');
  318. return
  319. }
  320. //预览文件
  321. toPdfPreview(data)
  322. }
  323. //保存
  324. const formSaveClick = () => {
  325. if (!isFormRender.value || taskStatus.value === 3 || taskStatus.value === 4) {
  326. errorToast('当前状态不可操作');
  327. return
  328. }
  329. uni.showLoading({title: '保存中...', mask: true})
  330. postMsg({
  331. type: 'formSave',
  332. fun: `formSave()`
  333. })
  334. }
  335. //保存结果
  336. const saveResData = (data) => {
  337. if (data === 'success') {
  338. uni.showLoading({title: '获取预览中...', mask: true})
  339. //flushedPage()
  340. }
  341. }
  342. //上报
  343. const reportModalClick = () => {
  344. const status = taskStatus.value
  345. if (!isFormRender.value || status === 1 || status === 3 || status === 4) {
  346. errorToast('当前状态不可操作');
  347. return
  348. }
  349. const {projectId, contractId, pkeyId, date, taskName} = pageNode.value
  350. //路由跳转
  351. uni.navigateTo({
  352. url: '/pages/report/report',
  353. events:{
  354. finish: () => {
  355. flushedPage()
  356. }
  357. },
  358. success:(res) => {
  359. res.eventChannel.emit('reportProps', {
  360. type: "log",
  361. typeData: pkeyId,
  362. projectId: projectId,
  363. contractId: contractId,
  364. taskName: taskName,
  365. url: 'contractLog/startTaskTheLog',
  366. addition: {
  367. nodePrimaryKeyId: pkeyId,
  368. recordTime: date,
  369. },
  370. })
  371. }
  372. });
  373. }
  374. //发送消息
  375. const postMsg = ({type, data, fun}) => {
  376. // #ifdef H5
  377. window.frames["exceliframe"].postMessage({
  378. type: type,
  379. source: 'app',
  380. data: data ?? {}
  381. }, envUrl);
  382. // #endif
  383. // #ifdef APP-PLUS
  384. if (fun) wv.evalJS(fun)
  385. // #endif
  386. }
  387. //刷新页面
  388. const flushedPage = () => {
  389. webviewShow.value = false
  390. checkTheLogTaskStatus()
  391. setTimeout(() => {
  392. webviewShow.value = true
  393. }, 500);
  394. }
  395. onUnload(()=>{
  396. // #ifdef H5
  397. window.removeEventListener('message', handleMessage);
  398. // #endif
  399. })
  400. </script>
  401. <style lang="scss" scoped>
  402. page {
  403. height: 100%;
  404. background: #FAFBFE;
  405. }
  406. </style>
  407. <style lang="scss">
  408. @import "@/style/ledger/edit-table.scss";
  409. </style>