Form.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. <template>
  2. <Dialog v-model="dialogVisible" :title="dialogTitle" width="80%">
  3. <div>
  4. <a-table
  5. v-loading="formLoading"
  6. v-model:selectedKeys="selectedKeys"
  7. :bordered="{wrapper: true, cell: true}"
  8. :columns="tableColumns"
  9. :data="list"
  10. :row-selection="rowSelection"
  11. row-key="id"
  12. >
  13. <template #kqmc-filter="{ filterValue, setFilterValue, handleFilterConfirm, handleFilterReset}">
  14. <div class="custom-filter">
  15. <a-space direction="vertical">
  16. <a-input :model-value="filterValue[0]" @input="(value)=>setFilterValue([value])" />
  17. <div class="custom-filter-footer">
  18. <a-button type="primary" @click="handleFilterConfirm">搜索</a-button>
  19. <a-button @click="handleFilterReset">取消</a-button>
  20. </div>
  21. </a-space>
  22. </div>
  23. </template>
  24. <template #cfmc-filter="{ filterValue, setFilterValue, handleFilterConfirm, handleFilterReset}">
  25. <div class="custom-filter">
  26. <a-space direction="vertical">
  27. <a-input :model-value="filterValue[0]" @input="(value)=>setFilterValue([value])" />
  28. <div class="custom-filter-footer">
  29. <a-button type="primary" @click="handleFilterConfirm">搜索</a-button>
  30. <a-button @click="handleFilterReset">取消</a-button>
  31. </div>
  32. </a-space>
  33. </div>
  34. </template>
  35. <template #cflx="{record }">
  36. <dict-tag :type="DICT_TYPE.SYSTEM_CFLX" :value="record.cflx"/>
  37. </template>
  38. <template #cazt="{record }">
  39. <dict-tag :type="DICT_TYPE.SYSTEM_CAZT" :value="record.cazt"/>
  40. </template>
  41. <template #edit="{record }">
  42. <el-button size="small" type="danger" @click="backRow(record)">
  43. 退回
  44. </el-button>
  45. </template>
  46. </a-table>
  47. </div>
  48. <template #footer>
  49. <el-button
  50. v-if="formType=='select' || formType == 'back'" :disabled="formLoading"
  51. type="primary" @click="submitForm"> {{ formType == 'select' ? '确 定' : '批量退回' }}
  52. </el-button>
  53. <el-button @click="dialogVisible = false">取 消</el-button>
  54. </template>
  55. </Dialog>
  56. </template>
  57. <script lang="ts" setup>
  58. import {ref} from 'vue'
  59. import {DeliveryWarehouseSelectApi} from '@/api/DeliveryWarehouse/DeliveryWarehouseSelect'
  60. import {DICT_TYPE} from '@/utils/dict'
  61. import {TableColumnData, TableRowSelection} from "@arco-design/web-vue";
  62. import {YxcfEnum} from "@/enum/yxcfEnum";
  63. import {IconSearch} from "@arco-design/web-vue/es/icon";
  64. // 接口定义
  65. interface QueryParams {
  66. pageNo: number
  67. pageSize: number
  68. }
  69. interface TableRow {
  70. id: number | string
  71. kqmc: string // 库区名称
  72. camc: string // 仓廒名称
  73. cflx: string // 仓房类型
  74. cazt: string // 仓房状态
  75. sjcr: number // 设计仓容
  76. }
  77. // interface ListItem {
  78. // sheng: string // 省份
  79. // shi: string // 市区
  80. // xian: string // 县区
  81. // dwmc: string // 企业名称
  82. // kqmc: string // 库区名称
  83. // sjcrNum: string // 实际仓容数量
  84. // cfnum: string // 仓房数量
  85. // yxcfnum: string // 已选仓房数量
  86. // }
  87. // interface SubmitData extends ListItem{
  88. // ids: (number | string)[]
  89. // yxcf: number
  90. //
  91. // }
  92. // 组件配置
  93. defineOptions({name: 'DeliveryWarehouseSelectForm'})
  94. // 组件状态
  95. const dialogVisible = ref(false)
  96. const dialogTitle = ref('仓房列表')
  97. const formLoading = ref(false)
  98. const formType = ref('')
  99. // 查询参数
  100. const queryParams = ref<QueryParams>({
  101. pageNo: 1,
  102. pageSize: 10
  103. })
  104. // 表格数据
  105. const list = ref<TableRow[]>([])
  106. // 表格列
  107. const tableColumns = ref<TableColumnData[]>([
  108. {
  109. title: '库区名称',
  110. dataIndex: 'kqmc',
  111. align: 'center',
  112. filterable: {
  113. filter: (value, record) => record.kqmc.includes(value),
  114. slotName: 'kqmc-filter',
  115. icon: () => h(IconSearch)
  116. }
  117. },
  118. {
  119. title: '仓房名称',
  120. dataIndex: 'cfmc',
  121. align: 'center',
  122. filterable: {
  123. filter: (value, record) => record.cfmc.includes(value),
  124. slotName: 'cfmc-filter',
  125. icon: () => h(IconSearch)
  126. }
  127. },
  128. {
  129. title: '仓房类型',
  130. dataIndex: 'cflx',
  131. slotName: 'cflx',
  132. align: 'center'
  133. },
  134. {
  135. title: '仓房状态',
  136. dataIndex: 'cazt',
  137. slotName: 'cazt',
  138. align: 'center'
  139. },
  140. {
  141. title: '设计仓容(吨)',
  142. dataIndex: 'sjcr',
  143. align: 'center'
  144. }
  145. ])
  146. const tableColumnsTemp: TableColumnData[] = [
  147. {
  148. title: '库区名称',
  149. dataIndex: 'kqmc',
  150. align: 'center',
  151. filterable: {
  152. filter: (value, record) => record.kqmc.includes(value),
  153. slotName: 'kqmc-filter',
  154. icon: () => h(IconSearch)
  155. }
  156. },
  157. {
  158. title: '仓房名称',
  159. dataIndex: 'cfmc',
  160. align: 'center',
  161. filterable: {
  162. filter: (value, record) => record.cfmc.includes(value),
  163. slotName: 'cfmc-filter',
  164. icon: () => h(IconSearch)
  165. }
  166. },
  167. {
  168. title: '仓房类型',
  169. dataIndex: 'cflx',
  170. slotName: 'cflx',
  171. align: 'center'
  172. },
  173. {
  174. title: '仓房状态',
  175. dataIndex: 'cazt',
  176. slotName: 'cazt',
  177. align: 'center'
  178. },
  179. {
  180. title: '设计仓容(吨)',
  181. dataIndex: 'sjcr',
  182. align: 'center'
  183. }]
  184. // 表格选择
  185. const rowSelection = reactive<TableRowSelection>({
  186. type: 'checkbox',
  187. showCheckedAll: true,
  188. onlyCurrent: false,
  189. });
  190. const selectedKeys = ref<(string | number)[]>([])
  191. /**
  192. * 打开弹窗
  193. */
  194. const open = async (type: string, row?: any) => {
  195. dialogVisible.value = true
  196. formType.value = type;
  197. selectedKeys.value = []
  198. if (formType.value == 'look') {
  199. rowSelection.type = undefined
  200. }
  201. if (row.yxcf == YxcfEnum.RdjskBank) {
  202. tableColumns.value = [...tableColumnsTemp,
  203. {
  204. title: '认定银行',
  205. dataIndex: 'rdyhName',
  206. slotName: 'rdyhName',
  207. align: 'center'
  208. }
  209. ]
  210. } else if (row.yxcf == YxcfEnum.XdjskCfxx) {
  211. tableColumns.value = [...tableColumnsTemp,
  212. {
  213. title: '认定银行',
  214. dataIndex: 'rdyhName',
  215. slotName: 'rdyhName',
  216. align: 'center'
  217. },
  218. {
  219. title: '选定单位名称',
  220. dataIndex: 'nickname',
  221. slotName: 'nickname',
  222. align: 'center'
  223. },
  224. {
  225. title: '选定人联系方式',
  226. dataIndex: 'mobile',
  227. slotName: 'mobile',
  228. align: 'center'
  229. },
  230. {
  231. title: '储存状态',
  232. dataIndex: 'cczt',
  233. slotName: 'cczt',
  234. align: 'center'
  235. }
  236. ]
  237. } else {
  238. tableColumns.value = [...tableColumnsTemp]
  239. }
  240. if (formType.value == 'back') {
  241. tableColumns.value.push({
  242. title: '操作',
  243. dataIndex: 'edit',
  244. slotName: 'edit',
  245. align: 'center'
  246. })
  247. } else {
  248. tableColumns.value.filter((item) => {
  249. return item.dataIndex !== 'edit'
  250. })
  251. }
  252. resetForm()
  253. try {
  254. formLoading.value = true
  255. queryParams.value = row
  256. await handleQuery()
  257. } finally {
  258. formLoading.value = false
  259. }
  260. }
  261. /**
  262. * 查询列表数据
  263. */
  264. const handleQuery = async () => {
  265. try {
  266. list.value = await DeliveryWarehouseSelectApi.getDeliveryWarehouseSelectList(queryParams.value)
  267. } catch (err) {
  268. throw err
  269. }
  270. }
  271. /**
  272. * 重置表单
  273. */
  274. const resetForm = () => {
  275. list.value = []
  276. }
  277. /**
  278. * 处理选择变更
  279. */
  280. /**
  281. * 提交表单
  282. */
  283. const submitForm = async () => {
  284. if (!selectedKeys.value?.length) {
  285. Message.warning('请至少选择一个需要退回的仓房!')
  286. return
  287. }
  288. formLoading.value = true
  289. await nextTick();
  290. try {
  291. const submitData: any = {
  292. ids: selectedKeys.value,
  293. ...queryParams.value
  294. }
  295. if (formType.value === 'select') {
  296. //存储id的list,找到对应id的数据
  297. submitData.storeRespVOList = list.value.filter((item) => selectedKeys.value.includes(item.id))
  298. await DeliveryWarehouseSelectApi.submitSelectList(submitData)
  299. Message.success("数据已提交到备选交收库")
  300. } else if (formType.value == 'back') {
  301. await DeliveryWarehouseSelectApi.returnToWarehouse(submitData)
  302. Message.success("数据已退回到交收仓选择")
  303. } else {
  304. return
  305. }
  306. dialogVisible.value = false
  307. emit('success')
  308. } finally {
  309. formLoading.value = false
  310. }
  311. }
  312. const backRow = async (row) => {
  313. try {
  314. await ElMessageBox.confirm('确认要退回的所选的库区?', '提示', {type:'warning'});
  315. const submitData: any = {
  316. ids: [row.id],
  317. ...queryParams.value
  318. }
  319. await DeliveryWarehouseSelectApi.returnToWarehouse(submitData)
  320. await handleQuery()
  321. Message.success("数据已退回到交收仓选择")
  322. } catch (err) {
  323. throw err
  324. }
  325. }
  326. // 监听
  327. // const stopWatches: (() => void)[] = [];
  328. // stopWatches.push(
  329. // watch(()=> formType.value)
  330. // )
  331. // onBeforeUnmount(() => {
  332. // stopWatches.forEach((stop) => stop())
  333. // })
  334. // 暴露方法
  335. defineExpose({open})
  336. // 定义事件
  337. const emit = defineEmits(['success'])
  338. </script>
  339. <style lang="scss" scoped>
  340. .mb-50px {
  341. margin-bottom: 50px;
  342. }
  343. :deep(.arco-table-element thead .arco-table-tr .arco-table-th) {
  344. background: var(--table-header-bg-color);
  345. font-weight: 700;
  346. height: 30px;
  347. }
  348. :deep(.arco-table .arco-table-cell) {
  349. //padding: 0px 0px;
  350. }
  351. :deep(.arco-table-border-cell .arco-table-th, .arco-table-border-cell .arco-table-td:not(.arco-table-tr-expand)) {
  352. border-right: 1px solid var(--color-neutral-3);
  353. background: var(--color-fill-2);
  354. }
  355. .custom-filter {
  356. padding: 20px;
  357. background: var(--color-bg-5);
  358. border: 1px solid var(--color-neutral-3);
  359. border-radius: var(--border-radius-medium);
  360. box-shadow: 0 2px 5px rgb(0 0 0 / 10%);
  361. }
  362. .custom-filter-footer {
  363. display: flex;
  364. justify-content: space-between;
  365. }
  366. </style>