You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

549 lines
22 KiB

  1. <template>
  2. <div class="customer-css">
  3. <!-- 查询条件 -->
  4. <el-form :inline="true" label-position="top" class="pi-search-form">
  5. <el-form-item :label="'报价单号'">
  6. <el-input v-model="searchData.orderNo" placeholder="报价单号" style="width:160px" @keyup.enter.native="getList" />
  7. </el-form-item>
  8. <el-form-item :label="'物料编码'">
  9. <el-input v-model="searchData.partNo" placeholder="物料编码" style="width:160px" @keyup.enter.native="getList" />
  10. </el-form-item>
  11. <el-form-item :label="'物料名称'">
  12. <el-input v-model="searchData.partDesc" placeholder="物料名称" style="width:200px" @keyup.enter.native="getList" />
  13. </el-form-item>
  14. <el-form-item :label="'报价日期'">
  15. <el-date-picker
  16. style="width: 130px"
  17. v-model="searchData.startDate"
  18. type="date"
  19. format="yyyy-MM-dd"
  20. value-format="yyyy-MM-dd"
  21. placeholder="Start">
  22. </el-date-picker>
  23. </el-form-item>
  24. <el-form-item :label="'To'">
  25. <el-date-picker
  26. style="width: 130px"
  27. v-model="searchData.endDate"
  28. type="date"
  29. format="yyyy-MM-dd"
  30. value-format="yyyy-MM-dd"
  31. placeholder="End">
  32. </el-date-picker>
  33. </el-form-item>
  34. <el-form-item label=" ">
  35. <el-button type="primary" class="customer-bun-min" @click="getList">查询</el-button>
  36. <!-- <el-button type="primary" class="customer-bun-min" @click="openDialog()">新增报价</el-button> -->
  37. </el-form-item>
  38. </el-form>
  39. <!-- 列表 -->
  40. <el-table :data="dataList" :height="height" border highlight-current-row v-loading="loading" style="width:100%" stripe>
  41. <el-table-column fixed="right" :label="'操作'" header-align="center" align="center" width="140">
  42. <template slot-scope="scope">
  43. <a class="customer-a" @click="openDialog(scope.row)">编辑 |</a>
  44. <a class="customer-a" @click="handleDelete(scope.row)">删除</a>
  45. </template>
  46. </el-table-column>
  47. <el-table-column prop="status" :label="'状态'" min-width="100" header-align="center" align="center">
  48. <template slot-scope="scope">
  49. {{ getStatusLabel(scope.row.status) }}
  50. <!-- <el-tag :type="getStatusType(scope.row.status)" size="small">{{ getStatusLabel(scope.row.status) }}</el-tag> -->
  51. </template>
  52. </el-table-column>
  53. <el-table-column prop="orderNo" :label="'报价单号'" min-width="150" header-align="center" align="left" show-overflow-tooltip />
  54. <el-table-column prop="itemNo" :label="'序号'" min-width="80" header-align="center" align="center" />
  55. <el-table-column prop="seqNo" :label="'报价次数'" min-width="100" header-align="center" align="center" />
  56. <el-table-column prop="createdDate" :label="'报价时间'" min-width="160" header-align="center" align="center" />
  57. <el-table-column prop="supplierId" :label="'供应商编码'" min-width="120" header-align="center" align="left" show-overflow-tooltip />
  58. <el-table-column prop="supplierName" :label="'供应商名称'" min-width="150" header-align="center" align="left" show-overflow-tooltip />
  59. <el-table-column prop="partNo" :label="'物料编码'" min-width="140" header-align="center" align="left" show-overflow-tooltip />
  60. <el-table-column prop="partDesc" :label="'物料名称'" min-width="180" header-align="center" align="left" show-overflow-tooltip />
  61. <el-table-column prop="qty" :label="'数量'" min-width="100" header-align="center" align="right" />
  62. <el-table-column prop="umid" :label="'计量单位'" min-width="100" header-align="center" align="center" />
  63. <el-table-column prop="remark2" :label="'特殊要求'" min-width="150" header-align="center" align="left" show-overflow-tooltip />
  64. <el-table-column prop="materialCost" :label="'材料费用'" min-width="120" header-align="center" align="right">
  65. <template slot-scope="scope">
  66. {{ formatMoney(scope.row.materialCost) }}
  67. </template>
  68. </el-table-column>
  69. <el-table-column prop="produceFee" :label="'加工费'" min-width="100" header-align="center" align="right">
  70. <template slot-scope="scope">
  71. {{ formatMoney(scope.row.produceFee) }}
  72. </template>
  73. </el-table-column>
  74. <el-table-column prop="surfaceFee" :label="'表面处理费'" min-width="120" header-align="center" align="right">
  75. <template slot-scope="scope">
  76. {{ formatMoney(scope.row.surfaceFee) }}
  77. </template>
  78. </el-table-column>
  79. <el-table-column prop="profit" :label="'利润'" min-width="100" header-align="center" align="right">
  80. <template slot-scope="scope">
  81. {{ formatMoney(scope.row.profit) }}
  82. </template>
  83. </el-table-column>
  84. <el-table-column prop="price" :label="'未税单价'" min-width="120" header-align="center" align="right">
  85. <template slot-scope="scope">
  86. {{ formatMoney(scope.row.price) }}
  87. </template>
  88. </el-table-column>
  89. <el-table-column prop="taxRate" :label="'税率(%)'" min-width="100" header-align="center" align="center" />
  90. <el-table-column prop="tax" :label="'含税单价'" min-width="120" header-align="center" align="right">
  91. <template slot-scope="scope">
  92. {{ formatMoney(scope.row.tax) }}
  93. </template>
  94. </el-table-column>
  95. <el-table-column prop="duty" :label="'关税'" min-width="100" header-align="center" align="right">
  96. <template slot-scope="scope">
  97. {{ formatMoney(scope.row.duty) }}
  98. </template>
  99. </el-table-column>
  100. <el-table-column prop="purchaseCycle" :label="'采购周期(天)'" min-width="120" header-align="center" align="center" />
  101. <el-table-column prop="mouldFee" :label="'模具费'" min-width="100" header-align="center" align="right">
  102. <template slot-scope="scope">
  103. {{ formatMoney(scope.row.mouldFee) }}
  104. </template>
  105. </el-table-column>
  106. <el-table-column prop="additionalCost" :label="'附加费用'" min-width="100" header-align="center" align="right">
  107. <template slot-scope="scope">
  108. {{ formatMoney(scope.row.additionalCost) }}
  109. </template>
  110. </el-table-column>
  111. <el-table-column prop="freight" :label="'运费'" min-width="100" header-align="center" align="right">
  112. <template slot-scope="scope">
  113. {{ formatMoney(scope.row.freight) }}
  114. </template>
  115. </el-table-column>
  116. <el-table-column prop="reason" :label="'原因'" min-width="150" header-align="center" align="left" show-overflow-tooltip />
  117. <el-table-column prop="remark" :label="'备注'" min-width="150" header-align="center" align="left" show-overflow-tooltip />
  118. <el-table-column prop="createdBy" :label="'报价人'" min-width="120" header-align="center" align="center" />
  119. <el-table-column prop="wantReplyDate" :label="'要求报价时间'" min-width="160" header-align="center" align="center" />
  120. <el-table-column prop="buyer" :label="'采购员'" min-width="120" header-align="center" align="center" />
  121. <el-table-column prop="paymentTerm" :label="'付款方式'" min-width="120" header-align="center" align="center" />
  122. <el-table-column prop="deliveryTerm" :label="'交货条款'" min-width="120" header-align="center" align="center" />
  123. <el-table-column prop="currency" :label="'货币'" min-width="80" header-align="center" align="center" />
  124. <el-table-column prop="contact" :label="'联系人'" min-width="120" header-align="center" align="center" />
  125. <el-table-column prop="phoneNo" :label="'联系电话'" min-width="130" header-align="center" align="center" />
  126. <el-table-column prop="faxNo" :label="'传真'" min-width="130" header-align="center" align="center" />
  127. <el-table-column prop="otherCondition" :label="'其他要求'" min-width="180" header-align="center" align="left" show-overflow-tooltip />
  128. </el-table>
  129. <!-- 分页 -->
  130. <el-pagination
  131. style="margin-top:10px"
  132. @size-change="sizeChangeHandle"
  133. @current-change="currentChangeHandle"
  134. :current-page="pageIndex"
  135. :page-sizes="[20,50,100,200,500]"
  136. :page-size="pageSize"
  137. :total="totalPage"
  138. layout="total, sizes, prev, pager, next, jumper" />
  139. <!-- 新增 / 编辑 弹窗 -->
  140. <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="800px" :close-on-click-modal="false" v-drag>
  141. <el-form label-position="top" class="pi-form" :model="form" label-width="120px">
  142. <!-- 基础信息 -->
  143. <div class="form-section">
  144. <el-row :gutter="20">
  145. <el-col :span="6">
  146. <el-form-item label="物料编码" prop="partNo">
  147. <el-input v-model="form.partNo" :disabled="true" placeholder="物料编码"></el-input>
  148. </el-form-item>
  149. </el-col>
  150. <el-col :span="18">
  151. <el-form-item label="物料名称" prop="partDesc">
  152. <el-input v-model="form.partDesc" :disabled="true" placeholder="物料名称"></el-input>
  153. </el-form-item>
  154. </el-col>
  155. </el-row>
  156. <el-row :gutter="20">
  157. <el-col :span="18">
  158. <el-form-item label="规格型号" prop="spec">
  159. <el-input v-model="form.spec" :disabled="true" placeholder="规格型号"></el-input>
  160. </el-form-item>
  161. </el-col>
  162. <el-col :span="6">
  163. <el-form-item label="询价数量" prop="qty">
  164. <el-input-number v-model="form.qty" :disabled="true" :min="0" style="width: 100%"></el-input-number>
  165. </el-form-item>
  166. </el-col>
  167. </el-row>
  168. <el-row :gutter="20">
  169. <el-col :span="18">
  170. <el-form-item label="其他要求" prop="otherCondition">
  171. <el-input v-model="form.otherCondition" type="text" :disabled="true" :rows="1" placeholder="其他要求"></el-input>
  172. </el-form-item>
  173. </el-col>
  174. <el-col :span="6">
  175. <el-form-item label="计量单位" prop="umid">
  176. <el-input v-model="form.umid" :disabled="true" placeholder="计量单位"></el-input>
  177. </el-form-item>
  178. </el-col>
  179. </el-row>
  180. </div>
  181. <!-- 费用信息 -->
  182. <div class="form-section">
  183. <el-row :gutter="20">
  184. <el-col :span="6">
  185. <el-form-item label="材料费用" prop="materialCost">
  186. <el-input-number v-model="form.materialCost" @change="calculatePrice" :precision="2" :min="0" style="width: 100%"></el-input-number>
  187. </el-form-item>
  188. </el-col>
  189. <el-col :span="6">
  190. <el-form-item label="加工费" prop="produceFee">
  191. <el-input-number v-model="form.produceFee" @change="calculatePrice" :precision="2" :min="0" style="width: 100%"></el-input-number>
  192. </el-form-item>
  193. </el-col>
  194. <el-col :span="6">
  195. <el-form-item label="表面处理费" prop="surfaceFee">
  196. <el-input-number v-model="form.surfaceFee" @change="calculatePrice" :precision="2" :min="0" style="width: 100%"></el-input-number>
  197. </el-form-item>
  198. </el-col>
  199. <el-col :span="6">
  200. <el-form-item label="利润" prop="profit">
  201. <el-input-number v-model="form.profit" @change="calculatePrice" :precision="2" :min="0" style="width: 100%"></el-input-number>
  202. </el-form-item>
  203. </el-col>
  204. </el-row>
  205. <!-- 价格信息 -->
  206. <div class="form-section">
  207. <el-row :gutter="20">
  208. <el-col :span="6">
  209. <el-form-item label="未税单价" prop="price">
  210. <el-input-number v-model="form.price" :disabled="true" :precision="4" :min="0" style="width: 100%" @change="calculateTax"></el-input-number>
  211. </el-form-item>
  212. </el-col>
  213. <el-col :span="6">
  214. <el-form-item label="税率(%)" prop="taxRate">
  215. <el-input-number v-model="form.taxRate" :disabled="true" :precision="2" :min="0" :max="100" style="width: 100%" @change="calculateTax"></el-input-number>
  216. </el-form-item>
  217. </el-col>
  218. <el-col :span="6">
  219. <el-form-item label="含税单价" prop="tax">
  220. <el-input-number v-model="form.tax" :disabled="true" :precision="4" :min="0" style="width: 100%"></el-input-number>
  221. </el-form-item>
  222. </el-col>
  223. <el-col :span="6">
  224. <el-form-item label="关税" prop="duty">
  225. <el-input-number v-model="form.duty" :precision="2" :min="0" style="width: 100%"></el-input-number>
  226. </el-form-item>
  227. </el-col>
  228. </el-row>
  229. </div>
  230. <el-row :gutter="20">
  231. <el-col :span="6">
  232. <el-form-item label="采购周期(天)" prop="purchaseCycle">
  233. <el-input-number v-model="form.purchaseCycle" :min="0" :precision="0" style="width: 100%"></el-input-number>
  234. </el-form-item>
  235. </el-col>
  236. <el-col :span="6">
  237. <el-form-item label="模具费" prop="mouldFee">
  238. <el-input-number v-model="form.mouldFee" :precision="2" :min="0" style="width: 100%"></el-input-number>
  239. </el-form-item>
  240. </el-col>
  241. <el-col :span="6">
  242. <el-form-item label="附加费用" prop="additionalCost">
  243. <el-input-number v-model="form.additionalCost" :precision="2" :min="0" style="width: 100%"></el-input-number>
  244. </el-form-item>
  245. </el-col>
  246. <el-col :span="6">
  247. <el-form-item label="运费" prop="freight">
  248. <el-input-number v-model="form.freight" :precision="2" :min="0" style="width: 100%"></el-input-number>
  249. </el-form-item>
  250. </el-col>
  251. </el-row>
  252. </div>
  253. <!-- 其他信息 -->
  254. <div class="form-section">
  255. <el-row :gutter="20">
  256. <el-col :span="24">
  257. <el-form-item label="特殊要求" prop="remark2">
  258. <el-input v-model="form.remark2" type="textarea" :disabled="true" :rows="1" placeholder="请输入特殊要求"></el-input>
  259. </el-form-item>
  260. </el-col>
  261. </el-row>
  262. <el-row :gutter="20">
  263. <el-col :span="24">
  264. <el-form-item label="备注" prop="remark">
  265. <el-input v-model="form.remark" type="textarea" :rows="1" placeholder="请输入备注"></el-input>
  266. </el-form-item>
  267. </el-col>
  268. </el-row>
  269. </div>
  270. </el-form>
  271. <div slot="footer" class="dialog-footer" style="margin-top: 20px">
  272. <el-button type="primary" @click="submitForm" :loading="submitLoading">保存</el-button>
  273. <el-button @click="dialogVisible=false">取消</el-button>
  274. </div>
  275. </el-dialog>
  276. </div>
  277. </template>
  278. <script>
  279. import {
  280. searchPurReplyHistPage,
  281. createPurReplyHist,
  282. updatePurReplyHist,
  283. deletePurReplyHist } from '@/api/supplier/purReplyHist.js'
  284. export default {
  285. name: 'MyQuotation',
  286. data() {
  287. return {
  288. height: 200,
  289. loading: false,
  290. submitLoading: false,
  291. dataList: [],
  292. pageIndex: 1,
  293. pageSize: 20,
  294. totalPage: 0,
  295. searchData: {
  296. site: this.$store.state.user.site,
  297. createdBy: this.$store.state.user.name,
  298. orderNo: '',
  299. partNo: '',
  300. partDesc: '',
  301. status: ''
  302. },
  303. dialogVisible: false,
  304. dialogTitle: '新增报价',
  305. editMode: false,
  306. form: {
  307. id: '',
  308. status: 'pending',
  309. orderNo: '',
  310. itemNo: '',
  311. seqNo: '',
  312. createdDate: '',
  313. supplierId: '',
  314. supplierName: '',
  315. partNo: '',
  316. partDesc: '',
  317. qty: 0,
  318. umid: '',
  319. remark2: '',
  320. materialCost: 0,
  321. produceFee: 0,
  322. surfaceFee: 0,
  323. profit: 0,
  324. price: 0,
  325. taxRate: 13,
  326. tax: 0,
  327. duty: 0,
  328. purchaseCycle: 0,
  329. mouldFee: 0,
  330. additionalCost: 0,
  331. freight: 0,
  332. reason: '',
  333. remark: '',
  334. createdBy: this.$store.state.user.name,
  335. wantReplyDate: '',
  336. employeeName: '',
  337. paymentTerm: '',
  338. deliveryTerm: '',
  339. currency: 'CNY',
  340. contact: '',
  341. phoneNo: '',
  342. faxNo: '',
  343. otherCondition: ''
  344. }
  345. }
  346. },
  347. mounted() {
  348. this.calcHeight()
  349. window.addEventListener('resize', this.calcHeight)
  350. this.getList()
  351. },
  352. beforeDestroy() {
  353. window.removeEventListener('resize', this.calcHeight)
  354. },
  355. methods: {
  356. calcHeight() {
  357. this.$nextTick(() => {
  358. this.height = window.innerHeight - 212
  359. })
  360. },
  361. getStatusType(status) {
  362. const map = {
  363. pending: 'warning',
  364. approved: 'success',
  365. rejected: 'danger'
  366. }
  367. return map[status] || 'info'
  368. },
  369. getStatusLabel(status) {
  370. const map = {
  371. pending: '待审核',
  372. approved: '已通过',
  373. rejected: '已拒绝'
  374. }
  375. return map[status] || status
  376. },
  377. formatMoney(value) {
  378. if (value === null || value === undefined) return '-'
  379. return new Intl.NumberFormat('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(value)
  380. },
  381. getList() {
  382. this.loading = true
  383. const params = {
  384. limit: this.pageSize,
  385. page: this.pageIndex,
  386. ...this.searchData
  387. }
  388. searchPurReplyHistPage(params).then(({ data }) => {
  389. if (data.code === 0) {
  390. this.dataList = data.page.list
  391. this.pageIndex = data.page.currPage
  392. this.pageSize = data.page.pageSize
  393. this.totalPage = data.page.totalCount
  394. } else {
  395. this.$message.error((data && data.msg) || '获取列表失败')
  396. }
  397. this.loading = false
  398. }).catch(() => {
  399. this.loading = false
  400. this.$message.error('请求失败')
  401. })
  402. },
  403. sizeChangeHandle(val) {
  404. this.pageSize = val
  405. this.pageIndex = 1
  406. this.getList()
  407. },
  408. currentChangeHandle(val) {
  409. this.pageIndex = val
  410. this.getList()
  411. },
  412. openDialog(row) {
  413. if (row) {
  414. this.dialogTitle = '编辑报价'
  415. this.editMode = true
  416. this.form = { ...row }
  417. } else {
  418. this.dialogTitle = '新增报价'
  419. this.editMode = false
  420. this.form = {
  421. id: '',
  422. status: '已报价',
  423. orderNo: '',
  424. itemNo: '',
  425. seqNo: '',
  426. createdDate: new Date().toISOString(),
  427. supplierId: '',
  428. supplierName: '',
  429. partNo: '',
  430. partDesc: '',
  431. qty: 0,
  432. umid: '',
  433. remark2: '',
  434. materialCost: 0,
  435. produceFee: 0,
  436. surfaceFee: 0,
  437. profit: 0,
  438. price: 0,
  439. taxRate: 13,
  440. tax: 0,
  441. duty: 0,
  442. purchaseCycle: 0,
  443. mouldFee: 0,
  444. additionalCost: 0,
  445. freight: 0,
  446. reason: '',
  447. remark: '',
  448. createdBy: this.$store.state.user.name,
  449. wantReplyDate: '',
  450. employeeName: '',
  451. paymentTerm: '',
  452. deliveryTerm: '',
  453. currency: 'CNY',
  454. contact: '',
  455. phoneNo: '',
  456. faxNo: '',
  457. otherCondition: ''
  458. }
  459. }
  460. // 计算含税单价:
  461. this.calculatePrice()
  462. // this.calculateTax()
  463. this.quoteDialogVisible = true
  464. this.dialogVisible = true
  465. },
  466. calculatePrice(){
  467. //未税单价=材料成本+加工费+表面费用+利润
  468. this.form.price = this.form.materialCost + this.form.produceFee +
  469. this.form.surfaceFee + this.form.profit
  470. this.calculateTax()
  471. },
  472. // 计算含税单价
  473. calculateTax() {
  474. //含税单价=未税单价*(1+税率)
  475. if (this.form.price && this.form.taxRate) {
  476. this.form.tax = this.form.price * (1 + this.form.taxRate / 100)
  477. }
  478. },
  479. validateForm() {
  480. if (!this.form.partNo) {
  481. this.$message.warning('物料编码不能为空')
  482. return false
  483. }
  484. if (!this.form.partDesc) {
  485. this.$message.warning('物料名称不能为空')
  486. return false
  487. }
  488. return true
  489. },
  490. submitForm() {
  491. if (!this.validateForm()) return
  492. this.submitLoading = true
  493. const api = this.editMode ? updatePurReplyHist : createPurReplyHist
  494. api(this.form).then(({ data }) => {
  495. if (data && data.code === 0) {
  496. this.$message.success('保存成功')
  497. this.dialogVisible = false
  498. this.getList()
  499. } else {
  500. this.$message.error((data && data.msg) || '保存失败')
  501. }
  502. }).catch(err => {
  503. this.$message.error('请求失败: ' + err.message)
  504. }).finally(() => {
  505. this.submitLoading = false
  506. })
  507. },
  508. handleDelete(row) {
  509. this.$confirm(`确定删除报价单: ${row.orderNo} ?`, '提示', { type: 'warning' }).then(() => {
  510. deletePurReplyHist({ id: row.id }).then(({ data }) => {
  511. if (data && data.code === 0) {
  512. this.$message.success('删除成功')
  513. this.getList()
  514. } else {
  515. this.$message.error((data && data.msg) || '删除失败')
  516. }
  517. }).catch(err => {
  518. this.$message.error('删除失败: ' + err.message)
  519. })
  520. }).catch(() => {})
  521. }
  522. }
  523. }
  524. </script>
  525. <style scoped>
  526. .pi-search-form { margin-top: 0; }
  527. .pi-form { margin-top: -5px; }
  528. .customer-a {
  529. cursor: pointer;
  530. color: #409EFF;
  531. margin: 0 4px;
  532. }
  533. .customer-a:hover {
  534. color: #66b1ff;
  535. }
  536. .customer-bun-min {
  537. margin-right: 10px;
  538. }
  539. </style>