CostSurveyTab.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. <template>
  2. <div>
  3. <!-- 调查表填报弹窗(单记录类型) -->
  4. <survey-form-dialog
  5. :visible.sync="surveyFormDialogVisible"
  6. :survey-data="currentSurveyRow"
  7. :form-fields="formFields"
  8. :is-view-mode="isViewMode"
  9. @save="handleSurveyFormSave"
  10. />
  11. <!-- 固定表填报弹窗 -->
  12. <fixed-table-dialog
  13. :visible.sync="fixedTableDialogVisible"
  14. :survey-data="currentSurveyRow"
  15. :table-items="tableItems"
  16. :audit-periods="auditPeriods"
  17. :is-view-mode="isViewMode"
  18. @save="handleFixedTableSave"
  19. />
  20. <!-- 动态表填报弹窗 -->
  21. <dynamic-table-dialog
  22. :visible.sync="dynamicTableDialogVisible"
  23. :survey-data="currentSurveyRow"
  24. :table-data="dynamicTableData"
  25. :table-items="tableItems"
  26. :is-view-mode="isViewMode"
  27. @save="handleDynamicTableSave"
  28. />
  29. <el-table
  30. style="width: 100%; margin-top: 20px"
  31. :data="paginatedData"
  32. border
  33. size="medium"
  34. >
  35. <!-- 序号列 -->
  36. <el-table-column prop="index" label="序号" width="60" align="center">
  37. <template slot-scope="scope">
  38. {{ scope.$index + 1 }}
  39. </template>
  40. </el-table-column>
  41. <el-table-column label="成本调查表" min-width="220">
  42. <template slot-scope="scope">
  43. <span
  44. :style="{
  45. color: scope.row.isDisabled ? '#909399' : '#409EFF',
  46. cursor: scope.row.isDisabled ? 'default' : 'pointer',
  47. }"
  48. @click="
  49. !scope.row.isDisabled && $emit('handle-survey-click', scope.row)
  50. "
  51. >
  52. {{ scope.row.name }}
  53. </span>
  54. </template>
  55. </el-table-column>
  56. <!-- 资料类型列 -->
  57. <el-table-column
  58. prop="dataType"
  59. label="资料类型"
  60. width="120"
  61. align="center"
  62. ></el-table-column>
  63. <!-- 表格类型列 -->
  64. <el-table-column
  65. prop="tableType"
  66. label="表格类型"
  67. width="120"
  68. align="center"
  69. ></el-table-column>
  70. <!-- 是否必填列 -->
  71. <el-table-column
  72. prop="isRequired"
  73. label="是否必填"
  74. width="100"
  75. align="center"
  76. >
  77. <template slot-scope="scope">
  78. <span>
  79. {{ scope.row.isRequired === '1' ? '是' : '否' }}
  80. </span>
  81. </template>
  82. </el-table-column>
  83. <!-- 是否上传列(红色“未上传”、绿色“已上传”) -->
  84. <el-table-column label="是否上传" width="100" align="center">
  85. <template slot-scope="scope">
  86. <span
  87. :style="{
  88. color: scope.row.isUploaded === true ? '#67c23a' : '#f56c6c',
  89. }"
  90. >
  91. {{ scope.row.isUploaded === true ? '已上传' : '未上传' }}
  92. </span>
  93. </template>
  94. </el-table-column>
  95. <!-- 操作列(根据“是否上传”“表格类型”显示不同按钮) -->
  96. <el-table-column label="操作" width="280" align="center">
  97. <template slot-scope="scope">
  98. <template v-if="scope.row.isUploaded">
  99. <el-button
  100. type="text"
  101. size="small"
  102. :disabled="isViewMode"
  103. @click="handleOnlineFillClick(scope.row)"
  104. >
  105. 在线填报
  106. </el-button>
  107. <el-button
  108. type="text"
  109. size="small"
  110. :disabled="isViewMode"
  111. @click="$emit('handle-modify', scope.row)"
  112. >
  113. 修改
  114. </el-button>
  115. <el-button
  116. type="text"
  117. size="small"
  118. :disabled="isViewMode"
  119. @click="$emit('handle-data-download', scope.row)"
  120. >
  121. 数据下载
  122. </el-button>
  123. <el-button
  124. type="text"
  125. size="small"
  126. :disabled="isViewMode"
  127. @click="$emit('handle-data-upload', scope.row)"
  128. >
  129. 数据上传
  130. </el-button>
  131. </template>
  132. <template v-else>
  133. <el-button
  134. type="text"
  135. size="small"
  136. :disabled="isViewMode"
  137. @click="handleOnlineFillClick(scope.row)"
  138. >
  139. 在线填报
  140. </el-button>
  141. <el-button
  142. v-if="scope.row.tableType === '动态表'"
  143. type="text"
  144. size="small"
  145. :disabled="isViewMode"
  146. @click="$emit('handle-template-download', scope.row)"
  147. >
  148. 模版下载
  149. </el-button>
  150. <el-button
  151. type="text"
  152. size="small"
  153. :disabled="isViewMode"
  154. @click="$emit('handle-data-upload', scope.row)"
  155. >
  156. 数据上传
  157. </el-button>
  158. </template>
  159. </template>
  160. </el-table-column>
  161. </el-table>
  162. <el-pagination
  163. background
  164. layout="total, sizes, prev, pager, next"
  165. :current-page="pagination.currentPage"
  166. :page-sizes="[10, 20, 30, 50]"
  167. :page-size="pagination.pageSize"
  168. :total="pagination.total"
  169. style="margin-top: 20px; text-align: right"
  170. @current-change="$emit('handle-page-change', $event)"
  171. @size-change="$emit('handle-size-change', $event)"
  172. />
  173. </div>
  174. </template>
  175. <script>
  176. import SurveyFormDialog from './SurveyFormDialog.vue'
  177. import FixedTableDialog from './FixedTableDialog.vue'
  178. import DynamicTableDialog from './DynamicTableDialog.vue'
  179. export default {
  180. name: 'CostSurveyTab',
  181. components: {
  182. SurveyFormDialog,
  183. FixedTableDialog,
  184. DynamicTableDialog,
  185. },
  186. props: {
  187. paginatedData: {
  188. type: Array,
  189. default: () => [],
  190. },
  191. pagination: {
  192. type: Object,
  193. default: () => ({ currentPage: 1, pageSize: 10, total: 0 }),
  194. },
  195. isViewMode: {
  196. type: Boolean,
  197. default: false,
  198. },
  199. },
  200. data() {
  201. return {
  202. surveyFormDialogVisible: false,
  203. fixedTableDialogVisible: false,
  204. dynamicTableDialogVisible: false,
  205. currentSurveyRow: null,
  206. // 表单字段配置(可以从后台获取,或通过 props 传入)
  207. formFields: [],
  208. // 固定表数据配置
  209. tableItems: [],
  210. // 监审期间(年份数组)
  211. auditPeriods: [],
  212. // 动态表数据
  213. dynamicTableData: [],
  214. }
  215. },
  216. mounted() {
  217. // 如果当前行有表单配置,则使用,否则使用默认配置
  218. // 这里可以根据实际需求从后台获取表单配置
  219. this.initFormFields()
  220. },
  221. methods: {
  222. // 处理在线填报点击
  223. handleOnlineFillClick(row) {
  224. this.currentSurveyRow = row
  225. // 如果表格类型是"单记录",弹出调查表填报弹窗
  226. if (row.tableType === '单记录') {
  227. // 初始化表单字段配置
  228. this.initFormFields()
  229. this.surveyFormDialogVisible = true
  230. } else if (row.tableType === '固定表') {
  231. // 如果表格类型是"固定表",弹出固定表填报弹窗
  232. this.initFixedTableData()
  233. this.fixedTableDialogVisible = true
  234. } else if (row.tableType === '动态表') {
  235. // 如果表格类型是"动态表",弹出动态表填报弹窗
  236. this.initDynamicTableData()
  237. this.dynamicTableDialogVisible = true
  238. } else {
  239. // 其他类型,触发原有事件
  240. this.$emit('handle-online-fill', row)
  241. }
  242. },
  243. // 处理调查表保存
  244. handleSurveyFormSave(formData) {
  245. // 可以将保存的数据传递给父组件
  246. this.$emit('handle-survey-form-save', {
  247. row: this.currentSurveyRow,
  248. formData: formData,
  249. })
  250. },
  251. // 处理固定表保存
  252. handleFixedTableSave(tableData) {
  253. // 可以将保存的数据传递给父组件
  254. this.$emit('handle-fixed-table-save', {
  255. row: this.currentSurveyRow,
  256. tableData: tableData,
  257. })
  258. },
  259. // 处理动态表保存
  260. handleDynamicTableSave(tableData) {
  261. // 可以将保存的数据传递给父组件
  262. this.$emit('handle-dynamic-table-save', {
  263. row: this.currentSurveyRow,
  264. tableData: tableData,
  265. })
  266. },
  267. // 初始化动态表数据
  268. initDynamicTableData() {
  269. // 如果当前行有动态表数据,则使用
  270. if (this.currentSurveyRow && this.currentSurveyRow.dynamicTableData) {
  271. this.dynamicTableData = this.currentSurveyRow.dynamicTableData
  272. } else {
  273. // 使用空数组,组件内部会使用假数据
  274. this.dynamicTableData = []
  275. }
  276. // 初始化表格项配置(用于详情/编辑时显示表单)
  277. if (this.currentSurveyRow && this.currentSurveyRow.tableItems) {
  278. this.tableItems = this.currentSurveyRow.tableItems
  279. } else {
  280. // 使用固定表的假数据配置
  281. this.tableItems = this.getMockTableItems()
  282. }
  283. },
  284. // 初始化表单字段配置
  285. initFormFields() {
  286. // 如果当前行有表单配置,则使用
  287. // 这里可以根据实际需求从后台获取表单配置
  288. // 例如:从 currentSurveyRow 中获取表单配置,或调用 API 获取
  289. if (this.currentSurveyRow && this.currentSurveyRow.formFields) {
  290. this.formFields = this.currentSurveyRow.formFields
  291. } else {
  292. // 使用假数据作为测试(实际开发中应该从后台获取)
  293. this.formFields = this.getMockFormFields()
  294. }
  295. },
  296. // 获取假数据表单字段配置(用于测试)
  297. getMockFormFields() {
  298. return [
  299. {
  300. prop: 'institutionName',
  301. label: '机构名称',
  302. type: 'input',
  303. colSpan: 12,
  304. defaultValue: '幼儿园基本情况',
  305. placeholder: '请输入机构名称',
  306. required: true,
  307. },
  308. {
  309. prop: 'institutionNature',
  310. label: '机构性质',
  311. type: 'select',
  312. colSpan: 12,
  313. dictType: 'institutionNature', // 字典类型
  314. defaultValue: '公办',
  315. placeholder: '请选择机构性质',
  316. required: true,
  317. clearable: true,
  318. },
  319. {
  320. prop: 'institutionLevel',
  321. label: '机构评定等级',
  322. type: 'select',
  323. colSpan: 12,
  324. dictType: 'institutionLevel', // 字典类型
  325. defaultValue: '省一级',
  326. placeholder: '请选择机构评定等级',
  327. required: true,
  328. clearable: true,
  329. },
  330. {
  331. prop: 'educationMode',
  332. label: '机构办学方式',
  333. type: 'select',
  334. colSpan: 12,
  335. dictType: 'educationMode', // 字典类型
  336. defaultValue: '全日制',
  337. placeholder: '请选择机构办学方式',
  338. required: true,
  339. clearable: true,
  340. },
  341. {
  342. prop: 'institutionAddress',
  343. label: '机构地址',
  344. type: 'input',
  345. colSpan: 12,
  346. placeholder: '请输入机构地址',
  347. required: true,
  348. },
  349. {
  350. prop: 'formFiller',
  351. label: '机构填表人',
  352. type: 'input',
  353. colSpan: 12,
  354. placeholder: '请输入机构填表人',
  355. required: true,
  356. },
  357. {
  358. prop: 'financialManager',
  359. label: '机构财务负责人',
  360. type: 'input',
  361. colSpan: 12,
  362. placeholder: '请输入机构财务负责人',
  363. required: true,
  364. },
  365. {
  366. prop: 'contactPhone',
  367. label: '机构联系电话',
  368. type: 'input',
  369. colSpan: 12,
  370. placeholder: '请输入机构联系电话',
  371. required: true,
  372. rules: [
  373. {
  374. required: true,
  375. message: '请输入机构联系电话',
  376. trigger: 'blur',
  377. },
  378. {
  379. pattern: /^1[3-9]\d{9}$/,
  380. message: '请输入正确的手机号码',
  381. trigger: 'blur',
  382. },
  383. ],
  384. },
  385. ]
  386. },
  387. // 初始化固定表数据
  388. initFixedTableData() {
  389. // 如果当前行有表格配置,则使用
  390. if (this.currentSurveyRow && this.currentSurveyRow.tableItems) {
  391. this.tableItems = this.currentSurveyRow.tableItems
  392. } else {
  393. // 使用假数据作为测试(实际开发中应该从后台获取)
  394. this.tableItems = this.getMockTableItems()
  395. }
  396. // 初始化监审期间
  397. if (this.currentSurveyRow && this.currentSurveyRow.auditPeriod) {
  398. this.auditPeriods = this.parseAuditPeriod(
  399. this.currentSurveyRow.auditPeriod
  400. )
  401. } else {
  402. // 默认使用最近3年
  403. const currentYear = new Date().getFullYear()
  404. this.auditPeriods = [
  405. String(currentYear - 2),
  406. String(currentYear - 1),
  407. String(currentYear),
  408. ]
  409. }
  410. },
  411. // 解析监审期间字符串(如 "2022,2023,2024" 或 "2022-2024")
  412. parseAuditPeriod(periodStr) {
  413. if (!periodStr) return []
  414. if (periodStr.includes(',')) {
  415. return periodStr.split(',').map((p) => p.trim())
  416. }
  417. if (periodStr.includes('-')) {
  418. const parts = periodStr.split('-')
  419. if (parts.length === 2) {
  420. const start = parseInt(parts[0].trim())
  421. const end = parseInt(parts[1].trim())
  422. const years = []
  423. for (let year = start; year <= end; year++) {
  424. years.push(String(year))
  425. }
  426. return years
  427. }
  428. }
  429. return [String(periodStr)]
  430. },
  431. // 获取假数据表格配置(用于测试)
  432. getMockTableItems() {
  433. return [
  434. {
  435. id: '1',
  436. itemName: '班级数',
  437. unit: '个',
  438. isCategory: false,
  439. seq: 1,
  440. validateRules: {
  441. required: true,
  442. type: 'number',
  443. min: 0,
  444. },
  445. },
  446. {
  447. id: '2',
  448. itemName: '幼儿学生人数',
  449. unit: '人',
  450. isCategory: false,
  451. seq: 2,
  452. validateRules: {
  453. required: true,
  454. type: 'number',
  455. min: 0,
  456. },
  457. },
  458. {
  459. id: 'III',
  460. itemName: '在取做保职工总人数',
  461. unit: '人',
  462. isCategory: true,
  463. categorySeq: 'III',
  464. children: [
  465. {
  466. id: '3-1',
  467. itemName: '行政管理人员数',
  468. unit: '人',
  469. isCategory: false,
  470. categoryId: 'III',
  471. seq: 3,
  472. validateRules: {
  473. required: true,
  474. type: 'number',
  475. min: 0,
  476. },
  477. linkageRules: {
  478. parent: 'III',
  479. relation: 'sum',
  480. },
  481. },
  482. {
  483. id: '3-2',
  484. itemName: '教师人数',
  485. unit: '人',
  486. isCategory: false,
  487. categoryId: 'III',
  488. seq: 4,
  489. validateRules: {
  490. required: true,
  491. type: 'number',
  492. min: 0,
  493. },
  494. linkageRules: {
  495. parent: 'III',
  496. relation: 'sum',
  497. },
  498. },
  499. {
  500. id: '3-3',
  501. itemName: '保育员人数',
  502. unit: '人',
  503. isCategory: false,
  504. categoryId: 'III',
  505. seq: 5,
  506. validateRules: {
  507. required: true,
  508. type: 'number',
  509. min: 0,
  510. },
  511. linkageRules: {
  512. parent: 'III',
  513. relation: 'sum',
  514. },
  515. },
  516. {
  517. id: '3-4',
  518. itemName: '医务人员',
  519. unit: '人',
  520. isCategory: false,
  521. categoryId: 'III',
  522. seq: 6,
  523. validateRules: {
  524. required: true,
  525. type: 'number',
  526. min: 0,
  527. },
  528. linkageRules: {
  529. parent: 'III',
  530. relation: 'sum',
  531. },
  532. },
  533. {
  534. id: '3-5',
  535. itemName: '工勤人员',
  536. unit: '人',
  537. isCategory: false,
  538. categoryId: 'III',
  539. seq: 7,
  540. validateRules: {
  541. required: true,
  542. type: 'number',
  543. min: 0,
  544. },
  545. linkageRules: {
  546. parent: 'III',
  547. relation: 'sum',
  548. },
  549. children: [
  550. {
  551. id: '3-5-1',
  552. itemName: '炊事员',
  553. unit: '人',
  554. isCategory: false,
  555. categoryId: '3-5',
  556. seq: 8,
  557. validateRules: {
  558. required: true,
  559. type: 'number',
  560. min: 0,
  561. },
  562. linkageRules: {
  563. parent: '3-5',
  564. relation: 'sum',
  565. },
  566. },
  567. {
  568. id: '3-5-2',
  569. itemName: '司机',
  570. unit: '人',
  571. isCategory: false,
  572. categoryId: '3-5',
  573. seq: 9,
  574. validateRules: {
  575. required: true,
  576. type: 'number',
  577. min: 0,
  578. },
  579. linkageRules: {
  580. parent: '3-5',
  581. relation: 'sum',
  582. },
  583. },
  584. {
  585. id: '3-5-3',
  586. itemName: '清洁工',
  587. unit: '人',
  588. isCategory: false,
  589. categoryId: '3-5',
  590. seq: 10,
  591. validateRules: {
  592. required: true,
  593. type: 'number',
  594. min: 0,
  595. },
  596. linkageRules: {
  597. parent: '3-5',
  598. relation: 'sum',
  599. },
  600. },
  601. ],
  602. },
  603. {
  604. id: '3-6',
  605. itemName: '其他人员',
  606. unit: '人',
  607. isCategory: false,
  608. categoryId: 'III',
  609. seq: 11,
  610. validateRules: {
  611. required: true,
  612. type: 'number',
  613. min: 0,
  614. },
  615. linkageRules: {
  616. parent: 'III',
  617. relation: 'sum',
  618. },
  619. },
  620. ],
  621. },
  622. ]
  623. },
  624. },
  625. }
  626. </script>