dialog.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <style scoped lang="scss">
  2. </style>
  3. <template>
  4. <div class="system-dialog-container">
  5. <el-dialog
  6. :title="state.dialog.title"
  7. v-model="state.dialog.isShowDialog"
  8. width="600px"
  9. draggable
  10. destroy-on-close
  11. :close-on-click-modal="false"
  12. align-center
  13. @open="onDialogOpen">
  14. <el-form
  15. inline
  16. :model="state.ruleForm"
  17. :rules="state.rules"
  18. label-position="top"
  19. ref="formRef"
  20. size="default"
  21. label-width="130px"
  22. class="mt5">
  23. <el-form-item label="设备名称" prop="deviceName" class="wd350">
  24. <el-input
  25. v-model="state.ruleForm.deviceName"
  26. placeholder="设备名称"
  27. clearable
  28. class="wd200">
  29. </el-input>
  30. </el-form-item>
  31. <el-form-item label="工位序号" prop="sequence" class="wd350">
  32. <el-input-number
  33. v-model="state.ruleForm.sequence"
  34. placeholder="工位序号"
  35. :min="1"
  36. class="wd200">
  37. </el-input-number>
  38. </el-form-item>
  39. <el-form-item label="所在网点" prop="stationId" class="wd350">
  40. <ext-select
  41. class="wd200"
  42. v-model="state.ruleForm.stationId"
  43. placeholder="所在网点"
  44. url="washStation/list"
  45. label-key="stationName"
  46. value-key="stationId">
  47. </ext-select>
  48. </el-form-item>
  49. <el-form-item label="网点ID" prop="stationId" class="wd350">
  50. <el-input
  51. v-model="state.ruleForm.stationId"
  52. placeholder="网点ID"
  53. clearable
  54. readonly
  55. class="w100">
  56. </el-input>
  57. </el-form-item>
  58. <el-form-item label="状态" prop="state" class="wd350">
  59. <el-select v-model="state.ruleForm.state" clearable placeholder="请选择" class="wd200">
  60. <el-option v-for="item in getStatusOptions()" :key="item.value" :label="item.name" :value="item.value" />
  61. </el-select>
  62. </el-form-item>
  63. <el-form-item label="是否有泡沫" prop="hasFoam" class="wd250">
  64. <el-switch v-model="state.ruleForm.hasFoam" active-text="有" inactive-text="无" />
  65. </el-form-item>
  66. <el-form-item label="是否有水" prop="hasWater" class="wd250">
  67. <el-switch v-model="state.ruleForm.hasWater" active-text="有" inactive-text="无" />
  68. </el-form-item>
  69. <el-form-item label="是否支持PA" prop="hasPa" class="wd250">
  70. <el-switch v-model="state.ruleForm.hasPa" active-text="是" inactive-text="否" />
  71. </el-form-item>
  72. <el-form-item label="板载温度" prop="temperatureChip" class="wd350">
  73. <el-input
  74. v-model="state.ruleForm.temperatureChip"
  75. placeholder="板载温度传感器的温度值"
  76. clearable
  77. class="w100">
  78. </el-input>
  79. </el-form-item>
  80. <el-form-item label="故障原因" prop="faultReason" class="w100">
  81. <el-input
  82. v-model="state.ruleForm.faultReason"
  83. placeholder="故障原因"
  84. clearable
  85. type="textarea"
  86. class="w100">
  87. </el-input>
  88. </el-form-item>
  89. <!-- <el-form-item label="设备主状态机的当前状态(状态可能增加或减少,仅供调试参考。)" prop="fsmState" class="wd350">
  90. <el-input
  91. v-model="state.ruleForm.fsmState"
  92. placeholder="设备主状态机的当前状态(状态可能增加或减少,仅供调试参考。)"
  93. clearable
  94. class="w100">
  95. </el-input>
  96. </el-form-item>-->
  97. <el-form-item label="功能" prop="functions" class="w100">
  98. <el-input
  99. v-model="state.ruleForm.functions"
  100. placeholder="功能"
  101. clearable
  102. class="w100">
  103. </el-input>
  104. </el-form-item>
  105. </el-form>
  106. <template #footer>
  107. <span class="dialog-footer">
  108. <el-button @click="onCancel" size="default">取 消</el-button>
  109. <el-button :loading="state.btnLoading" type="primary" @click="onSubmit" size="default">{{ state.dialog.submitTxt }}</el-button>
  110. </span>
  111. </template>
  112. </el-dialog>
  113. </div>
  114. </template>
  115. <script setup lang="ts" name="WashDeviceDialog">
  116. import {defineAsyncComponent, reactive, ref} from 'vue';
  117. import {Msg} from "/@/utils/message";
  118. import {$body, $get} from "/@/utils/request";
  119. import u from '/@/utils/u'
  120. import {Session} from "/@/utils/storage";
  121. import ExtSelect from "/@/components/form/ExtSelect.vue";
  122. // 定义子组件向父组件传值/事件
  123. const emit = defineEmits(['refresh']);
  124. const formRef = ref();
  125. //定义初始变量,重置使用
  126. const initState = () => ({
  127. ruleForm: {
  128. id: null
  129. },
  130. btnLoading: false,
  131. dialog: {
  132. isShowDialog: false,
  133. type: '',
  134. title: '',
  135. submitTxt: '',
  136. },
  137. rules: {
  138. deviceName: [u.validator.required],
  139. },
  140. })
  141. // 定义变量内容
  142. const state = reactive(initState());
  143. // 状态字典选项,直接从 Session 读取,避免 ext-d-select 组件挂载时序问题
  144. const getStatusOptions = (): any[] => {
  145. const dicts = Session.get('dicts')
  146. return dicts?.['WashDevice.status'] || []
  147. }
  148. // 暂存打开参数,等弹窗动画完成后再加载
  149. let pendingAction = ''
  150. let pendingRow: any = null
  151. // 弹窗打开后(动画完成、DOM 就绪)加载数据
  152. const onDialogOpen = () => {
  153. if (pendingAction !== 'add' && pendingRow?.id) {
  154. loadData(pendingRow.id)
  155. } else if (pendingAction === 'add') {
  156. state.ruleForm = { id: null, ...pendingRow }
  157. }
  158. }
  159. // 打开弹窗
  160. const open = (action: string = 'add', row: any) => {
  161. pendingAction = action
  162. pendingRow = row
  163. state.dialog.title = u.dialog.actions[action].title + "『洗车设备』"
  164. state.dialog.submitTxt = u.dialog.actions[action].btn + "『洗车设备』"
  165. state.dialog.isShowDialog = true;
  166. };
  167. // 关闭弹窗
  168. const onClose = () => {
  169. state.dialog.isShowDialog = false;
  170. Object.assign(state, initState())
  171. };
  172. // 取消
  173. const onCancel = () => {
  174. onClose();
  175. };
  176. // 提交
  177. const onSubmit = () => {
  178. formRef.value.validate((v: boolean) => {
  179. if (v) {
  180. state.btnLoading = true;
  181. const url = !!state.ruleForm.id ? "washDevice/modify" : "washDevice/add"
  182. $body(url, state.ruleForm).then(() => {
  183. state.btnLoading = false;
  184. Msg.message('操作成功');
  185. //console.log('submit!')
  186. onClose();
  187. emit('refresh');
  188. })
  189. } else {
  190. state.btnLoading = false;
  191. Msg.message('请先完整填写表单', 'error');
  192. }
  193. })
  194. };
  195. const handleFormChange = (formData: any) => {
  196. //console.log(formData)
  197. }
  198. // 将后端 boolean 字段(int 0/1 或 string "0"/"1")转为前端 boolean
  199. const BOOL_FIELDS = ['hasFoam', 'hasWater', 'hasPa'] as const
  200. const normalizeBooleans = (data: Record<string, any>) => {
  201. BOOL_FIELDS.forEach((key) => {
  202. const v = data[key]
  203. if (v === undefined || v === null) return
  204. if (typeof v === 'boolean') return
  205. data[key] = typeof v === 'number' ? v !== 0 : v === '1' || v === 'true'
  206. })
  207. }
  208. // 初始化数据
  209. const loadData = (id: number) => {
  210. $get(`washDevice/detail/${id}`).then((res: any) => {
  211. normalizeBooleans(res)
  212. state.ruleForm = res
  213. })
  214. }
  215. // 暴露变量
  216. defineExpose({
  217. open
  218. });
  219. </script>