index.vue 12 KB

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