detail.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <template>
  2. <div class="modal">
  3. <el-dialog
  4. v-model="dialogVisible"
  5. :title="dialogTitle"
  6. :width="modalConfig.dialogWidth || '80%'"
  7. center
  8. @close="handleExcel(ruleFormRef)"
  9. :close-on-click-modal="false"
  10. >
  11. <template #header>
  12. <pageTitle :title="dialogTitle"></pageTitle>
  13. </template>
  14. <div class="form">
  15. <el-form
  16. ref="ruleFormRef"
  17. :rules="modalConfig.formRules"
  18. label-suffix=":"
  19. :model="formData"
  20. :label-width="modalConfig.labelWidth || '100px'"
  21. size="large"
  22. >
  23. <el-row :gutter="12">
  24. <template v-for="item in modalConfig.formItems" :key="item.prop">
  25. <el-col :span="item.span || 8">
  26. <el-form-item :label="item.label" :prop="item.prop">
  27. <template v-if="item.type === 'input'">
  28. <el-input
  29. :disabled="item.disabled"
  30. v-model="formData[item.prop]"
  31. :placeholder="item.placeholder"
  32. />
  33. </template>
  34. <template v-if="item.type === 'number'">
  35. <el-input
  36. v-model="formData[item.prop]"
  37. type="number"
  38. :min="0"
  39. :max="999999999999"
  40. :disabled="item.disabled"
  41. :placeholder="item.placeholder"
  42. />
  43. </template>
  44. <template v-if="item.type === 'select'">
  45. <el-select
  46. v-model="formData[item.prop]"
  47. :placeholder="item.placeholder"
  48. style="width: 100%"
  49. :disabled="item.disabled"
  50. >
  51. <template v-for="(val, index) in item.options" :key="index">
  52. <el-option :value="val.value" :label="val.label" />
  53. </template>
  54. </el-select>
  55. </template>
  56. <template v-if="item.type === 'date-picker'">
  57. <el-date-picker
  58. :type="item.dateType || 'daterange'"
  59. range-separator="-"
  60. start-placeholder="开始时间"
  61. end-placeholder="结束时间"
  62. v-model="formData[item.prop]"
  63. :disabled="item.disabled"
  64. />
  65. </template>
  66. <template v-if="item.type === 'date'">
  67. <el-date-picker
  68. type="date"
  69. :placeholder="item.placeholder"
  70. style="width: 100%"
  71. v-model="formData[item.prop]"
  72. :disabled="item.disabled"
  73. />
  74. </template>
  75. <template v-if="item.type === 'textMessage'">
  76. <el-radio-group :disabled="item.disabled" v-model="formData[item.prop]">
  77. <el-radio value="y">是</el-radio>
  78. <el-radio value="n">否</el-radio>
  79. </el-radio-group>
  80. </template>
  81. <template v-if="item.type === 'userName'">
  82. <el-select
  83. :disabled="item.disabled"
  84. v-model="formData[item.prop]"
  85. multiple
  86. filterable
  87. remote
  88. reserve-keyword
  89. :placeholder="item.placeholder"
  90. :remote-method="remoteuserNameMethod"
  91. :loading="userLoading"
  92. style="width: 100%"
  93. >
  94. <el-option
  95. v-for="item in options"
  96. :key="item.value"
  97. :label="item.label"
  98. :value="item.value"
  99. />
  100. </el-select>
  101. </template>
  102. </el-form-item>
  103. </el-col>
  104. </template>
  105. </el-row>
  106. </el-form>
  107. </div>
  108. <template #footer>
  109. <span class="dialog-footer">
  110. <el-button @click="handleExcel(ruleFormRef)">返回</el-button>
  111. <el-button type="primary" v-show="dialogLook == false" @click="handleConfirmClick(ruleFormRef)"
  112. >确定</el-button
  113. >
  114. <slot name="button"></slot>
  115. </span>
  116. </template>
  117. </el-dialog>
  118. </div>
  119. </template>
  120. <script setup lang="ts" name="modal">
  121. import { reactive, ref } from 'vue';
  122. import type { FormInstance } from 'element-plus';
  123. import useSystemStore from '@/store/main';
  124. // 定义props
  125. interface IProps {
  126. modalConfig: {
  127. pageName: string;
  128. addTitle: string;
  129. editTitle: string;
  130. detailTitle: string;
  131. dialogWidth: string;
  132. labelWidth: string;
  133. formItems: any[];
  134. formRules: object;
  135. pageListParams?: object; //新增一个对象,用来传给特殊的列表接口刷新页面(非必传)
  136. };
  137. otherInfo?: any;
  138. }
  139. const props = defineProps<IProps>();
  140. const dialogVisible = ref(false);
  141. const isEdit = ref(false);
  142. const ruleFormRef = ref<FormInstance>();
  143. const systemStore = useSystemStore();
  144. const { pageDetailInfo, pageOperateType } = storeToRefs(systemStore);
  145. interface userNameListItem {
  146. value: string;
  147. label: string;
  148. }
  149. const options = ref<userNameListItem[]>([]);
  150. const userLoading = ref(false);
  151. const remoteuserNameMethod = (query: string) => {
  152. if (query) {
  153. // userLoading.value = true;
  154. } else {
  155. options.value = [];
  156. }
  157. };
  158. onMounted(async () => {});
  159. // 定义数据绑定
  160. const initialForm: any = {};
  161. for (const item of props.modalConfig.formItems) {
  162. initialForm[item.prop] = item.initialValue ?? '';
  163. }
  164. let formData = ref(JSON.parse(JSON.stringify(initialForm)));
  165. const dialogTitle = ref();
  166. const dialogLook = ref(false);
  167. // 新建或者编辑
  168. async function setDialogVisible(isNew: boolean = true, check: boolean = false) {
  169. dialogVisible.value = true;
  170. ruleFormRef.value?.resetFields();
  171. await nextTick();
  172. dialogLook.value = false;
  173. if (!isNew) {
  174. watch(pageDetailInfo, newVal => {
  175. formData.value = pageDetailInfo.value;
  176. });
  177. if (check) {
  178. dialogTitle.value = props.modalConfig.detailTitle;
  179. dialogLook.value = true;
  180. systemStore.getDetailType('detail');
  181. } else {
  182. dialogTitle.value = props.modalConfig.editTitle;
  183. systemStore.getDetailType('edit');
  184. }
  185. } else {
  186. props.modalConfig.formItems.map((m: any) => {
  187. if (m.numberType === '2') {
  188. if (m.prop === initialForm[m.prop]) {
  189. initialForm[m.prop] = (0.0).toFixed(2);
  190. }
  191. } else if (m.numberType === '1') {
  192. if (m.porp === initialForm[m.porp]) {
  193. initialForm[m.prop] = Math.trunc(0);
  194. }
  195. }
  196. });
  197. formData.value = JSON.parse(JSON.stringify(initialForm));
  198. await nextTick();
  199. dialogTitle.value = props.modalConfig.addTitle;
  200. systemStore.detailPageEval(initialForm);
  201. systemStore.getDetailType('add');
  202. }
  203. isEdit.value = !isNew;
  204. }
  205. // 点击确定
  206. function handleConfirmClick(formEl: FormInstance | undefined) {
  207. if (!formEl) return;
  208. formEl.validate((valid, fields) => {
  209. if (valid) {
  210. dialogVisible.value = false;
  211. let data = { ...formData.value };
  212. if (props.otherInfo) {
  213. data = { ...data, ...props.otherInfo };
  214. }
  215. if (!isEdit.value) {
  216. systemStore.newPageDataAction(props.modalConfig.pageName, data, props.modalConfig.pageListParams);
  217. } else {
  218. if (pageOperateType.value === 'edit') {
  219. systemStore.editPageDataAction(props.modalConfig.pageName, data, props.modalConfig.pageListParams);
  220. }
  221. }
  222. } else {
  223. console.log('error submit!', fields);
  224. }
  225. });
  226. }
  227. // 取消
  228. function handleExcel(formEl: FormInstance | undefined) {
  229. dialogVisible.value = false;
  230. if (!formEl) return;
  231. formEl.resetFields();
  232. }
  233. // 获取详情
  234. function onPageDetail(urlId: number | [] | string) {
  235. systemStore.detailPageDataAction(props.modalConfig.pageName, urlId);
  236. }
  237. defineExpose({
  238. setDialogVisible,
  239. onPageDetail,
  240. });
  241. </script>
  242. <style scoped lang="scss">
  243. .form {
  244. padding: 10px 30px;
  245. }
  246. </style>