index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. <template>
  2. <a-card :bordered="false" style="margin-bottom: 10px" class="mb-2">
  3. <a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
  4. <a-row :gutter="24">
  5. <a-col :span="6">
  6. <a-form-item label="预约单号" name="loadNumber">
  7. <a-input v-model:value="searchFormState.loadNumber" placeholder="预约单号查询" />
  8. </a-form-item>
  9. </a-col>
  10. <a-col :span="6">
  11. <a-form-item label="客户名称" name="customerName">
  12. <a-input v-model:value="searchFormState.customerName" placeholder="客户名称查询" />
  13. </a-form-item>
  14. </a-col>
  15. <a-col :span="6">
  16. <a-form-item label="货品名称" name="goodsName">
  17. <a-input v-model:value="searchFormState.goodsName" placeholder="货品名称查询" />
  18. </a-form-item>
  19. </a-col>
  20. <template v-if="advanced">
  21. <a-col :span="6">
  22. <a-form-item label="支付方式" name="payType">
  23. <a-select v-model:value="searchFormState.payType" placeholder="支付方式查询"
  24. :options="payTypeList"
  25. > </a-select>
  26. </a-form-item>
  27. </a-col>
  28. <a-col :span="6">
  29. <a-form-item label="创建时间" name="createTime">
  30. <a-range-picker
  31. v-model:value="searchFormState.createTime"
  32. value-format="YYYY-MM-DD"
  33. />
  34. </a-form-item>
  35. </a-col>
  36. </template>
  37. <a-col :span="6">
  38. <a-button type="primary" @click="tableRef.refresh()">查询</a-button>
  39. <a-button style="margin: 0 8px" @click="reset">重置</a-button>
  40. <a @click="toggleAdvanced" style="margin-left: 8px">
  41. {{ advanced ? '收起' : '展开' }}
  42. <component :is="advanced ? 'up-outlined' : 'down-outlined'" />
  43. </a>
  44. </a-col>
  45. </a-row>
  46. </a-form>
  47. </a-card>
  48. <a-card :bordered="false">
  49. <s-table
  50. ref="tableRef"
  51. :columns="columns"
  52. :data="loadData"
  53. bordered
  54. :row-key="(record) => record.id"
  55. >
  56. <template #operator class="table-operator">
  57. <a-space>
  58. <a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizLoadAppointAdd')">
  59. <template #icon><plus-outlined /></template>
  60. 新增
  61. </a-button>
  62. <a-button @click="exportTotal" v-if="hasPerm('bizLoadAppointExport')">
  63. <template #icon>
  64. <export-outlined/>
  65. </template>
  66. 导出
  67. </a-button>
  68. </a-space>
  69. </template>
  70. <template #bodyCell="{ column, record }">
  71. <template v-if="column.dataIndex === 'action'">
  72. <a @click="showModal(record)" v-if="(record.status == '5' || record.status == '6')">二维码</a>
  73. <a-divider type="vertical" v-if="(record.status == '5' || record.status == '6') "/>
  74. <a-dropdown>
  75. <a class="ant-dropdown-link">
  76. 更多
  77. <DownOutlined />
  78. </a>
  79. <template #overlay>
  80. <a-menu>
  81. <a-menu-item>
  82. <a size="small" type="link" @click="detailRef.onOpen(record)" >详情</a>
  83. </a-menu-item>
  84. <a-menu-item v-if="hasPerm('bizLoadAppointSubmit') && record.status=='0'">
  85. <a style="color:orangered" size="small" type="link" @click="bizLoadAppointsubmit(record.id)">提交</a>
  86. </a-menu-item>
  87. <a-menu-item v-if="hasPerm('bizLoadAppointSign') && record.status == '1'">
  88. <a style="color:orange" @click="XnSignNameRef.show(record.id)">签名</a>
  89. </a-menu-item>
  90. <a-menu-item v-if="hasPerm('bizLoadAppointEdit') && (record.status == '0')">
  91. <a style="color:blue" size="small" type="link" @click="formRef.onOpen(record)" >编辑</a>
  92. </a-menu-item>
  93. <a-menu-item v-if="hasPerm('bizLoadAppointDelete') && (record.status == '0')">
  94. <a style="color:red" size="small" type="link" @click="deleteConfig(record)">删除</a>
  95. </a-menu-item>
  96. <a-menu-item v-if="hasPerm('bizLoadDispatch') && (record.status == '4' || record.status=='5' || record.status=='6') && record.arriveStatus == '2'">
  97. <a style="color:blue" size="small" type="link" @click="dispatchRef.onOpen(record)">装货调度</a>
  98. </a-menu-item>
  99. <a-menu-item v-if="hasPerm('bizDispatchLoad') && (record.status == '4' || record.status=='5' || record.status=='6') && record.arriveStatus == '2'">
  100. <a style="color:green" size="small" type="link" @click="dispatchLoadRef.onOpen(record)">起卸调度</a>
  101. </a-menu-item>
  102. <a-menu-item v-if="hasPerm('bizLoadAppointEnd') && (record.status=='5' || record.status=='6')">
  103. <a style="color:red" @click="endRef.showModal(record.id)">结束</a>
  104. </a-menu-item>
  105. <a-menu-item v-if="hasPerm('bizLoadAppointFill') && (record.status=='7' )">
  106. <a style="color:orange" @click="fillRef.showModal(record.id)">填报</a>
  107. </a-menu-item>
  108. </a-menu>
  109. </template>
  110. </a-dropdown>
  111. </template>
  112. <template v-if="column.dataIndex === 'status'">
  113. <a-tag
  114. :color="
  115. record.status === '1'
  116. ? 'blue'
  117. : record.status === '2'
  118. ? 'warning'
  119. : record.status === '3'
  120. ? 'processing'
  121. : record.status === '4'
  122. ? 'volcano'
  123. : record.status === '5'
  124. ? 'purple'
  125. : record.status === '6'
  126. ? 'error'
  127. : record.status === '7'
  128. ? 'red'
  129. : record.status === '8'
  130. ? 'cyan'
  131. : '#f50'
  132. "
  133. >
  134. {{ $TOOL.dictTypeData('load_appoint_status', record.status) }}
  135. </a-tag>
  136. </template>
  137. </template>
  138. </s-table>
  139. </a-card>
  140. <Form ref="formRef" @successful="tableRef.refresh()" />
  141. <Detail ref="detailRef" @successful="tableRef.refresh()" />
  142. <Dispatch ref="dispatchRef" @successful="tableRef.refresh()" />
  143. <DispatchLoad ref="dispatchLoadRef" @successful="tableRef.refresh()" />
  144. <End ref="endRef" @successful="tableRef.refresh(true)" />
  145. <Fill ref="fillRef" @successful="tableRef.refresh(true)" />
  146. <XnSignName ref="XnSignNameRef" @successful="signSuccess" />
  147. <a-modal v-model:visible="open" title="二维码" width="600px" style="height: 700px">
  148. <div id="qrcode" style="text-align: center; margin: 15px 5px 15px 5px">
  149. <a-row>
  150. <a-col :span="13" id="colFlag">
  151. <div style="margin-top:10px;font-size:16px;">
  152. <p id="projectCodeFlag">预约单号:{{ nowRecord.loadNumber }}</p>
  153. <p id="projectCodeFlag">服务客户名称:{{ nowRecord.customerName }}</p>
  154. <p id="projectCodeFlag">货品名称:{{ nowRecord.goodsName }}</p>
  155. <p id="projectCodeFlag">货品编码:{{ nowRecord.goodsCode }}</p>
  156. <p id="projectCodeFlag">船运供应商:{{ nowRecord.supplierName }}</p>
  157. </div>
  158. </a-col>
  159. <a-col :span="11">
  160. <a-image width="250" height="100%" :src="qrCodeUrl.codeUrl"></a-image>
  161. </a-col>
  162. </a-row>
  163. </div>
  164. <template #footer>
  165. <a-button @click="closeQrCode">关闭</a-button>
  166. <a-button type="primary" @click="downloadFile">下载</a-button>
  167. </template>
  168. </a-modal>
  169. </template>
  170. <script setup name="bizloadappoint">
  171. import { cloneDeep } from 'lodash-es'
  172. import Form from './form.vue'
  173. import bizLoadAppointApi from '@/api/biz/bizLoadAppointApi'
  174. import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
  175. import {Modal} from 'ant-design-vue';
  176. import {createVNode} from 'vue';
  177. import tool from '@/utils/tool'
  178. import Detail from "./detail.vue";
  179. import QRCode from 'qrcode'
  180. import html2canvas from 'html2canvas'
  181. import downloadUtil from '@/utils/downloadUtil'
  182. import Dispatch from './dispatch.vue'
  183. import DispatchLoad from './dispatchload.vue'
  184. import End from "./end.vue";
  185. import Fill from './fill.vue'
  186. const tableRef = ref()
  187. const formRef = ref()
  188. const dispatchRef = ref()
  189. const dispatchLoadRef = ref()
  190. const detailRef = ref()
  191. const XnSignNameRef = ref()
  192. const nowRecord = ref()
  193. const endRef = ref()
  194. const fillRef = ref()
  195. const submitLoading = ref(false)
  196. const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
  197. //查询数据
  198. const searchFormState = ref({})
  199. const searchFormRef = ref()
  200. const payTypeList = tool.dictList('pay_type')
  201. // 查询区域显示更多控制
  202. const advanced = ref(false)
  203. const toggleAdvanced = () => {
  204. advanced.value = !advanced.value
  205. }
  206. const columns = [
  207. {
  208. title: '预约单号',
  209. dataIndex: 'loadNumber',
  210. align:'center'
  211. },
  212. {
  213. title: '服务客户名称',
  214. dataIndex: 'customerName',
  215. align:'center'
  216. },
  217. {
  218. title: '货品名称',
  219. dataIndex: 'goodsName',
  220. align:'center'
  221. },
  222. {
  223. title: '订单数量(吨)',
  224. dataIndex: 'orderWeight',
  225. align:'center'
  226. },
  227. {
  228. title: '单价(元/吨)',
  229. dataIndex: 'orderPrice',
  230. align:'center'
  231. },
  232. {
  233. title: '订单总额(元)',
  234. dataIndex: 'orderAmount',
  235. align:'center'
  236. },
  237. {
  238. title: '船运供应商',
  239. dataIndex: 'supplierName',
  240. align:'center'
  241. },
  242. {
  243. title: '运费单价(元/吨)',
  244. dataIndex: 'freightPrice',
  245. align:'center'
  246. },
  247. {
  248. title: '状态',
  249. dataIndex: 'status',
  250. align:'center'
  251. },
  252. ]
  253. // 操作栏通过权限判断是否显示
  254. columns.push({
  255. title: '操作',
  256. dataIndex: 'action',
  257. align: 'center',
  258. width: 150
  259. })
  260. const selectedRowKeys = ref([])
  261. // 列表选择配置
  262. const options = {
  263. // columns数字类型字段加入 needTotal: true 可以勾选自动算账
  264. alert: {
  265. show: true,
  266. clear: () => {
  267. selectedRowKeys.value = ref([])
  268. }
  269. },
  270. rowSelection: {
  271. onChange: (selectedRowKey, selectedRows) => {
  272. selectedRowKeys.value = selectedRowKey
  273. }
  274. }
  275. }
  276. const loadData = (parameter) => {
  277. const searchFormParam = cloneDeep(searchFormState.value)
  278. // 创建时间范围查询条件重载
  279. if (searchFormParam.createTime) {
  280. searchFormParam.createTimeBegin = searchFormParam.createTime[0]
  281. searchFormParam.createTimeEnd = searchFormParam.createTime[1]
  282. delete searchFormParam.createTime
  283. }
  284. return bizLoadAppointApi.bizLoadAppointPage(Object.assign(parameter, searchFormParam)).then((data) => {
  285. return data
  286. })
  287. }
  288. //提交
  289. const bizLoadAppointsubmit = (id) =>{
  290. Modal.confirm({
  291. title: '提示',
  292. icon: createVNode(ExclamationCircleOutlined),
  293. content: '是否提交该数据?',
  294. onOk() {
  295. submitLoading.value = true
  296. let params =
  297. {
  298. id: id
  299. }
  300. bizLoadAppointApi
  301. .submit(params)
  302. .then(() => {
  303. tableRef.value.refresh(true)
  304. })
  305. .finally(() => {
  306. submitLoading.value = false
  307. })
  308. },
  309. onCancel() {}
  310. })
  311. }
  312. // 签名板组件回调
  313. const signSuccess = (value) => {
  314. const param = {
  315. id:value.id,
  316. customerSign: value.value
  317. }
  318. bizLoadAppointApi.updateCustomerSign(param).then(() => {
  319. tableRef.value.refresh(true)
  320. })
  321. }
  322. //导出
  323. const exportTotal = () => {
  324. Modal.confirm({
  325. title: '确定要导出记录吗?',
  326. icon: createVNode(ExclamationCircleOutlined),
  327. content: '',
  328. onOk() {
  329. submitLoading.value = true
  330. const searchFormParam = cloneDeep(searchFormState.value)
  331. // 创建时间范围查询条件重载
  332. if (searchFormParam.createTime) {
  333. searchFormParam.createTimeBegin = searchFormParam.createTime[0]
  334. searchFormParam.createTimeEnd = searchFormParam.createTime[1]
  335. delete searchFormParam.createTime
  336. }
  337. bizLoadAppointApi
  338. .exportRecord(Object.assign(searchFormParam))
  339. .then((res) => {
  340. downloadUtil.resultDownload(res)
  341. })
  342. .finally(() => {
  343. submitLoading.value = false
  344. })
  345. },
  346. onCancel() {}
  347. })
  348. }
  349. //二维码
  350. const open = ref(false);
  351. const qrCodeUrl = ref({})
  352. const showModal = (record) => {
  353. nowRecord.value = record
  354. open.value = true;
  355. getQrCode(record)
  356. };
  357. const getQrCode = (record) => {
  358. //QRCode.toDataURL("id:"+record.id+"saleCode:"+record.saleCode, {
  359. let param = {
  360. id:record.id,
  361. loadNumber:record.loadNumber,
  362. type:'3'
  363. }
  364. QRCode.toDataURL(JSON.stringify(param), {
  365. errorCorrectionLevel: 'H',
  366. margin: 1,
  367. height: 206,
  368. width: 206,
  369. type: '10',
  370. scal: 177,
  371. color: {
  372. dark: '#000' // 二维码背景颜色
  373. },
  374. rendererOpts: {
  375. quality: 0.9
  376. }
  377. })
  378. .then((url) => {
  379. qrCodeUrl.value.codeUrl = url
  380. })
  381. .catch((err) => {
  382. console.error(err)
  383. })
  384. }
  385. const closeQrCode = () => {
  386. open.value = false;
  387. }
  388. // 下载二维码
  389. const downloadFile = () => {
  390. const qrcodeDiv = document.getElementById('qrcode');
  391. html2canvas(qrcodeDiv, {
  392. logging: false,
  393. allowTaint: true,
  394. scale: window.devicePixelRatio,
  395. scrollY: 0,
  396. scrollX: 0,
  397. useCORS: true,
  398. backgroundColor: '#ffffff'
  399. })
  400. .then(function (canvas) {
  401. const a = window.document.createElement('a')
  402. a.href = canvas.toDataURL('image/png')
  403. a.download = '二维码'
  404. a.click()
  405. this.$message.success('正在进行下载保存')
  406. })
  407. .catch((err) => {
  408. console.log(err)
  409. })
  410. }
  411. // 重置
  412. const reset = () => {
  413. searchFormRef.value.resetFields()
  414. tableRef.value.refresh(true)
  415. }
  416. // 删除
  417. const deleteBizLoadAppoint = (record) => {
  418. let params = [
  419. {
  420. id: record.id
  421. }
  422. ]
  423. bizLoadAppointApi.bizLoadAppointDelete(params).then(() => {
  424. tableRef.value.refresh(true)
  425. })
  426. }
  427. // 删除
  428. const deleteConfig = (record) => {
  429. Modal.confirm({
  430. title: '确定删除该数据吗?',
  431. icon: createVNode(ExclamationCircleOutlined),
  432. content: '',
  433. onOk() {
  434. submitLoading.value = true
  435. let params = [
  436. {
  437. id: record.id
  438. }
  439. ]
  440. bizLoadAppointApi
  441. .bizLoadAppointDelete(params)
  442. .then(() => {
  443. tableRef.value.refresh(true)
  444. })
  445. .finally(() => {
  446. submitLoading.value = false
  447. })
  448. },
  449. onCancel() {}
  450. })
  451. }
  452. // 批量删除
  453. const deleteBatchBizLoadAppoint = (params) => {
  454. bizLoadAppointApi.bizLoadAppointDelete(params).then(() => {
  455. tableRef.value.clearRefreshSelected()
  456. })
  457. }
  458. </script>