index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <script setup>
  2. import { CirclePlus } from '@element-plus/icons-vue'
  3. import { getWorkFlowList, getAllWaterFactoryList, getPositionList, getAssayList, putWorkFlow, postWorkFlow, delWorkFlow } from '@/api/configuration'
  4. import { getAllDeviceList} from '@/api/client/manage'
  5. const { proxy } = getCurrentInstance();
  6. const queryParams = ref({
  7. pageNum: 1,
  8. pageSize: 10,
  9. });
  10. const total = ref(0);
  11. const loading = ref(false);
  12. const tableData = ref([]);
  13. const waterFactoryOptions = ref([]);
  14. const deviceOptions = ref([]);
  15. const pointOptions = ref([]);
  16. const assayOptions = ref([]);
  17. const formData = ref({});
  18. const formRef = ref(null);
  19. const dialogVisible = ref(false);
  20. const rules = {
  21. name: { required: true, message: '请输入化验流程名称', trigger: 'blur' },
  22. organizationId: { required: true, message: '请选择所属水厂', trigger: 'blur' },
  23. code: { required: true, message: '请输入化验流程编号', trigger: 'blur' },
  24. deviceId: { required: true, message: '请选择所属设备', trigger: 'blur' },
  25. totalSteps: { required: true, message: '化验总步数', trigger: 'blur' },
  26. items: { type: 'array', required: true, message: '请添加化验内容', trigger: 'blur' }
  27. }
  28. const initPageData = async () => {
  29. loading.value = true;
  30. const { total: tableTotal, rows } = await getWorkFlowList(queryParams.value);
  31. tableData.value = rows.map(val => ({
  32. ...val,
  33. items: val.items.map(item => ({
  34. ...item,
  35. itemId: item.id,
  36. itemName: item.assayItem?.name,
  37. positionId: item.position?.id,
  38. positionName: item.position?.name,
  39. workflowId: val.id
  40. }))
  41. }));
  42. total.value = tableTotal;
  43. loading.value = false;
  44. }
  45. // 查询
  46. const handleQuery = async() => {
  47. initPageData();
  48. }
  49. // 重置
  50. const handleReset = () => {
  51. queryParams.value = {
  52. pageNum: 1,
  53. pageSize: 10
  54. }
  55. initPageData();
  56. }
  57. // 编辑流程
  58. const handleTableEdit = (row) => {
  59. formData.value = { ...row };
  60. dialogVisible.value = true;
  61. }
  62. // Dialog - 新增 or 修改 化验流程
  63. const handleDialogConfirm = async () => {
  64. if (!formRef.value) return
  65. await formRef.value.validate(async(valid, fields) => {
  66. if (valid) {
  67. formData.value.id ? await putWorkFlow(formData.value) : await postWorkFlow(formData.value);
  68. formRef.value.resetFields();
  69. dialogVisible.value = false;
  70. proxy.$modal.msgSuccess("操作成功");
  71. initPageData();
  72. } else {
  73. console.log('error submit!', fields)
  74. }
  75. })
  76. }
  77. // Dialog - 重置表单
  78. const handleDialogReset = () => {
  79. formData.value = {};
  80. formRef.value.resetFields();
  81. }
  82. // Dialog - 新增行
  83. const handleAddRow = () => {
  84. const { itemId, positionId, id: workflowId } = formData.value;
  85. if ( !itemId ) {
  86. return proxy.$modal.msgError("请先选择化验项目");
  87. }
  88. if ( !positionId ) {
  89. return proxy.$modal.msgError("请先选择取样点位");
  90. }
  91. formRef.value.validate("items");
  92. const params = {
  93. itemId,
  94. itemName: assayOptions.value.find(({ id }) => id === itemId).name,
  95. positionId,
  96. positionName: pointOptions.value.find(({ id }) => id === positionId).name,
  97. workflowId
  98. }
  99. if ( !formData.value.items?.length ) formData.value.items = [];
  100. formData.value.items.push(params);
  101. }
  102. // Table - 删除
  103. const handleDelete = async ({ id }) => {
  104. await delWorkFlow(id);
  105. proxy.$modal.msgSuccess("删除成功");
  106. initPageData();
  107. }
  108. // Tag - 删除行
  109. const handleCloseTag = (index) => {
  110. formData.value.items.splice(index, 1);
  111. }
  112. onMounted(async () => {
  113. // 水厂
  114. getAllWaterFactoryList().then(({ data }) => waterFactoryOptions.value = data)
  115. // 设备
  116. getAllDeviceList().then(({ data }) => deviceOptions.value = data)
  117. // 化验项目
  118. getAssayList({ pageNum: 1, pageSize: 9999 }).then(({ rows }) => assayOptions.value = rows)
  119. // 点位
  120. getPositionList({ pageNum: 1, pageSize: 10000 }).then(({ rows }) => pointOptions.value = rows)
  121. // 初始化数据
  122. initPageData();
  123. })
  124. </script>
  125. <template>
  126. <section>
  127. <el-card shadow="never" :body-style="{ border: '0px' }" style="margin-bottom: 10px;">
  128. <template #header>
  129. <p class="space-x-[10px]">
  130. <span class="font-bold">数据筛选</span>
  131. </p>
  132. </template>
  133. <el-row class="pt-[5px]" justify="space-between" :gutter="20">
  134. <el-col :span="6">
  135. <el-form-item label="水厂名称">
  136. <el-select v-model="queryParams.organizationId" placeholder="请选择水厂名称" filterable clearable>
  137. <el-option v-for="item in waterFactoryOptions" :key="item.id" :label="item.name" :value="item.id" />
  138. </el-select>
  139. </el-form-item>
  140. </el-col>
  141. <el-col :span="6">
  142. <el-form-item label="设备SN / 名称">
  143. <el-select v-model="queryParams.deviceId" placeholder="请选择设备SN" filterable clearable>
  144. <el-option v-for="item in deviceOptions" :key="item.deviceId" :label="(item.deviceSn ? item.deviceSn + '-' : '') + item.deviceName || ''" :value="item.deviceId" />
  145. </el-select>
  146. </el-form-item>
  147. </el-col>
  148. <el-col :span="6">
  149. <el-form-item label="化验流程名称">
  150. <el-input v-model.trim="queryParams.name" placeholder="请输入化验流程名称" clearable />
  151. </el-form-item>
  152. </el-col>
  153. <el-col :span="6">
  154. <el-form-item label="化验流程编号">
  155. <el-input v-model.trim="queryParams.code" placeholder="请输入化验流程编号" clearable />
  156. </el-form-item>
  157. </el-col>
  158. <el-col :span="6" :offset="18">
  159. <div class="flex justify-end">
  160. <el-button type="primary" @click="handleQuery" :loading="loading">查询</el-button>
  161. <el-button @click="handleReset" :loading="loading">重置</el-button>
  162. </div>
  163. </el-col>
  164. </el-row>
  165. </el-card>
  166. <el-card shadow="never" :body-style="{ padding: '20px' }">
  167. <div class="flex justify-between items-center mb-[10px]">
  168. <el-button type="primary" @click="dialogVisible = true" :loading="loading" :icon="CirclePlus">新增化验流程</el-button>
  169. </div>
  170. <el-table :data="tableData" style="width: 100%" v-loading="loading" row-key="id">
  171. <el-table-column prop="code" label="化验流程编号" width="180" fixed/>
  172. <el-table-column prop="name" label="化验流程名称" width="180" />
  173. <el-table-column prop="organization.name" label="所属水厂名称" width="180"/>
  174. <el-table-column prop="bizDevice.deviceSn" label="所属设备SN" width="180"/>
  175. <el-table-column prop="bizDevice.deviceName" label="所属设备名称" width="180"/>
  176. <el-table-column prop="xxxxxxxx" label="化验项目" width="400" show-overflow-tooltip>
  177. <template #default="{row}">
  178. <div class="space-x-[4px]">
  179. <el-tag v-for="item in row.items" :key="item.id">{{item?.assayItem?.name}}({{ item?.position?.name }})</el-tag>
  180. </div>
  181. </template>
  182. </el-table-column>
  183. <el-table-column prop="totalSteps" label="化验总步数" width="180"/>
  184. <el-table-column prop="createUser.nickName" label="创建人" width="180"/>
  185. <el-table-column prop="createTime" label="创建时间" width="180"/>
  186. <el-table-column prop="address" label="操作" fixed="right" width="100">
  187. <template #default="{ row }">
  188. <el-button link type="primary" size="small" @click="handleTableEdit(row)">编辑</el-button>
  189. <el-popconfirm title="请确认是否删除?" @confirm="handleDelete(row)" width="200">
  190. <template #reference>
  191. <el-button link type="primary" size="small">删除</el-button>
  192. </template>
  193. </el-popconfirm>
  194. </template>
  195. </el-table-column>
  196. </el-table>
  197. <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
  198. v-model:limit="queryParams.pageSize" @pagination="initPageData" />
  199. </el-card>
  200. <el-dialog v-model="dialogVisible" :title="formData.id ? '编辑化验流程' : '新增化验流程'" width="900" @closed="handleDialogReset">
  201. <el-form :model="formData" :rules="rules" ref="formRef" label-width="110px" label-position="left" require-asterisk-position="right">
  202. <el-row justify="space-between">
  203. <el-col :span="11">
  204. <el-form-item label="化验流程名称" prop="name">
  205. <el-input v-model.trim="formData.name" placeholder="请输入流程名称" clearable />
  206. </el-form-item>
  207. </el-col>
  208. <el-col :span="11">
  209. <el-form-item label="所属水厂" prop="organizationId">
  210. <el-select v-model="formData.organizationId" placeholder="请选择所属水厂" filterable clearable>
  211. <el-option v-for="item in waterFactoryOptions" :key="item.id" :label="item.name" :value="item.id" />
  212. </el-select>
  213. </el-form-item>
  214. </el-col>
  215. <el-col :span="11">
  216. <el-form-item label="化验流程编号" prop="code">
  217. <el-input v-model.trim="formData.code" placeholder="请输入化验流程编号" clearable />
  218. </el-form-item>
  219. </el-col>
  220. <el-col :span="11">
  221. <el-form-item label="所属设备" prop="deviceId">
  222. <el-select v-model="formData.deviceId" placeholder="请选所属设备" filterable clearable>
  223. <el-option v-for="item in deviceOptions" :key="item.deviceId" :label="item.deviceName" :value="item.deviceId" />
  224. </el-select>
  225. </el-form-item>
  226. </el-col>
  227. <el-col :span="11">
  228. <el-form-item label="化验总步数" prop="totalSteps">
  229. <el-input v-model.trim="formData.totalSteps" placeholder="请输入总步数" clearable />
  230. </el-form-item>
  231. </el-col>
  232. </el-row>
  233. <el-divider border-style="dashed" />
  234. <el-form-item label="化验内容" prop="items">
  235. <el-row class="w-full" :gutter="20">
  236. <el-col :span="8">
  237. <el-select v-model="formData.itemId" placeholder="请选择化验项目" filterable clearable>
  238. <el-option v-for="item in assayOptions" :key="item.id" :label="item.name" :value="item.id" />
  239. </el-select>
  240. </el-col>
  241. <el-col :span="8">
  242. <el-select v-model="formData.positionId" placeholder="请选择取样点位" filterable clearable>
  243. <el-option v-for="item in pointOptions" :key="item.id" :label="item.name" :value="item.id" />
  244. </el-select>
  245. </el-col>
  246. <el-col :span="8">
  247. <el-button type="primary" @click="handleAddRow(row)">添加</el-button>
  248. </el-col>
  249. </el-row>
  250. <div class="w-full min-h-[100px] px-[10px] py-[10px] mt-[30px] bg-[#f3f5f9] space-x-[10px]">
  251. <el-tag v-for="item, index in formData.items" :key="index" closable type="primary" @close="handleCloseTag(index)">
  252. <span>{{ item.itemName }}({{ item.positionName }})</span>
  253. </el-tag>
  254. </div>
  255. </el-form-item>
  256. </el-form>
  257. <template #footer>
  258. <div class="dialog-footer">
  259. <el-button @click="dialogVisible = false" >取 消</el-button>
  260. <el-button @click="handleDialogConfirm" type="primary">确 定</el-button>
  261. </div>
  262. </template>
  263. </el-dialog>
  264. </section>
  265. </template>
  266. <style lang="scss" scoped>
  267. </style>