dialog.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <script setup lang="ts">
  2. import { reactive, ref } from "vue";
  3. import { getStationDetail, addStation, modifyStation } from "@/api/station";
  4. import { ElMessage } from "element-plus";
  5. const emit = defineEmits(["refresh"]);
  6. const formRef = ref();
  7. const dialogVisible = ref(false);
  8. const dialogType = ref<"add" | "edit" | "view">("add");
  9. const loading = ref(false);
  10. const state = reactive({
  11. ruleForm: {
  12. id: null as number | null,
  13. stationId: "",
  14. stationName: "",
  15. address: "",
  16. stationStatus: "1",
  17. stationType: "1",
  18. parkingFee: "",
  19. parkingQrCode: "",
  20. parkingCouponMinAmount: 6.0,
  21. remark: "",
  22. pictures: [] as string[],
  23. stationLng: "",
  24. stationLat: ""
  25. },
  26. rules: {
  27. stationName: [{ required: true, message: "请输入站点名称", trigger: "blur" }],
  28. address: [{ required: true, message: "请输入站点地址", trigger: "blur" }]
  29. }
  30. });
  31. const resetForm = () => {
  32. state.ruleForm = {
  33. id: null,
  34. stationId: "",
  35. stationName: "",
  36. address: "",
  37. stationStatus: "1",
  38. stationType: "1",
  39. parkingFee: "",
  40. parkingQrCode: "",
  41. parkingCouponMinAmount: 6.0,
  42. remark: "",
  43. pictures: [],
  44. stationLng: "",
  45. stationLat: ""
  46. };
  47. formRef.value?.resetFields();
  48. };
  49. const open = async (type: "add" | "edit" | "view", row?: any) => {
  50. dialogType.value = type;
  51. resetForm();
  52. if (type !== "add" && row) {
  53. loading.value = true;
  54. try {
  55. const res = await getStationDetail(row.id);
  56. Object.assign(state.ruleForm, res);
  57. state.ruleForm.parkingCouponMinAmount = (res.parkingCouponMinAmount || 600) / 100;
  58. } catch (e) {
  59. ElMessage.error("加载站点详情失败");
  60. } finally {
  61. loading.value = false;
  62. }
  63. }
  64. dialogVisible.value = true;
  65. };
  66. const handleClose = () => {
  67. dialogVisible.value = false;
  68. resetForm();
  69. };
  70. const handleSubmit = async () => {
  71. const valid = await formRef.value?.validate().catch(() => false);
  72. if (!valid) return;
  73. loading.value = true;
  74. try {
  75. const payload = {
  76. ...state.ruleForm,
  77. parkingCouponMinAmount: Math.round(state.ruleForm.parkingCouponMinAmount * 100)
  78. };
  79. if (dialogType.value === "add") {
  80. await addStation(payload);
  81. ElMessage.success("新增成功");
  82. } else {
  83. await modifyStation(payload);
  84. ElMessage.success("修改成功");
  85. }
  86. handleClose();
  87. emit("refresh");
  88. } catch (e) {
  89. ElMessage.error("操作失败");
  90. } finally {
  91. loading.value = false;
  92. }
  93. };
  94. const isView = () => dialogType.value === "view";
  95. const getTitle = () => {
  96. const map = { add: "新增站点", edit: "编辑站点", view: "站点详情" };
  97. return map[dialogType.value];
  98. };
  99. defineExpose({ open });
  100. </script>
  101. <template>
  102. <el-dialog
  103. v-model="dialogVisible"
  104. :title="getTitle()"
  105. width="700px"
  106. :close-on-click-modal="false"
  107. destroy-on-close
  108. >
  109. <el-form
  110. ref="formRef"
  111. :model="state.ruleForm"
  112. :rules="state.rules"
  113. label-width="120px"
  114. :disabled="isView()"
  115. >
  116. <el-form-item label="站点ID" prop="stationId">
  117. <el-input v-model="state.ruleForm.stationId" placeholder="请输入站点ID" />
  118. </el-form-item>
  119. <el-form-item label="站点名称" prop="stationName">
  120. <el-input v-model="state.ruleForm.stationName" placeholder="请输入站点名称" />
  121. </el-form-item>
  122. <el-form-item label="站点地址" prop="address">
  123. <el-input v-model="state.ruleForm.address" placeholder="请输入站点地址" />
  124. </el-form-item>
  125. <el-form-item label="站点状态" prop="stationStatus">
  126. <ext-d-select v-model="state.ruleForm.stationStatus" type="Station.status" placeholder="请选择站点状态" />
  127. </el-form-item>
  128. <el-form-item label="站点类型" prop="stationType">
  129. <ext-d-select v-model="state.ruleForm.stationType" type="Station.type" placeholder="请选择站点类型" />
  130. </el-form-item>
  131. <el-form-item label="停车券最低消费金额(元)" prop="parkingCouponMinAmount">
  132. <el-input-number v-model="state.ruleForm.parkingCouponMinAmount" :min="0" :precision="2" placeholder="默认6元" />
  133. </el-form-item>
  134. <el-form-item label="停车减免规则" prop="parkingFee">
  135. <el-input
  136. v-model="state.ruleForm.parkingFee"
  137. type="textarea"
  138. :rows="2"
  139. placeholder="洗车费用满10元减免1小时停车费"
  140. />
  141. </el-form-item>
  142. <el-form-item label="停车二维码文本" prop="parkingQrCode">
  143. <el-input
  144. v-model="state.ruleForm.parkingQrCode"
  145. type="textarea"
  146. :rows="2"
  147. placeholder="停车费减免二维码文本"
  148. />
  149. </el-form-item>
  150. <el-form-item label="备注" prop="remark">
  151. <el-input
  152. v-model="state.ruleForm.remark"
  153. type="textarea"
  154. :rows="2"
  155. placeholder="请输入备注"
  156. />
  157. </el-form-item>
  158. </el-form>
  159. <template #footer>
  160. <span class="dialog-footer">
  161. <el-button @click="handleClose">取消</el-button>
  162. <el-button v-if="!isView()" :loading="loading" type="primary" @click="handleSubmit">
  163. 确定
  164. </el-button>
  165. </span>
  166. </template>
  167. </el-dialog>
  168. </template>
  169. <style scoped lang="scss">
  170. .el-select {
  171. width: 100%;
  172. }
  173. </style>