quotation.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. <template>
  2. <div class="p-2">
  3. <!--查询区域-->
  4. <div class="jeecg-basic-table-form-container">
  5. <a-form ref="formRef" @keyup.enter.native="reload" :model="queryParam">
  6. <a-row :gutter="24">
  7. <a-col :lg="8">
  8. <a-form-item name="billCode" :label-col="{ style: 'width: 200px' }">
  9. <template #label><span title="报价单号(bill code)">报价单号(bill code)</span></template>
  10. <JInput placeholder="请输入询价单号(bill code)" v-model:value="queryParam.billCode" allow-clear AutoComplete="off" />
  11. </a-form-item>
  12. </a-col>
  13. <a-col :lg="8">
  14. <a-form-item name="quotationProject" :label-col="{ style: 'width: 200px' }">
  15. <template #label ><span title="报价项目(quotation project)">报价项目(quotation project)</span></template>
  16. <ApiSelect
  17. :api="ProjectOption"
  18. showSearch
  19. v-model:value="queryParam.quotationProject"
  20. :filterOption="true"
  21. resultField="records"
  22. labelField="code"
  23. valueField="id"
  24. :params="{ pageSize: -1 }"
  25. optionFilterProp="label"
  26. />
  27. </a-form-item>
  28. </a-col>
  29. <template v-if="toggleSearchStatus">
  30. <a-col :lg="8">
  31. <a-form-item name="billDate" :label-col="{ style: 'width: 200px' }">
  32. <template #label><span title="单据日期(bill date)">单据日期(bill date)</span></template>
  33. <a-range-picker value-format="YYYY-MM-DD" v-model:value="queryParam.billDate" class="query-group-cust" />
  34. </a-form-item>
  35. </a-col>
  36. <a-col :lg="16">
  37. <a-form-item name="quotationCustomer" :label-col="{ style: 'width: 200px' }">
  38. <template #label><span title="报价客户(quotation customer)">报价客户(quotation customer)</span></template>
  39. <JSelect v-model:value="queryParam.quotationCustomer" :get-option-url="CustomerOption" :showField="showField" :param="{status:null}"></JSelect>
  40. </a-form-item>
  41. </a-col>
  42. <a-col :lg="8">
  43. <a-form-item name="priority" :label-col="{ style: 'width: 200px' }">
  44. <template #label><span title="优先级(priority)">优先级(priority)</span></template>
  45. <JDictSelectTag v-model:value="queryParam.priority" placeholder="请选择" dictCode="priority" />
  46. </a-form-item>
  47. </a-col>
  48. <a-col :lg="16">
  49. <a-form-item name="quotationCustomer" :label-col="{ style: 'width: 200px' }">
  50. <template #label><span title="客户简称(abbreviation)">客户简称(abbreviation)</span></template>
  51. <JSelect v-model:value="queryParam.quotationCustomer" :get-option-url="CustomerOption" :showField="showField2" :param="{status:null}"></JSelect>
  52. </a-form-item>
  53. </a-col>
  54. <a-col :lg="8">
  55. <a-form-item name="productionClass" :label-col="{ style: 'width: 200px' }">
  56. <template #label><span title="产品分类(production class)">产品分类(production class)</span></template>
  57. <JDictSelectTag
  58. v-model:value="queryParam.productionClass"
  59. placeholder=""
  60. dictCode="base_product_class,name,id,del_flag=0 and parent_id is null"
  61. page="false"
  62. showSearch
  63. />
  64. </a-form-item>
  65. </a-col>
  66. <a-col :lg="8">
  67. <a-form-item name="model" :label-col="{ style: 'width: 200px' }">
  68. <template #label><span title="机型(model)">机型(model)</span></template>
  69. <JDictSelectTag v-model:value="queryParam.model" placeholder="请选择" dictCode="model_typer" />
  70. </a-form-item>
  71. </a-col>
  72. <a-col :lg="8">
  73. <a-form-item name="maker" :label-col="{ style: 'width: 200px' }">
  74. <template #label><span title="厂家(maker)">厂家(maker)</span></template>
  75. <JDictSelectTag v-model:value="queryParam.maker" placeholder="请选择" dictCode="factory" />
  76. </a-form-item>
  77. </a-col>
  78. <a-col :lg="8">
  79. <a-form-item name="englishName" :label-col="{ style: 'width: 200px' }">
  80. <template #label><span title="产品英文名(english name)">产品英文名(english name)</span></template>
  81. <JInput placeholder="请输入产品英文名(english name)" v-model:value="queryParam.englishName" allow-clear AutoComplete="off" />
  82. </a-form-item>
  83. </a-col>
  84. <a-col :lg="8">
  85. <a-form-item name="productCode" :label-col="{ style: 'width: 200px' }">
  86. <template #label><span title="产品编码(product code)">产品编码(product code)</span></template>
  87. <JInput placeholder="请输入产品编码(product code)" v-model:value="queryParam.productCode" allow-clear AutoComplete="off" />
  88. </a-form-item>
  89. </a-col>
  90. <a-col :lg="8">
  91. <a-form-item name="sourceCode" :label-col="{ style: 'width: 200px' }">
  92. <template #label><span title="来源(sourceCode)">来源(sourceCode)</span></template>
  93. <JInput placeholder="请输入来源(sourceCode)" v-model:value="queryParam.sourceCode" allow-clear AutoComplete="off" />
  94. </a-form-item>
  95. </a-col>
  96. <a-col :lg="8">
  97. <a-form-item name="shipName" :label-col="{ style: 'width: 200px' }">
  98. <template #label><span title="船(shipName)">船(shipName)</span></template>
  99. <JInput placeholder="请输入船(shipName)" v-model:value="queryParam.shipName" allow-clear AutoComplete="off" />
  100. </a-form-item>
  101. </a-col>
  102. <a-col :lg="8">
  103. <a-form-item name="imo" :label-col="{ style: 'width: 200px' }">
  104. <template #label><span title="imo(imo)">imo(imo)</span></template>
  105. <JInput placeholder="请输入imo(imo)" v-model:value="queryParam.imo" allow-clear AutoComplete="off" />
  106. </a-form-item>
  107. </a-col>
  108. <a-col :lg="8">
  109. <a-form-item name="model" :label-col="{ style: 'width: 200px' }">
  110. <template #label><span title="型号(model">型号(model)</span></template>
  111. <JInput placeholder="请输入型号(model)" v-model:value="queryParam.model" allow-clear AutoComplete="off" />
  112. </a-form-item>
  113. </a-col>
  114. <a-col :lg="8">
  115. <a-form-item name="status" :label-col="{ style: 'width: 200px' }">
  116. <template #label><span title="状态(status)">状态(status)</span></template>
  117. <JDictSelectTag v-model:value="queryParam.status" placeholder="请选择" dictCode="quotation_status" />
  118. </a-form-item>
  119. </a-col>
  120. </template>
  121. <a-col :xl="6" :lg="7" :md="8" :sm="24">
  122. <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
  123. <a-col :lg="6">
  124. <a-button type="primary" preIcon="ant-design:search-outlined" @click="reload">查询</a-button>
  125. <a-button preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
  126. <a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px">
  127. {{ toggleSearchStatus ? '收起' : '展开' }}
  128. <Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
  129. </a>
  130. </a-col>
  131. </span>
  132. </a-col>
  133. </a-row>
  134. </a-form>
  135. </div>
  136. <!--引用表格-->
  137. <BasicTable @register="registerTable" :rowSelection="rowSelection" size="small">
  138. <!--插槽:table标题-->
  139. <template #tableTitle>
  140. <a-button type="primary" v-auth="'saleCode:sale_quotation:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增(add)</a-button>
  141. <a-button type="primary" v-auth="'saleCode:sale_quotation:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls">
  142. 导出(export)</a-button
  143. >
  144. <a-button type="primary" v-auth="'saleCode:sale_quotation:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls2">
  145. 导出明细(export)</a-button
  146. >
  147. <a-button type="primary" @click="submit"> 提交(submit)</a-button>
  148. <a-button type="primary" @click="cancelSubmit"> 取消提交(cancelSubmit)</a-button>
  149. <a-dropdown v-if="selectedRowKeys.length > 0">
  150. <template #overlay>
  151. <a-menu>
  152. <a-menu-item key="1" @click="batchHandleDelete" v-auth="'saleCode:sale_quotation:deleteBatch'">
  153. <Icon icon="ant-design:delete-outlined" />
  154. 删除(delete)
  155. </a-menu-item>
  156. </a-menu>
  157. </template>
  158. <a-button v-auth="'saleCode:sale_inquiry_form:deleteBatch'"
  159. >批量操作
  160. <Icon icon="mdi:chevron-down" />
  161. </a-button>
  162. </a-dropdown>
  163. </template>
  164. <!--操作栏-->
  165. <template #action="{ record }">
  166. <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
  167. </template>
  168. <!--字段回显插槽-->
  169. <template #bodyCell="{ column, record, index, text }"> </template>
  170. </BasicTable>
  171. <quotationFormModal @register="registerModal" @success="handleSuccess" />
  172. <ViewHistoryVersionModal ref="ViewHistoryVersionModalRef" @success="handleSuccess" />
  173. <SetToExamine ref="SetToExamineRef" @success="handleSuccess" ></SetToExamine>
  174. <!-- 表单区域 -->
  175. </div>
  176. </template>
  177. <script lang="ts" name="saleCode-saleInquiryForm" setup>
  178. import { ref, reactive, computed, unref, onMounted } from 'vue';
  179. import { BasicTable, useTable, TableAction } from '/@/components/Table';
  180. import { useListPage } from '/@/hooks/system/useListPage';
  181. import { useModal } from '/@/components/Modal';
  182. import { columns, superQuerySchema } from './quotationForm.data';
  183. import {
  184. list,
  185. deleteOne,
  186. batchDelete,
  187. getImportUrl,
  188. getExportUrl,
  189. getExportUrl2,
  190. batchSubmit,
  191. cancelBatchSubmit,
  192. ProjectOption,
  193. CustomerOption,
  194. } from './quotationForm.api';
  195. import { cloneDeep } from 'lodash-es';
  196. import { JDictSelectTag, ApiSelect, JInput ,JSelect} from '/@/components/Form';
  197. import SetToExamine from './components/SetToExamine.vue';
  198. import quotationFormModal from './components/quotationFormModal.vue';
  199. import ViewHistoryVersionModal from './components/ViewHistoryVersionModal.vue';
  200. import { message } from 'ant-design-vue';
  201. import { useMethods } from '/@/hooks/system/useMethods';
  202. const { handleExportXlsx, } = useMethods();
  203. const formRef = ref();
  204. const queryParam = reactive<any>({});
  205. const checkedKeys = ref<Array<string | number>>([]);
  206. //注册model
  207. const [registerModal, { openModal }] = useModal();
  208. var showField = ref('currency_dictText+name');
  209. var showField2 = ref('currency_dictText+abbreviation');
  210. var ViewHistoryVersionModalRef = ref();
  211. var SetToExamineRef = ref();
  212. //注册table数据
  213. const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
  214. tableProps: {
  215. title: '报价单',
  216. api: list,
  217. columns,
  218. canResize: false,
  219. useSearchForm: false,
  220. actionColumn: {
  221. width: 440,
  222. fixed: 'right',
  223. },
  224. scroll: {
  225. x: '2700px',
  226. y:'calc(100vh - 400px)',
  227. },
  228. beforeFetch: async (params) => {
  229. let rangerQuery = await setRangeQuery();
  230. return Object.assign(params, rangerQuery);
  231. },
  232. },
  233. exportConfig: {
  234. name: '销售报价单',
  235. url: getExportUrl,
  236. params: queryParam,
  237. },
  238. importConfig: {
  239. url: getImportUrl,
  240. success: handleSuccess,
  241. },
  242. });
  243. //注册table数据
  244. const { onExportXls: onExportXls2 } = useListPage({
  245. tableProps: {
  246. title: '销售报价单明细',
  247. api: list,
  248. columns,
  249. canResize: false,
  250. useSearchForm: false,
  251. actionColumn: {
  252. width: 300,
  253. fixed: 'right',
  254. },
  255. scroll: {
  256. x: '4000px',
  257. y:'calc(100vh - 400px)',
  258. },
  259. beforeFetch: async (params) => {
  260. let rangerQuery = await setRangeQuery();
  261. return Object.assign(params, rangerQuery);
  262. },
  263. },
  264. exportConfig: {
  265. name: '销售报价单明细',
  266. url: '/saleCode/saleQuotation/exportXlsDetail',
  267. params: queryParam,
  268. }
  269. });
  270. const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
  271. // 高级查询配置
  272. const superQueryConfig = reactive(superQuerySchema);
  273. /**
  274. * 高级查询事件
  275. */
  276. function handleSuperQuery(params) {
  277. Object.keys(params).map((k) => {
  278. queryParam[k] = params[k];
  279. });
  280. reload();
  281. }
  282. /**
  283. * 新增事件
  284. */
  285. function handleAdd() {
  286. openModal(true, {
  287. isUpdate: false,
  288. showFooter: true,
  289. isRevise: false,
  290. });
  291. }
  292. /**
  293. * 编辑事件
  294. */
  295. function handleEdit(record: Recordable) {
  296. openModal(true, {
  297. record,
  298. isUpdate: true,
  299. showFooter: true,
  300. isRevise: false,
  301. });
  302. }
  303. //修订
  304. function handleRevise(record: Recordable) {
  305. openModal(true, {
  306. record,
  307. isUpdate: true,
  308. showFooter: true,
  309. isRevise: true,
  310. });
  311. }
  312. function handleViewHistory(record: Recordable) {
  313. ViewHistoryVersionModalRef.value.getTable(record);
  314. }
  315. /**
  316. * 详情
  317. */
  318. function handleDetail(record: Recordable) {
  319. openModal(true, {
  320. record,
  321. isUpdate: true,
  322. showFooter: false,
  323. isRevise: false,
  324. });
  325. }
  326. /**
  327. * 删除事件
  328. */
  329. async function handleDelete(record) {
  330. await deleteOne({ id: record.id }, handleSuccess);
  331. }
  332. /**
  333. * 批量删除事件
  334. */
  335. async function batchHandleDelete() {
  336. await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
  337. }
  338. /**
  339. * 成功回调
  340. */
  341. function handleSuccess() {
  342. (selectedRowKeys.value = []) && reload();
  343. }
  344. // 审核
  345. function handleToExamine(record) {
  346. SetToExamineRef.value.getTable(record);
  347. }
  348. /**
  349. * 操作栏
  350. */
  351. function getTableAction(record) {
  352. return [
  353. {
  354. label: '导出(export)',
  355. onClick: onExportXlsNow.bind(null, record),
  356. auth: 'saleCode:sale_quotation:edit',
  357. },
  358. {
  359. label: '编辑(edit)',
  360. onClick: handleEdit.bind(null, record),
  361. auth: 'saleCode:sale_quotation:edit',
  362. ifShow: record.status == '0',
  363. },
  364. {
  365. label: '修订(revise)',
  366. ifShow: record.status == '1',
  367. auth: 'saleCode:sale_quotation:editHis',
  368. onClick: handleRevise.bind(null, record),
  369. },
  370. // {
  371. // label: '审核(to examine)',
  372. // ifShow: record.status == '1',
  373. // // auth: 'saleCode:sale_quotation:editHis',
  374. // onClick: handleToExamine.bind(null, record),
  375. // },
  376. {
  377. label: '删除(delete)',
  378. popConfirm: {
  379. title: '是否确认删除',
  380. confirm: handleDelete.bind(null, record),
  381. placement: 'topLeft',
  382. },
  383. ifShow: record.status == '0',
  384. auth: 'saleCode:sale_quotation:delete',
  385. },
  386. ];
  387. }
  388. /**
  389. * 下拉操作栏
  390. */
  391. function getDropDownAction(record) {
  392. return [
  393. {
  394. label: '详情(detail)',
  395. onClick: handleDetail.bind(null, record),
  396. },
  397. {
  398. label: '查看历史版本(history)',
  399. onClick: handleViewHistory.bind(null, record),
  400. ifShow: record.status == '1',
  401. },
  402. ];
  403. }
  404. function submit() {
  405. if (selectedRowKeys.value.length == 0) {
  406. message.warning('请选择数据');
  407. } else {
  408. var ids = selectedRowKeys.value.join(',');
  409. batchSubmit({ ids: ids }, handleSuccess);
  410. }
  411. }
  412. function cancelSubmit() {
  413. if (selectedRowKeys.value.length == 0) {
  414. message.warning('请选择数据');
  415. } else {
  416. var ids = selectedRowKeys.value.join(',');
  417. cancelBatchSubmit({ ids: ids }, handleSuccess);
  418. }
  419. }
  420. async function onExportXlsNow(record) {
  421. var obj ={
  422. id:record.id
  423. }
  424. handleExportXlsx(record.billCode, getExportUrl2,obj)
  425. }
  426. /* ----------------------以下为原生查询需要添加的-------------------------- */
  427. const toggleSearchStatus = ref<boolean>(false);
  428. const labelCol = reactive({
  429. xs: 24,
  430. sm: 9,
  431. });
  432. const wrapperCol = reactive({
  433. xs: 24,
  434. sm: 17,
  435. });
  436. const labelCol1 = reactive({
  437. xs: 24,
  438. sm: 12,
  439. });
  440. const wrapperCol1 = reactive({
  441. xs: 24,
  442. sm: 12,
  443. });
  444. /**
  445. * 重置
  446. */
  447. function searchReset() {
  448. formRef.value.resetFields();
  449. selectedRowKeys.value = [];
  450. //刷新数据
  451. reload();
  452. }
  453. let rangeField = 'billDate,';
  454. /**
  455. * 设置范围查询条件
  456. */
  457. async function setRangeQuery() {
  458. let queryParamClone = cloneDeep(queryParam);
  459. if (rangeField) {
  460. let fieldsValue = rangeField.split(',');
  461. fieldsValue.forEach((item) => {
  462. if (queryParamClone[item]) {
  463. let range = queryParamClone[item];
  464. queryParamClone[item + '_begin'] = range[0];
  465. queryParamClone[item + '_end'] = range[1];
  466. delete queryParamClone[item];
  467. } else {
  468. queryParamClone[item + '_begin'] = '';
  469. queryParamClone[item + '_end'] = '';
  470. }
  471. });
  472. }
  473. return queryParamClone;
  474. }
  475. </script>
  476. <style lang="less" scoped>
  477. .jeecg-basic-table-form-container {
  478. padding: 0;
  479. .table-page-search-submitButtons {
  480. display: block;
  481. margin-bottom: 8px;
  482. white-space: nowrap;
  483. }
  484. .query-group-cust {
  485. min-width: 100px !important;
  486. }
  487. .query-group-split-cust {
  488. width: 30px;
  489. display: inline-block;
  490. text-align: center;
  491. }
  492. .ant-form-item:not(.ant-form-item-with-help) {
  493. margin-bottom: 8px;
  494. height: 32px;
  495. }
  496. :deep(.ant-picker),
  497. :deep(.ant-input-number) {
  498. width: 100%;
  499. }
  500. }
  501. </style>