quotation.vue 15 KB

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