index.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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="planNumber">
  7. <a-input v-model:value="searchFormState.planNumber" placeholder="计划编号查询" />
  8. </a-form-item>
  9. </a-col>
  10. <a-col :span="6">
  11. <a-form-item label="计划名称" name="planName">
  12. <a-input v-model:value="searchFormState.planName" placeholder="计划名称查询" />
  13. </a-form-item>
  14. </a-col>
  15. <a-col :span="6">
  16. <a-button type="primary" @click="tableRef.refresh()">查询</a-button>
  17. <a-button style="margin: 0 8px" @click="reset">重置</a-button>
  18. </a-col>
  19. </a-row>
  20. </a-form>
  21. </a-card>
  22. <a-card :bordered="false">
  23. <s-table
  24. ref="tableRef"
  25. :columns="columns"
  26. :data="loadData"
  27. bordered
  28. :row-key="(record) => record.id"
  29. >
  30. <template #operator class="table-operator">
  31. <a-space>
  32. <a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizPipePlanAdd')">
  33. <template #icon><plus-outlined /></template>
  34. 新增
  35. </a-button>
  36. </a-space>
  37. </template>
  38. <template #bodyCell="{ column, record }">
  39. <template v-if="column.dataIndex === 'action'">
  40. <a @click="showModal(record)" v-if="(record.status == '1' || record.status == '2')">二维码</a>
  41. <a-divider type="vertical" v-if="(record.status == '1' || record.status == '2') "/>
  42. <a-dropdown>
  43. <a class="ant-dropdown-link">
  44. 更多
  45. <DownOutlined />
  46. </a>
  47. <template #overlay>
  48. <a-menu>
  49. <a-menu-item v-if="hasPerm('bizPipePlanEdit')">
  50. <a @click="formRef.onOpen(record)" >编辑</a>
  51. </a-menu-item>
  52. <a-menu-item v-if="hasPerm('bizPipePlanDelete')">
  53. <a style="color:red" size="small" type="link" @click="deleteConfig(record)">删除</a>
  54. </a-menu-item>
  55. <a-menu-item v-if="hasPerm('bizPipePlanEnd')">
  56. <a style="color:red" size="small" type="link" @click="endPlan(record)">结束</a>
  57. </a-menu-item>
  58. </a-menu>
  59. </template>
  60. </a-dropdown>
  61. </template>
  62. <template v-if="column.dataIndex === 'planSurplusCount'">
  63. {{record.planCount-record.planAlreadyCount}}
  64. </template>
  65. <template v-if="column.dataIndex === 'status'">
  66. <a-tag
  67. :color="
  68. record.status === '1'
  69. ? 'blue'
  70. : record.status === '2'
  71. ? 'warning'
  72. : record.status === '3'
  73. ? 'red'
  74. : record.status === '4'
  75. ? 'volcano'
  76. : record.status === '5'
  77. ? 'purple'
  78. : record.status === '6'
  79. ? 'error'
  80. : record.status === '7'
  81. ? 'red'
  82. : record.status === '8'
  83. ? 'cyan'
  84. : '#f50'
  85. "
  86. >
  87. {{ $TOOL.dictTypeData('pipe_plan_status', record.status) }}
  88. </a-tag>
  89. </template>
  90. </template>
  91. </s-table>
  92. </a-card>
  93. <Form ref="formRef" @successful="tableRef.refresh()" />
  94. <a-modal v-model:visible="open" title="二维码" width="600px" style="height: 700px">
  95. <div id="qrcode" style="text-align: center; margin: 15px 5px 15px 5px">
  96. <a-row>
  97. <a-col :span="13" id="colFlag">
  98. <div style="margin-top:10px;font-size:16px;">
  99. <p id="projectCodeFlag">计划编码:{{ nowRecord.planNumber }}</p>
  100. <p id="projectCodeFlag">计划名称:{{ nowRecord.planName }}</p>
  101. <!-- <p id="projectCodeFlag">预约次数:{{ nowRecord.planCount }}</p>
  102. <p id="projectCodeFlag">已约次数:{{ nowRecord.planAlreadyCount }}</p>-->
  103. <p id="projectCodeFlag">开始时间:{{ nowRecord.beginTime }}</p>
  104. <p id="projectCodeFlag">结束时间:{{ nowRecord.endTime }}</p>
  105. </div>
  106. </a-col>
  107. <a-col :span="11">
  108. <a-image width="250" height="100%" :src="qrCodeUrl.codeUrl"></a-image>
  109. </a-col>
  110. </a-row>
  111. </div>
  112. <template #footer>
  113. <a-button @click="closeQrCode">关闭</a-button>
  114. <a-button type="primary" @click="downloadFile">下载</a-button>
  115. </template>
  116. </a-modal>
  117. </template>
  118. <script setup name="bizpipeplan">
  119. import { cloneDeep } from 'lodash-es'
  120. import Form from './form.vue'
  121. import bizPipePlanApi from '@/api/biz/bizPipePlanApi'
  122. import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
  123. import {Modal} from 'ant-design-vue';
  124. import {createVNode} from 'vue';
  125. import QRCode from 'qrcode'
  126. import html2canvas from 'html2canvas'
  127. //查询数据
  128. const searchFormState = ref({})
  129. const searchFormRef = ref()
  130. const tableRef = ref()
  131. const formRef = ref()
  132. const submitLoading = ref(false)
  133. const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
  134. const columns = [
  135. {
  136. title: '计划编号',
  137. dataIndex: 'planNumber',
  138. align:'center'
  139. },
  140. {
  141. title: '计划名称',
  142. dataIndex: 'planName',
  143. align:'center'
  144. },
  145. {
  146. title: '预约次数',
  147. dataIndex: 'planCount',
  148. align:'center'
  149. },
  150. {
  151. title: '已约次数',
  152. dataIndex: 'planAlreadyCount',
  153. align:'center'
  154. },
  155. {
  156. title: '剩余次数',
  157. dataIndex: 'planSurplusCount',
  158. align:'center'
  159. },
  160. {
  161. title: '开始时间',
  162. dataIndex: 'beginTime',
  163. align:'center'
  164. },
  165. {
  166. title: '结束时间',
  167. dataIndex: 'endTime',
  168. align:'center'
  169. },
  170. {
  171. title: '状态',
  172. dataIndex: 'status',
  173. align:'center'
  174. },
  175. ]
  176. // 操作栏通过权限判断是否显示
  177. columns.push({
  178. title: '操作',
  179. dataIndex: 'action',
  180. align: 'center',
  181. width: 150
  182. })
  183. const selectedRowKeys = ref([])
  184. // 列表选择配置
  185. const options = {
  186. // columns数字类型字段加入 needTotal: true 可以勾选自动算账
  187. alert: {
  188. show: true,
  189. clear: () => {
  190. selectedRowKeys.value = ref([])
  191. }
  192. },
  193. rowSelection: {
  194. onChange: (selectedRowKey, selectedRows) => {
  195. selectedRowKeys.value = selectedRowKey
  196. }
  197. }
  198. }
  199. const loadData = (parameter) => {
  200. const searchFormParam = cloneDeep(searchFormState.value)
  201. return bizPipePlanApi.bizPipePlanPage(Object.assign(parameter, searchFormParam)).then((data) => {
  202. return data
  203. })
  204. }
  205. // 重置
  206. const reset = () => {
  207. searchFormRef.value.resetFields()
  208. tableRef.value.refresh(true)
  209. }
  210. // 删除
  211. const deleteBizPipePlan = (record) => {
  212. let params = [
  213. {
  214. id: record.id
  215. }
  216. ]
  217. bizPipePlanApi.bizPipePlanDelete(params).then(() => {
  218. tableRef.value.refresh(true)
  219. })
  220. }
  221. // 删除
  222. const deleteConfig = (record) => {
  223. Modal.confirm({
  224. title: '确定删除该数据吗?',
  225. icon: createVNode(ExclamationCircleOutlined),
  226. content: '',
  227. onOk() {
  228. submitLoading.value = true
  229. let params = [
  230. {
  231. id: record.id
  232. }
  233. ]
  234. bizPipePlanApi
  235. .bizPipePlanDelete(params)
  236. .then(() => {
  237. tableRef.value.refresh(true)
  238. })
  239. .finally(() => {
  240. submitLoading.value = false
  241. })
  242. },
  243. onCancel() {}
  244. })
  245. }
  246. //结束
  247. const endPlan = (record) => {
  248. Modal.confirm({
  249. title: '确定结束该数据吗?',
  250. icon: createVNode(ExclamationCircleOutlined),
  251. content: '',
  252. onOk() {
  253. submitLoading.value = true
  254. let params =
  255. {
  256. id: record.id
  257. }
  258. bizPipePlanApi
  259. .endPlan(params)
  260. .then(() => {
  261. tableRef.value.refresh(true)
  262. })
  263. .finally(() => {
  264. submitLoading.value = false
  265. })
  266. },
  267. onCancel() {}
  268. })
  269. }
  270. // 批量删除
  271. const deleteBatchBizPipePlan = (params) => {
  272. bizPipePlanApi.bizPipePlanDelete(params).then(() => {
  273. tableRef.value.clearRefreshSelected()
  274. })
  275. }
  276. //二维码
  277. const open = ref(false);
  278. const qrCodeUrl = ref({})
  279. const nowRecord = ref()
  280. const showModal = (record) => {
  281. nowRecord.value = record
  282. open.value = true;
  283. getQrCode(record)
  284. };
  285. const getQrCode = (record) => {
  286. //QRCode.toDataURL("id:"+record.id+"saleCode:"+record.saleCode, {
  287. let param = {
  288. id:record.id,
  289. loadNumber:record.planNumber,
  290. type:'5'
  291. }
  292. QRCode.toDataURL(JSON.stringify(param), {
  293. errorCorrectionLevel: 'H',
  294. margin: 1,
  295. height: 206,
  296. width: 206,
  297. type: '10',
  298. scal: 177,
  299. color: {
  300. dark: '#000' // 二维码背景颜色
  301. },
  302. rendererOpts: {
  303. quality: 0.9
  304. }
  305. })
  306. .then((url) => {
  307. qrCodeUrl.value.codeUrl = url
  308. })
  309. .catch((err) => {
  310. console.error(err)
  311. })
  312. }
  313. const closeQrCode = () => {
  314. open.value = false;
  315. }
  316. // 下载二维码
  317. const downloadFile = () => {
  318. const qrcodeDiv = document.getElementById('qrcode');
  319. html2canvas(qrcodeDiv, {
  320. logging: false,
  321. allowTaint: true,
  322. scale: window.devicePixelRatio,
  323. scrollY: 0,
  324. scrollX: 0,
  325. useCORS: true,
  326. backgroundColor: '#ffffff'
  327. })
  328. .then(function (canvas) {
  329. const a = window.document.createElement('a')
  330. a.href = canvas.toDataURL('image/png')
  331. a.download = '二维码'
  332. a.click()
  333. this.$message.success('正在进行下载保存')
  334. })
  335. .catch((err) => {
  336. console.log(err)
  337. })
  338. }
  339. </script>