DocRecord.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <template>
  2. <div class="ya_bar">
  3. <h3>预案内容</h3>
  4. <div>
  5. <el-button type="primary" @click="importDoc()"> 导入预案 </el-button>
  6. <el-button type="info" plain icon="Download" @click="handleTemplate">下载导入模板</el-button>
  7. </div>
  8. </div>
  9. <el-card shadow="hover" v-show="doc_items.length > 0">
  10. <el-tabs v-model="activeName" type="border-card" class="demo-tabs" @tab-click="handleClick2">
  11. <!--
  12. <el-tab-pane label="总则" name="first">
  13. <div>
  14. <el-row>
  15. <el-col :span="4">
  16. <el-anchor :container="containerRef" direction="vertical" type="default" :offset="30" @click="handleClick1">
  17. <el-anchor-link href="#part1" title="编制目的" />
  18. <el-anchor-link href="#part2" title="编制依据" />
  19. <el-anchor-link href="#part3" title="适用范围" />
  20. <el-anchor-link href="#part4" title="工作原则" />
  21. </el-anchor>
  22. </el-col>
  23. <el-col :span="20">
  24. <div ref="containerRef" style="height: 300px; overflow-y: auto">
  25. <div id="part1" style="height: auto; margin-top: 20px; font-size: 14px">
  26. <h3 style="font-weight: 600">1.1 编制目的</h3>
  27. <span style="text-indent: 2em"
  28. >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
  29. >
  30. </div>
  31. <div id="part2" style="height: auto; margin-top: 15px; font-size: 14px">
  32. <h3 style="font-weight: 600">1.2 编制依据</h3>
  33. <span style="text-indent: 28px"
  34. >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
  35. >
  36. </div>
  37. <div id="part3" style="height: auto; margin-top: 15px; font-size: 14px">
  38. <h3 style="font-weight: 600">1.3 适用范围</h3>
  39. <span style="text-indent: 28px"
  40. >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
  41. >
  42. </div>
  43. <div id="part4" style="height: auto; margin-top: 15px; font-size: 14px">
  44. <h3 style="font-weight: 600">1.4 工作原则</h3>
  45. <span style="text-indent: 28px"
  46. >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
  47. >
  48. </div>
  49. </div>
  50. </el-col>
  51. </el-row>
  52. </div>
  53. </el-tab-pane>
  54. -->
  55. <el-tab-pane :label="item.title" :name="item.id" v-for="(item, index) in doc_items" :key="index">
  56. <div>
  57. <el-row>
  58. <el-col :span="4">
  59. <el-anchor container="`containerRef${index}`" direction="vertical" type="default" :offset="30" @click="handleClick1">
  60. <el-anchor-link :href="sub_item.href" :title="sub_item.title" :name="sub_item.id" v-for="(sub_item, index2) in item.items" :key="index2"/>
  61. </el-anchor>
  62. </el-col>
  63. <el-col :span="20">
  64. <div ref="`containerRef${index}`" style="height: 400px; overflow-y: auto">
  65. <div :id="sub_item.id" style="height: auto; margin-top: 15px; font-size: 14px" v-for="(sub_item, index3) in item.items" :key="index3">
  66. <h3 style="font-weight: 600">{{ sub_item.title }}</h3>
  67. <span v-html="sub_item.value"></span>
  68. </div>
  69. </div>
  70. </el-col>
  71. </el-row>
  72. </div>
  73. </el-tab-pane>
  74. </el-tabs>
  75. </el-card>
  76. <el-dialog ref="formDialogRef" v-model="showImportDlg" title="导入结构化文档" width="500px" append-to-body>
  77. <el-form ref="formRef" :model="form" :rules="rules">
  78. <FileUpload v-model="form.filename" :file-type="['xls', 'xlsx']" :limit="1" />
  79. </el-form>
  80. <template #footer>
  81. <div class="dialog-footer">
  82. <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
  83. <el-button @click="cancel">取 消</el-button>
  84. </div>
  85. </template>
  86. </el-dialog>
  87. </template>
  88. <script setup lang="ts">
  89. import { ref } from 'vue';
  90. import type { TabsPaneContext } from 'element-plus';
  91. import { getDoc, importDocXls } from '@/api/riskPrevention/planManage';
  92. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  93. // const containerRef = ref<HTMLElement | null>(null);
  94. const doc_items = ref([]);
  95. const props = defineProps({
  96. id: String
  97. });
  98. watch(
  99. () => props.id,
  100. () => {
  101. if (props.id) {
  102. getData();
  103. }
  104. },
  105. {
  106. immediate: true
  107. }
  108. );
  109. const handleClick1 = (e: MouseEvent) => {
  110. e.preventDefault();
  111. };
  112. const activeName = ref('first');
  113. const handleClick2 = (tab: TabsPaneContext, event: Event) => {
  114. // console.log(tab, event);
  115. };
  116. const getData = () => {
  117. getDoc({plan_id: props.id})
  118. .then((res)=> {
  119. doc_items.value = res.data;
  120. if(doc_items.value.length > 0) {
  121. activeName.value = doc_items.value[0].id;
  122. }
  123. })
  124. }
  125. const baseUrl = import.meta.env.VITE_APP_BASE_API;
  126. const downLoadApi = import.meta.env.VITE_APP_BASE_DOWNLOAD_API;
  127. const showImportDlg = ref(false);
  128. const formDialogRef = ref(null);
  129. const formRef = ref<ElFormInstance>();
  130. const buttonLoading = ref(false);
  131. const form = ref({
  132. filename: ''
  133. });
  134. const rules = reactive({
  135. filename: [{ required: true, message: '导入文件不能为空', trigger: 'blur' }]
  136. });
  137. const importDoc = () => {
  138. resetForm();
  139. showImportDlg.value = true;
  140. }
  141. const resetForm = () => {
  142. form.value = {
  143. filename:''
  144. }
  145. formRef.value?.resetFields();
  146. formRef.value?.clearValidate();
  147. }
  148. /**提交按钮 */
  149. const submitForm = () => {
  150. formRef.value?.validate(async (valid) => {
  151. if (valid) {
  152. try {
  153. buttonLoading.value = true;
  154. await importDocXls({ ...form.value, plan_id: props.id })
  155. proxy?.$modal.msgSuccess('导入成功');
  156. showImportDlg.value = false;
  157. getData();
  158. } finally {
  159. buttonLoading.value = false;
  160. }
  161. }
  162. })
  163. }
  164. /** 取消按钮 */
  165. const cancel = () => {
  166. resetForm();
  167. showImportDlg.value = false;
  168. };
  169. const handleTemplate = async() => {
  170. location.href=baseUrl + downLoadApi + "yjya_doc_import.xlsx";
  171. };
  172. </script>
  173. <style lang="scss" scoped>
  174. .ya_bar {
  175. display:flex;
  176. flex-direction: row;
  177. flex-wrap: nowrap;
  178. justify-content:space-between;
  179. align-items: center;
  180. }
  181. .demo-tabs > .el-tabs__content {
  182. padding: 32px;
  183. color: #6b778c;
  184. font-size: 32px;
  185. font-weight: 600;
  186. }
  187. </style>