index.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <template>
  2. <el-dialog :title="dialogTitle" v-model="dialogVisible" width="900px" append-to-body
  3. :close-on-click-modal="false">
  4. <div v-loading="scLoading">
  5. <!-- 新增抽查:先选择演练实施记录(仅未抽查记录) -->
  6. <el-form v-if="!props.row.drGuid" :model="scForm" label-width="110px">
  7. <el-row>
  8. <el-col :span="24">
  9. <el-form-item label="选择演练记录" prop="drGuid">
  10. <el-select v-model="scForm.drGuid" filterable remote :remote-method="searchDrillRecords"
  11. :loading="drillLoading" placeholder="请输入演练名称搜索(仅未抽查记录)" style="width: 100%"
  12. @change="handleDrillSelected">
  13. <el-option v-for="item in drillOptions" :key="item.drGuid"
  14. :label="`${item.orgName || ''} - ${item.drillName || ''}`" :value="item.drGuid">
  15. <span>{{ item.orgName || '--' }} - {{ item.drillName || '--' }}</span>
  16. <span style="float: right; color: #8492a6; font-size: 12px;">{{ item.drillTime }}</span>
  17. </el-option>
  18. </el-select>
  19. </el-form-item>
  20. </el-col>
  21. </el-row>
  22. </el-form>
  23. <!-- 块一:演练实施记录信息 -->
  24. <el-divider content-position="left">
  25. <el-icon><OfficeBuilding /></el-icon>
  26. <span style="margin-left:6px;font-weight:600;">演练实施记录信息</span>
  27. </el-divider>
  28. <DrillDetail v-if="scDrGuid" :key="'sc-' + scDrGuid + '-' + scSeq" :dr-guid="scDrGuid" inline />
  29. <!-- 块二:预案演练抽查 -->
  30. <el-divider content-position="left">
  31. <el-icon><Checked /></el-icon>
  32. <span style="margin-left:6px;font-weight:600;">预案演练抽查</span>
  33. </el-divider>
  34. <el-form :model="scForm" :rules="scRules" ref="scFormRef" label-width="110px">
  35. <el-row>
  36. <el-col :span="12">
  37. <el-form-item label="抽查时间" prop="scTime">
  38. <el-date-picker v-model="scForm.scTime" type="date" value-format="YYYY-MM-DD"
  39. placeholder="请选择" style="width: 100%" />
  40. </el-form-item>
  41. </el-col>
  42. <el-col :span="12">
  43. <el-form-item label="抽查单位" prop="orgGuid">
  44. <el-input :model-value="userStore.orgName || userStore.orgGuid" disabled />
  45. </el-form-item>
  46. </el-col>
  47. </el-row>
  48. <el-row>
  49. <el-col :span="12">
  50. <el-form-item label="抽查结果" prop="spotCheck">
  51. <el-select v-model="scForm.spotCheck" placeholder="请选择" style="width: 100%">
  52. <el-option v-for="dict in scResultOptions" :key="dict.value" :label="dict.label" :value="dict.value" />
  53. </el-select>
  54. </el-form-item>
  55. </el-col>
  56. </el-row>
  57. <el-row>
  58. <el-col :span="24">
  59. <el-form-item label="抽查结果说明" prop="scExplain">
  60. <el-input v-model="scForm.scExplain" type="textarea" :rows="3" maxlength="200" show-word-limit
  61. placeholder="请输入抽查结果说明" />
  62. </el-form-item>
  63. </el-col>
  64. </el-row>
  65. </el-form>
  66. </div>
  67. <template #footer>
  68. <el-button @click="dialogVisible = false">取消</el-button>
  69. <el-button type="primary" @click="submitScForm">确定</el-button>
  70. </template>
  71. </el-dialog>
  72. </template>
  73. <script setup>
  74. import { computed, getCurrentInstance, reactive, ref, toRefs, watch } from 'vue'
  75. import { getDrillSc, saveDrillSc, listDrillSc } from "@/api/slaj/eme"
  76. import { parseTime } from '@/utils/goldenwater'
  77. import useUserStore from '@/store/modules/user'
  78. import DrillDetail from '@/components/DrillDetail/index.vue'
  79. const props = defineProps({
  80. /** v-model 控制显隐 */
  81. modelValue: { type: Boolean, default: false },
  82. /** 当前演练实施记录行(含 drGuid / basicId) */
  83. row: { type: Object, default: () => ({}) }
  84. })
  85. const emit = defineEmits(['update:modelValue', 'saved'])
  86. const { proxy } = getCurrentInstance()
  87. const userStore = useUserStore()
  88. const { eme_drill_sc_status } = proxy.useDict("eme_drill_sc_status")
  89. const dialogVisible = computed({
  90. get: () => props.modelValue,
  91. set: (val) => emit('update:modelValue', val)
  92. })
  93. const dialogTitle = computed(() =>
  94. (props.row && props.row.drGuid) ? '应急演练记录抽查' : '新增预案演练抽查'
  95. )
  96. const scLoading = ref(false)
  97. const scDrGuid = ref('')
  98. const scSeq = ref(0)
  99. const drillOptions = ref([])
  100. const drillLoading = ref(false)
  101. const scData = reactive({
  102. scForm: {
  103. drGuid: undefined,
  104. basicId: undefined,
  105. orgGuid: undefined,
  106. scTime: undefined,
  107. spotCheck: undefined,
  108. scExplain: undefined
  109. },
  110. scRules: {
  111. orgGuid: [{ required: true, message: "抽查单位不能为空", trigger: "change" }],
  112. scTime: [{ required: true, message: "抽查时间不能为空", trigger: "change" }],
  113. spotCheck: [{ required: true, message: "抽查结果不能为空", trigger: "change" }],
  114. scExplain: [{ required: true, message: "抽查结果说明不能为空", trigger: "blur" }]
  115. }
  116. })
  117. const { scForm, scRules } = toRefs(scData)
  118. /** 抽查结果选项:合格 / 打回整改(不含“未抽查”) */
  119. const scResultOptions = computed(() =>
  120. (eme_drill_sc_status.value || []).filter(dict => dict.value !== '0')
  121. )
  122. function openLoad() {
  123. const row = props.row || {}
  124. scSeq.value++
  125. scForm.value = {
  126. drGuid: row.drGuid,
  127. basicId: row.basicId,
  128. orgGuid: userStore.orgGuid || '',
  129. scTime: parseTime(new Date(), '{y}-{m}-{d}'),
  130. spotCheck: undefined,
  131. scExplain: undefined
  132. }
  133. // 新增抽查:先加载未抽查的演练记录供选择
  134. if (!row.drGuid) {
  135. scDrGuid.value = ''
  136. loadDrillOptions('')
  137. return
  138. }
  139. scDrGuid.value = row.drGuid
  140. // 已抽查过的记录回显
  141. scLoading.value = true
  142. getDrillSc(row.drGuid).then(r => {
  143. const d = r.data || {}
  144. if (d.ccGuid) {
  145. scForm.value.scTime = d.scTime || scForm.value.scTime
  146. scForm.value.spotCheck = d.spotCheck
  147. scForm.value.scExplain = d.scExplain
  148. }
  149. }).finally(() => {
  150. scLoading.value = false
  151. })
  152. }
  153. /** 加载未抽查的演练实施记录(新增抽查选择器) */
  154. function loadDrillOptions(query) {
  155. drillLoading.value = true
  156. listDrillSc({
  157. pageNum: 1,
  158. pageSize: 20,
  159. spotCheck: '0',
  160. drillName: query || undefined
  161. }).then(res => {
  162. drillOptions.value = res.rows || []
  163. }).finally(() => {
  164. drillLoading.value = false
  165. })
  166. }
  167. function searchDrillRecords(query) {
  168. loadDrillOptions(query)
  169. }
  170. function handleDrillSelected(val) {
  171. if (!val) {
  172. scDrGuid.value = ''
  173. return
  174. }
  175. scDrGuid.value = val
  176. scSeq.value++
  177. }
  178. watch(() => props.modelValue, (val) => {
  179. if (val) openLoad()
  180. })
  181. function submitScForm() {
  182. if (!scForm.value.drGuid) {
  183. proxy.$modal.msgWarning('请先选择演练记录')
  184. return
  185. }
  186. proxy.$refs["scFormRef"].validate(valid => {
  187. if (!valid) return
  188. saveDrillSc(scForm.value).then(() => {
  189. proxy.$modal.msgSuccess("操作成功")
  190. dialogVisible.value = false
  191. emit('saved')
  192. })
  193. })
  194. }
  195. </script>