add-export-to-nine-precautions.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. const fs = require('fs')
  2. const path = require('path')
  3. const baseDir = path.resolve(__dirname, '../src/views/elderly/apply/nine-precautions')
  4. const configs = [
  5. {
  6. dir: 'MMSE',
  7. pageApi: 'mmseGetPage',
  8. title: 'MMSE认知评估',
  9. columns: [
  10. { key: 'orgName', title: '机构名称' },
  11. { key: 'elderName', title: '长者姓名' },
  12. { key: 'assessor', title: '评估人' },
  13. { key: 'assessDate', title: '记录日期' },
  14. { key: 'riskLevelText', title: '风险等级' },
  15. { key: 'creator', title: '记录人' }
  16. ],
  17. riskMode: 'info'
  18. },
  19. {
  20. dir: 'anti-entertainment',
  21. pageApi: 'entertainmentPage',
  22. title: '防文娱活动意外评估',
  23. columns: [
  24. { key: 'orgName', title: '机构名称' },
  25. { key: 'elderName', title: '长者姓名' },
  26. { key: 'assessor', title: '评估人' },
  27. { key: 'assessDate', title: '记录日期' },
  28. { key: 'assessScore', title: '评估总得分' },
  29. { key: 'riskLevelText', title: '风险等级' },
  30. { key: 'creator', title: '记录人' }
  31. ],
  32. riskMode: 'text'
  33. },
  34. {
  35. dir: 'asphyxiation-by-choking',
  36. pageApi: 'asphyxiationPage',
  37. title: '防噎食评估',
  38. columns: [
  39. { key: 'orgName', title: '机构名称' },
  40. { key: 'elderName', title: '长者姓名' },
  41. { key: 'assessor', title: '评估人' },
  42. { key: 'assessDate', title: '记录日期' },
  43. { key: 'riskLevelText', title: '风险等级' },
  44. { key: 'creator', title: '记录人' }
  45. ],
  46. riskMode: 'text'
  47. },
  48. {
  49. dir: 'attack',
  50. pageApi: 'attackRiskPage',
  51. title: '攻击风险评估',
  52. columns: [
  53. { key: 'orgName', title: '机构名称' },
  54. { key: 'elderName', title: '长者姓名' },
  55. { key: 'assessor', title: '评估人' },
  56. { key: 'riskLevelText', title: '风险等级' },
  57. { key: 'assessDate', title: '记录日期' },
  58. { key: 'creator', title: '记录人' }
  59. ],
  60. riskMode: 'info'
  61. },
  62. {
  63. dir: 'commit-suicide',
  64. pageApi: 'ngasrPage',
  65. title: '自伤自杀风险评估',
  66. columns: [
  67. { key: 'orgName', title: '机构名称' },
  68. { key: 'elderName', title: '长者姓名' },
  69. { key: 'assessor', title: '评估人' },
  70. { key: 'assessDate', title: '记录日期' },
  71. { key: 'riskLevelText', title: '风险等级' },
  72. { key: 'creator', title: '记录人' }
  73. ],
  74. riskMode: 'info'
  75. },
  76. {
  77. dir: 'communication',
  78. pageApi: 'perceptionPage',
  79. title: '感知沟通评估',
  80. columns: [
  81. { key: 'orgName', title: '机构名称' },
  82. { key: 'elderName', title: '长者姓名' },
  83. { key: 'assessor', title: '评估人' },
  84. { key: 'assessDate', title: '记录日期' },
  85. { key: 'riskLevelText', title: '风险等级' },
  86. { key: 'creator', title: '记录人' }
  87. ],
  88. riskMode: 'info'
  89. },
  90. {
  91. dir: 'daily-life',
  92. pageApi: 'dailyLifePage',
  93. title: '日常生活活动能力评估',
  94. columns: [
  95. { key: 'orgName', title: '机构名称' },
  96. { key: 'elderName', title: '长者姓名' },
  97. { key: 'assessor', title: '评估人' },
  98. { key: 'assessDate', title: '记录日期' },
  99. { key: 'assessScore', title: '评估总得分' },
  100. { key: 'riskLevelText', title: '结果等级' },
  101. { key: 'creator', title: '记录人' }
  102. ],
  103. riskMode: 'result'
  104. },
  105. {
  106. dir: 'empyrosis',
  107. pageApi: 'burnPreventionPage',
  108. title: '防烫伤评估',
  109. columns: [
  110. { key: 'orgName', title: '机构名称' },
  111. { key: 'elderName', title: '长者姓名' },
  112. { key: 'assessor', title: '评估人' },
  113. { key: 'assessDate', title: '记录日期' },
  114. { key: 'riskLevelText', title: '风险等级' },
  115. { key: 'assessScore', title: '评估总得分' },
  116. { key: 'creator', title: '记录人' }
  117. ],
  118. riskMode: 'text'
  119. },
  120. {
  121. dir: 'equilibrium',
  122. pageApi: 'equilibriumPage',
  123. title: '平衡能力评估',
  124. columns: [
  125. { key: 'orgName', title: '机构名称' },
  126. { key: 'elderName', title: '长者姓名' },
  127. { key: 'assessor', title: '评估人' },
  128. { key: 'assessDate', title: '记录日期' },
  129. { key: 'assessScore', title: '评估总得分' },
  130. { key: 'riskLevelText', title: '风险等级' },
  131. { key: 'creator', title: '记录人' }
  132. ],
  133. riskMode: 'text'
  134. },
  135. {
  136. dir: 'fall-down',
  137. pageApi: 'fallDownPage',
  138. title: '跌倒风险评估',
  139. columns: [
  140. { key: 'orgName', title: '机构名称' },
  141. { key: 'elderName', title: '长者姓名' },
  142. { key: 'assessor', title: '评估人' },
  143. { key: 'assessDate', title: '记录日期' },
  144. { key: 'assessScore', title: '评估总得分' },
  145. { key: 'riskLevelText', title: '风险等级' },
  146. { key: 'creator', title: '记录人' }
  147. ],
  148. riskMode: 'text'
  149. },
  150. {
  151. dir: 'fall-prevention-measures',
  152. pageApi: 'fallPreventionPage',
  153. title: '防坠床评估',
  154. columns: [
  155. { key: 'orgName', title: '机构名称' },
  156. { key: 'elderName', title: '长者姓名' },
  157. { key: 'assessor', title: '评估人' },
  158. { key: 'assessDate', title: '记录日期' },
  159. { key: 'assessScore', title: '评估总得分' },
  160. { key: 'riskLevelText', title: '风险等级' },
  161. { key: 'creator', title: '记录人' }
  162. ],
  163. riskMode: 'text'
  164. },
  165. {
  166. dir: 'pressure-sores',
  167. pageApi: 'pressureSoresPage',
  168. title: '防压疮评估',
  169. columns: [
  170. { key: 'orgName', title: '机构名称' },
  171. { key: 'elderName', title: '长者姓名' },
  172. { key: 'assessor', title: '评估人' },
  173. { key: 'assessDate', title: '记录日期' },
  174. { key: 'assessScore', title: '评估总得分' },
  175. { key: 'riskLevelText', title: '风险等级' },
  176. { key: 'creator', title: '记录人' }
  177. ],
  178. riskMode: 'text'
  179. },
  180. {
  181. dir: 'nutritional-risk',
  182. pageApi: 'nutritionalRiskPage',
  183. title: '营养风险评估',
  184. columns: [
  185. { key: 'orgName', title: '机构名称' },
  186. { key: 'elderName', title: '长者姓名' },
  187. { key: 'assessor', title: '评估人' },
  188. { key: 'assessDate', title: '记录日期' },
  189. { key: 'assessScore', title: '量表总分' },
  190. { key: 'riskLevelText', title: '评估结果' },
  191. { key: 'creator', title: '记录人' }
  192. ],
  193. riskMode: 'result'
  194. },
  195. {
  196. dir: 'wander-away',
  197. pageApi: 'wanderAwayPage',
  198. title: '防走失风险评估',
  199. columns: [
  200. { key: 'orgName', title: '机构名称' },
  201. { key: 'elderName', title: '长者姓名' },
  202. { key: 'assessor', title: '评估人' },
  203. { key: 'assessDate', title: '记录日期' },
  204. { key: 'assessScore', title: '评估总得分' },
  205. { key: 'riskLevelText', title: '风险等级' },
  206. { key: 'creator', title: '记录人' }
  207. ],
  208. riskMode: 'text'
  209. }
  210. ]
  211. function buildExportFunction(config) {
  212. const { pageApi, title, columns, riskMode } = config
  213. const headersStr = JSON.stringify(columns, null, 6).replace(/"/g, "'")
  214. let riskLevelProcess = ''
  215. if (riskMode === 'info') {
  216. riskLevelProcess = `const riskInfo = getRiskLevelInfo(item.assessData)
  217. row.riskLevelText = riskInfo.text || '-'`
  218. } else if (riskMode === 'text') {
  219. riskLevelProcess = `row.riskLevelText = getRiskLevelText(item.riskLevel) || '-'`
  220. } else if (riskMode === 'result') {
  221. riskLevelProcess = `row.riskLevelText = getResultLevelText(item.riskLevel) || '-'`
  222. }
  223. return `
  224. // 打开导出弹窗
  225. const handleImportCard = async () => {
  226. exportLoading.value = true
  227. try {
  228. const queryP = {
  229. pageNo: 1,
  230. pageSize: 9999,
  231. elderName: queryParams.elderName,
  232. assessor: queryParams.assessor,
  233. assessDate: queryParams.assessDate,
  234. tenantIds: queryParams.tenantIds
  235. }
  236. const data = await ${pageApi}(queryP)
  237. const exportData = data.list || []
  238. if (exportData.length === 0) {
  239. message.warning('暂无数据可导出')
  240. return
  241. }
  242. const processedData = exportData.map((item) => {
  243. const row = {
  244. orgName: findLabelById(userStore.getOrgTenant.options, item.tenantId) || '',
  245. elderName: item.elderName || '',
  246. assessor: item.assessor || '',
  247. assessDate: item.assessDate || '',
  248. assessScore: item.assessScore ?? '',
  249. creator: item.creator || ''
  250. }
  251. ${riskLevelProcess}
  252. return row
  253. })
  254. const headers = ${headersStr}
  255. exportWithExpandedObjectArrays(processedData, headers, \`${title}_\${new Date().getTime()}.xlsx\`, '${title}')
  256. message.success('导出成功')
  257. } catch (error) {
  258. console.error('导出失败:', error)
  259. message.error('导出失败,请重试')
  260. } finally {
  261. exportLoading.value = false
  262. }
  263. }
  264. `
  265. }
  266. function removeBlock(content, startRegex, endMarker) {
  267. const startMatch = content.match(startRegex)
  268. if (!startMatch) return content
  269. const startIndex = startMatch.index
  270. let depth = 0
  271. let endIndex = startIndex
  272. for (let i = startIndex; i < content.length; i++) {
  273. if (content[i] === '{') depth++
  274. if (content[i] === '}') {
  275. depth--
  276. if (depth === 0) {
  277. endIndex = i + 1
  278. break
  279. }
  280. }
  281. }
  282. // 包含到 endMarker 之前或之后的换行
  283. let before = content.slice(0, startIndex)
  284. let after = content.slice(endIndex)
  285. if (after.startsWith('\n')) after = after.slice(1)
  286. return before + after
  287. }
  288. function processFile(config) {
  289. const filePath = path.join(baseDir, config.dir, 'index.vue')
  290. if (!fs.existsSync(filePath)) {
  291. console.log(`跳过:${filePath} 不存在`)
  292. return
  293. }
  294. let content = fs.readFileSync(filePath, 'utf-8')
  295. // 1. 添加 ButtonImport 导入(如果还没有)
  296. if (!content.includes("import ButtonImport from '@/components/ButtonImport/src/ButtonImport.vue'")) {
  297. content = content.replace(
  298. "import ButtonAdd from '@/components/ButtonAdd/src/ButtonAdd.vue'",
  299. "import ButtonAdd from '@/components/ButtonAdd/src/ButtonAdd.vue'\nimport ButtonImport from '@/components/ButtonImport/src/ButtonImport.vue'"
  300. )
  301. }
  302. // 2. 添加 exportWithExpandedObjectArrays 导入
  303. if (!content.includes("import { exportWithExpandedObjectArrays } from '@/utils/excel-export'")) {
  304. const apiImportMatch = content.match(/import \{[^}]+\} from '@\/api\/social-work'/)
  305. if (apiImportMatch) {
  306. const insertPos = apiImportMatch.index + apiImportMatch[0].length
  307. content = content.slice(0, insertPos) + "\nimport { exportWithExpandedObjectArrays } from '@/utils/excel-export'" + content.slice(insertPos)
  308. } else {
  309. content = content.replace(
  310. '<script setup lang="ts">',
  311. '<script setup lang="ts">\nimport { exportWithExpandedObjectArrays } from \'@/utils/excel-export\''
  312. )
  313. }
  314. }
  315. // 3. 添加导出按钮(紧跟 ButtonAdd 之后,并移除原有的注释导入按钮)
  316. content = content.replace(
  317. /<ButtonAdd @click="openForm\(undefined\)"\s*\/>/g,
  318. '<ButtonAdd @click="openForm(undefined)" />\n <ButtonImport @click="handleImportCard" />'
  319. )
  320. // 移除旧的注释按钮行
  321. content = content.replace(/\s*<!--\s*<ButtonImport[^>]*>\s*-->\s*/g, '\n')
  322. // 4. 移除 BatchExportDialog 组件
  323. content = content.replace(
  324. /\s*<!-- 通用批量导出弹窗 -->\s*<BatchExportDialog[\s\S]*?<\/BatchExportDialog>/,
  325. ''
  326. )
  327. // 5. 移除已存在的 handleImportCard / handleBatchExport / handleExport 空壳函数
  328. content = content.replace(
  329. /\/\/ 打开导出弹窗\s*const handleImportCard = async \(\) => \{[\s\S]*?\}\s*/,
  330. ''
  331. )
  332. content = removeBlock(
  333. content,
  334. /\/\/ 处理批量导出\s*const handleBatchExport = async \(batch: number, count: number\) => \{/,
  335. ''
  336. )
  337. content = removeBlock(
  338. content,
  339. /const handleExport = \(\) => \{/,
  340. ''
  341. )
  342. // 6. 精简状态管理为只保留 exportLoading
  343. content = content.replace(
  344. /\n\/\/ 状态管理\s*const showBatchExport = ref\(false\)\s*const exportConfig = ref\(\{[\s\S]*?description: \[\] as string\[\]\s*\}\)\s*const exportLoading = ref\(false\)\s*/,
  345. '\nconst exportLoading = ref(false)\n'
  346. )
  347. // 7. 插入新的 handleImportCard 函数
  348. const exportFunc = buildExportFunction(config)
  349. // 优先在 queryFormRef 定义后插入
  350. const queryFormRefPattern = /const queryFormRef = ref\(\)\s*\/\/ 搜索的表单/
  351. if (queryFormRefPattern.test(content)) {
  352. content = content.replace(queryFormRefPattern, `const queryFormRef = ref() // 搜索的表单\n${exportFunc}`)
  353. } else {
  354. content = content.replace(
  355. /const queryFormRef = ref\(\)\s*$/m,
  356. `const queryFormRef = ref()\n${exportFunc}`
  357. )
  358. }
  359. fs.writeFileSync(filePath, content, 'utf-8')
  360. console.log(`已处理:${filePath}`)
  361. }
  362. configs.forEach(processFile)