QueryForm.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <div>
  3. <el-form :model="queryForm" label-width="auto" :inline="true" ref="formRef">
  4. <div class="select-group">
  5. <el-form-item label="问题来源:" prop="source">
  6. <el-select
  7. v-model="queryForm.source"
  8. placeholder="全部"
  9. clearable
  10. @change="handleSelectChange"
  11. >
  12. <el-option
  13. v-for="item in sourceOptions"
  14. :key="item.value"
  15. :label="item.label"
  16. :value="item.value"
  17. />
  18. </el-select>
  19. </el-form-item>
  20. <el-form-item label="类型:" prop="issueType">
  21. <!-- <el-select
  22. v-model="queryForm.issueType"
  23. placeholder="全部"
  24. clearable
  25. :disabled="typeDisable"
  26. >
  27. <el-option v-for="item in options" :label="item.name" :value="item.id" />
  28. </el-select> -->
  29. <el-cascader
  30. v-model="issueTypeValue"
  31. :options="options"
  32. :props="issueMainTypeProp"
  33. :show-all-levels="false"
  34. clearable
  35. :disabled="typeDisable"
  36. @change="handleIssueMainTypeChange"
  37. />
  38. </el-form-item>
  39. <el-form-item label="地点:" prop="workspaceId">
  40. <el-cascader
  41. v-model="workLocation"
  42. :options="locationOptions"
  43. :props="location"
  44. clearable
  45. collapse-tags
  46. :show-all-levels="false"
  47. @change="handleCascaderChange"
  48. />
  49. </el-form-item>
  50. <el-form-item label="状态:" prop="issueState">
  51. <el-select v-model="tempState" clearable @change="handleIssueStateChange">
  52. <el-option
  53. v-for="item in issueStateOptions"
  54. :key="item.value"
  55. :label="item.label"
  56. :value="item.value"
  57. />
  58. </el-select>
  59. </el-form-item>
  60. <el-form-item label="日期:">
  61. <el-date-picker
  62. v-model="dateRange"
  63. type="daterange"
  64. range-separator="~"
  65. start-placeholder="开始时间"
  66. end-placeholder="结束时间"
  67. clearable
  68. unlink-panels
  69. value-format="YYYY-MM-DD HH:mm:ss"
  70. :default-time="defaultTime"
  71. @change="handleDateChange"
  72. />
  73. </el-form-item>
  74. </div>
  75. <div class="btn-group">
  76. <el-form-item>
  77. <el-button class="search-btn" type="primary" @click="handleSearch">查询</el-button>
  78. <el-button class="reset-btn" @click="handleReset">重置</el-button>
  79. <el-button class="reset-btn" @click="handleExport" v-if="!isShowTab">导出</el-button>
  80. </el-form-item>
  81. </div>
  82. </el-form>
  83. </div>
  84. </template>
  85. <script setup lang="ts">
  86. import type { FormInstance } from 'element-plus';
  87. import { computed, reactive, ref } from 'vue';
  88. import { sourceOptions, issueStateOptions } from './constant.question';
  89. interface Props {
  90. isShowTab: boolean; // true展示数据,false默认数据
  91. aiOptions: Array<any>;
  92. manualOptions: Array<any>;
  93. locationOptions: Array<any>;
  94. }
  95. const props = defineProps<Props>();
  96. const emits = defineEmits(['onSearch', 'onReset', 'onExport']);
  97. interface QueryModel {
  98. pageNumber: number;
  99. pageSize: number;
  100. source?: number; // 来源
  101. issueMainType?: number; // 一级类型
  102. issueType?: number; // 类型
  103. workspaceId?: number[]; // 地点=工位id
  104. issueState?: number[]; // 状态
  105. startTime?: string; // 开始时间(默认)
  106. endTime?: string; // 结束时间(默认)
  107. }
  108. const formRef = ref<FormInstance>();
  109. const queryForm = reactive<QueryModel>({
  110. pageNumber: 1,
  111. pageSize: 10,
  112. });
  113. type MainOption = {
  114. value: number;
  115. label: string;
  116. children: {
  117. value: number;
  118. label: string;
  119. }[];
  120. };
  121. const options = ref<MainOption[]>([]);
  122. const typeDisable = ref(true);
  123. const workLocation = ref([]); // 级联选择器,为二维数组(提取workspaceId)
  124. const location = { multiple: true }; // 级联选择器(打开多选)
  125. const tempState = ref(''); // 状态,字符串转number[]
  126. const dateRange = ref([]); // 时间段,拆分成startTime/endTime
  127. const defaultTime = ref<[Date, Date]>([
  128. new Date(2000, 1, 1, 0, 0, 0),
  129. new Date(2000, 2, 1, 23, 59, 59),
  130. ]);
  131. const issueTypeValue = ref([]); // 问题类型,级联选择器
  132. const issueMainTypeProp = computed(() => {
  133. if (props.isShowTab) return { expandTrigger: 'hover' as const, checkStrictly: false };
  134. else return { expandTrigger: 'hover' as const, checkStrictly: true };
  135. });
  136. const workShopIds = ref([]);
  137. const handleSearch = () => {
  138. emits('onSearch', queryForm);
  139. };
  140. const handleReset = () => {
  141. workShopIds.value = [];
  142. issueTypeValue.value = [];
  143. typeDisable.value = true;
  144. workLocation.value = [];
  145. tempState.value = '';
  146. dateRange.value = [];
  147. Reflect.deleteProperty(queryForm, 'startTime');
  148. Reflect.deleteProperty(queryForm, 'endTime');
  149. Reflect.deleteProperty(queryForm, 'issueMainType');
  150. formRef.value?.resetFields();
  151. emits('onReset', queryForm);
  152. };
  153. const handleExport = () => {
  154. emits('onExport', queryForm, workShopIds.value);
  155. };
  156. const handleSelectChange = () => {
  157. if (Number(queryForm.source) === 1) {
  158. typeDisable.value = false;
  159. options.value = props.aiOptions;
  160. } else if (Number(queryForm.source) === 2) {
  161. typeDisable.value = false;
  162. options.value = props.manualOptions;
  163. } else {
  164. typeDisable.value = true;
  165. options.value = [];
  166. queryForm.issueMainType = undefined;
  167. queryForm.issueType = undefined;
  168. }
  169. };
  170. const handleIssueMainTypeChange = () => {
  171. if (issueTypeValue.value) {
  172. queryForm.issueMainType = issueTypeValue.value[0];
  173. queryForm.issueType = issueTypeValue.value[1];
  174. } else {
  175. Reflect.deleteProperty(queryForm, 'issueMainType');
  176. Reflect.deleteProperty(queryForm, 'issueType');
  177. }
  178. };
  179. const handleCascaderChange = () => {
  180. const arr = [];
  181. workShopIds.value = [];
  182. workLocation.value.forEach((item) => {
  183. arr.push(item[1]);
  184. workShopIds.value.push(item[0]);
  185. });
  186. queryForm.workspaceId = arr;
  187. workShopIds.value = [...new Set(workShopIds.value)];
  188. };
  189. const handleIssueStateChange = () => {
  190. if (tempState.value) queryForm.issueState = JSON.parse(tempState.value);
  191. };
  192. const handleDateChange = () => {
  193. if (dateRange.value != null) {
  194. queryForm.startTime = dateRange.value[0];
  195. queryForm.endTime = dateRange.value[1];
  196. } else {
  197. Reflect.deleteProperty(queryForm, 'startTime');
  198. Reflect.deleteProperty(queryForm, 'endTime');
  199. }
  200. };
  201. </script>
  202. <style scoped lang="scss">
  203. .el-form {
  204. display: flex;
  205. justify-content: space-between;
  206. }
  207. :deep(.el-form--inline .el-form-item) {
  208. margin-right: 0;
  209. }
  210. :deep(.el-form-item__label) {
  211. padding: 0;
  212. }
  213. .select-group {
  214. flex: 1;
  215. }
  216. .btn-group {
  217. .search-btn {
  218. width: 65px;
  219. height: 32px;
  220. background: #1890ff;
  221. border-radius: 2px;
  222. }
  223. .reset-btn {
  224. width: 65px;
  225. height: 32px;
  226. border-radius: 2px;
  227. border: 1px solid #1890ff;
  228. color: #1890ff;
  229. }
  230. }
  231. .el-select {
  232. --el-select-width: 215px;
  233. }
  234. </style>