index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. <template>
  2. <div class="app-container">
  3. <div class="head-container" style="margin: 10px 0 10px 0;">
  4. <!-- 搜索 -->
  5. <el-input
  6. v-model="query.value"
  7. clearable
  8. placeholder="请输入标题"
  9. style="width: 200px;"
  10. size="small"
  11. class="filter-item"
  12. />
  13. <el-button class="filter-item" size="small" type="primary" icon="el-icon-search" plain @click="handleFind">搜索</el-button>
  14. <el-button
  15. class="filter-item"
  16. size="small"
  17. type="primary"
  18. icon="el-icon-plus"
  19. @click="handleAdd"
  20. >发布新标
  21. </el-button>
  22. </div>
  23. <!--表格渲染-->
  24. <el-table v-loading="loading" :data="data" style="width: 100%;">
  25. <el-table-column label="序号" fixed="left" width="60" align="center">
  26. <template slot-scope="scope">
  27. <span>{{ scope.$index + 1 }}</span>
  28. </template>
  29. </el-table-column>
  30. <el-table-column prop="title" label="标题" :show-overflow-tooltip="true" width="250" align="center" />
  31. <el-table-column label="状态" align="center" width="100">
  32. <template slot-scope="scope">
  33. <el-tag v-if="scope.row.status ==1">进行中</el-tag>
  34. <el-tag v-if="scope.row.status ==2" type="info">已结束</el-tag>
  35. <el-tag v-if="scope.row.status ==3" type="danger">已作废</el-tag>
  36. </template>
  37. </el-table-column>
  38. <el-table-column prop="description" :show-overflow-tooltip="true" label="报价方式" width="100" align="center">
  39. <template slot-scope="scope">
  40. <el-tag v-if="scope.row.priceQuotes == 1" color="#5783E6" style="border-color:#5783E6" effect="dark">总价</el-tag>
  41. <el-tag v-if="scope.row.priceQuotes == 2" effect="dark" color="#82C497" style="border-color:#82C497">单价</el-tag>
  42. </template>
  43. </el-table-column>
  44. <el-table-column prop="remarks" label="备注" :show-overflow-tooltip="true" align="center" />
  45. <el-table-column prop="appendix" label="附件" align="center" width="100">
  46. <template slot-scope="scope">
  47. <el-button type="text" @click="onLoad(scope.row.appendix)">下载</el-button>
  48. </template>
  49. </el-table-column>
  50. <el-table-column prop="createTime" label="开始时间" align="center" width="160" />
  51. <el-table-column prop="endTime" label="截止时间" align="center" width="160" />
  52. <el-table-column label="操作" width="150" fixed="right" align="center">
  53. <template slot-scope="scope">
  54. <el-button v-if="scope.row.status == 1" slot="reference" type="text" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
  55. <el-popover
  56. :ref="scope.row.id"
  57. placement="bottom"
  58. width="180"
  59. >
  60. <p>此操作将作废该标,确定要作废吗?</p>
  61. <div style="text-align: right; margin: 0">
  62. <el-button size="mini" @click="$refs[scope.row.id].doClose()">取消</el-button>
  63. <el-button :loading="delLoading" type="primary" size="mini" @click="subDelete(scope.row.id)">确定
  64. </el-button>
  65. </div>
  66. <el-button v-if="scope.row.status == 1" slot="reference" icon="el-icon-delete" type="text">作废</el-button>
  67. </el-popover>
  68. <el-button v-if="scope.row.status != 1" slot="reference" icon="el-icon-view" type="text" @click="handleView(scope.row)">投标详情</el-button>
  69. </template>
  70. </el-table-column>
  71. </el-table>
  72. <!--分页-->
  73. <div class="pagination">
  74. <el-pagination
  75. :current-page.sync="currentPage"
  76. :page-sizes="[1,10, 20, 30, 50]"
  77. :page-size="pageSize"
  78. layout="total, sizes, prev, pager, next, jumper"
  79. :total="total"
  80. background
  81. @size-change="handleSizeChange"
  82. @current-change="handleCurrentChange"
  83. />
  84. </div>
  85. <!--新增-->
  86. <el-dialog :append-to-body="true" :close-on-click-modal="false" :visible.sync="dialog" :title="isAdd ? '发布新标' : '修改新标'" width="40%">
  87. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  88. <el-form-item label="标题" prop="title">
  89. <div class="padding" style="width: 370px;">
  90. <el-input v-model="form.title" maxlength="200" show-word-limit placeholder="请输入标题" />
  91. </div>
  92. </el-form-item>
  93. <el-form-item label="备注" prop="remarks">
  94. <el-input
  95. v-model="form.remarks"
  96. type="textarea"
  97. style="width: 370px;"
  98. :autosize="{ minRows: 2, maxRows: 10}"
  99. placeholder="请输入内容"
  100. maxlength="500"
  101. show-word-limit
  102. />
  103. </el-form-item>
  104. <el-form-item label="附件" prop="appendix" class="is-required">
  105. <el-upload
  106. class="upload-demo"
  107. drag
  108. :limit="1"
  109. :on-preview="handlePreview"
  110. :on-change="handleChange"
  111. :on-remove="handleRemove"
  112. :before-remove="beforeRemove"
  113. :on-exceed="handleExceed"
  114. :on-error="hanndleErr"
  115. :action="BASE_API+'/tender/upload'"
  116. list-type="text"
  117. :file-list="fileList"
  118. multiple
  119. >
  120. <i class="el-icon-upload" />
  121. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  122. <!-- <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div> -->
  123. </el-upload>
  124. </el-form-item>
  125. <el-form-item label="报价方式" prop="priceQuotes">
  126. <el-radio v-model="form.priceQuotes" :label="1">总价</el-radio>
  127. <el-radio v-model="form.priceQuotes" :label="2">单价</el-radio>
  128. </el-form-item>
  129. <el-form-item label="发布时间" prop="startTime">
  130. <!-- <el-date-picker
  131. v-model="form.startTime"
  132. type="datetime"
  133. @change="oncustom"
  134. size="mini"
  135. value-format="yyyy-MM-dd HH:mm:ss"
  136. default-time="00:00:00"
  137. placeholder="开始日期"
  138. >
  139. </el-date-picker>
  140. <span> ~ </span>
  141. <el-date-picker
  142. v-model="form.endTime"
  143. type="datetime"
  144. size="mini"
  145. value-format="yyyy-MM-dd HH:mm:ss"
  146. default-time="15:00:00"
  147. placeholder="截止日期"
  148. >
  149. </el-date-picker> -->
  150. <el-date-picker
  151. v-model="bidDate"
  152. type="datetimerange"
  153. size="mini"
  154. range-separator="~"
  155. value-format="yyyy-MM-dd HH:mm:ss"
  156. :default-time="['00:00:00', '15:00:00']"
  157. start-placeholder="开始日期"
  158. end-placeholder="结束日期"
  159. @change="oncustom"
  160. @clear="onClear"
  161. />
  162. </el-form-item>
  163. </el-form>
  164. <div slot="footer" class="dialog-footer">
  165. <el-button @click="dialog = false">取消</el-button>
  166. <el-button :loading="buton" type="primary" @click="doSubmit">确认</el-button>
  167. </div>
  168. </el-dialog>
  169. <!-- 详情 -->
  170. <el-dialog :append-to-body="true" :visible.sync="viewDialog" title="投标详情" width="90%" center>
  171. <el-table center :data="Paramdata" style="width: 100%;">
  172. <el-table-column prop="customerName" label="客户名称" show-overflow-tooltip="true" align="center" />
  173. <el-table-column label="报价方式" align="center">
  174. <template slot-scope="scope">
  175. <el-tag v-if="scope.row.priceQuotes == 1" color="#5783E6" style="border-color:#5783E6" effect="dark">总价</el-tag>
  176. <el-tag v-if="scope.row.priceQuotes == 2" effect="dark" color="#82C497" style="border-color:#82C497">单价</el-tag>
  177. </template>
  178. </el-table-column>
  179. <el-table-column prop="price" :show-overflow-tooltip="true" label="报价金额" align="center">
  180. <template slot-scope="scope">
  181. <div>
  182. {{ scope.row.price | toThousandFilter }}
  183. </div>
  184. </template>
  185. </el-table-column>
  186. <el-table-column prop="remarks" label="备注" :show-overflow-tooltip="true" align="center" />
  187. <el-table-column prop="appendix" label="附件" align="center" width="100">
  188. <template slot-scope="scope">
  189. <!-- <el-link type="primary" :href="scope.row.appendix">查看</el-link> -->
  190. <el-button type="text" @click="onLoad(scope.row.appendix)">下载</el-button>
  191. </template>
  192. </el-table-column>
  193. <el-table-column prop="createTime" label="投标时间" align="center" />
  194. <el-table-column prop="userName" label=" 投标帐号" align="center" />
  195. <el-table-column prop="status" label=" 投标结果" align="center">
  196. <template slot-scope="scope">
  197. <el-tag v-if="scope.row.status == 0" type="warning">已提交</el-tag>
  198. <el-tag v-if="scope.row.status == 1" type="success">已中标</el-tag>
  199. <el-tag v-if="scope.row.status == 2" type="danger">未中标</el-tag>
  200. </template>
  201. </el-table-column>
  202. </el-table>
  203. <div class="pagination">
  204. <el-pagination
  205. :current-page.sync="param.page"
  206. :page-size="param.size"
  207. layout="total, sizes, prev, pager, next, jumper"
  208. :total="total1"
  209. :page-sizes="[10, 20, 30, 50]"
  210. background
  211. @size-change="handleSizeChangeParam"
  212. @current-change="handleCurrentChangeParam"
  213. />
  214. </div>
  215. <div slot="footer" class="dialog-footer">
  216. <el-button @click="viewDialog = false">取消</el-button>
  217. <el-button :loading="loading" type="primary" @click="viewDialog = false">确认</el-button>
  218. </div>
  219. </el-dialog>
  220. </div>
  221. </template>
  222. <script>
  223. import { getTableList, getQueryId, getQueryAdd, getQueryEdit, getQueryDelete, loadCustomer } from '@/api/bid'
  224. import { Notification, MessageBox } from 'element-ui'
  225. export default {
  226. data() {
  227. const checkTel = (rule, value, callback) => {
  228. console.log(this.form.appendix)
  229. console.log(value, 'value')
  230. if (this.form.appendix == null || this.form.appendix == '') {
  231. callback(new Error('请选择附件'))
  232. console.log('没过')
  233. } else {
  234. callback()
  235. console.log('过')
  236. }
  237. }
  238. return {
  239. form: {
  240. },
  241. data: [],
  242. fileList: [],
  243. BASE_API: process.env.BASE_API,
  244. dialog: false,
  245. delLoading: false,
  246. viewDialog: false,
  247. loading: false,
  248. isAdd: false,
  249. currentPage: 1,
  250. pageSize: 10,
  251. total: 0, // 总数量
  252. rules: {
  253. title: [
  254. { required: true, message: '标题不为空', trigger: 'blur' }
  255. ],
  256. priceQuotes: [
  257. { required: true, message: '请选择报价方式', trigger: 'blur' }
  258. ],
  259. appendix: [
  260. { validator: checkTel, trigger: 'change' }
  261. ]
  262. // startTime: [
  263. // { type:"array",required: true, message: '发布时间不为空', trigger: 'blur' }
  264. // ]
  265. },
  266. queryTypeOptions: [
  267. { key: 'name', display_name: '字典名称' },
  268. { key: 'remark', display_name: '描述' }
  269. ],
  270. query: {
  271. type: '',
  272. value: ''
  273. },
  274. param: {
  275. page: 1,
  276. size: 10
  277. },
  278. total1: 0,
  279. Paramdata: [],
  280. bidDate: [],
  281. buton: false
  282. }
  283. },
  284. created() {
  285. this.getDictData()
  286. },
  287. methods: {
  288. // 发布时间
  289. oncustom() {
  290. console.log(this.bidDate)
  291. if (this.bidDate != null) {
  292. this.form.startTime = this.bidDate[0]
  293. this.form.endTime = this.bidDate[1]
  294. }
  295. },
  296. onClear() {
  297. this.bidDate = []
  298. console.log(this.form)
  299. },
  300. // 下载
  301. onLoad(row) {
  302. // const params = new URLSearchParams()
  303. // params.append('path', row)
  304. const a = document.createElement('a')
  305. // a.href= /bidding/load
  306. const url = window.location.origin + process.env.BASE_API + '/bidding/load?path=' + encodeURIComponent(row)
  307. a.href = url
  308. a.click()
  309. },
  310. // 搜索
  311. handleFind: function() {
  312. this.currentPage = 1
  313. this.getDictData()
  314. },
  315. // 获取详情
  316. getDictData: function() {
  317. this.loading = true
  318. // const params = new URLSearchParams()
  319. // params.append('current', this.currentPage)
  320. // params.append('size', this.pageSize)
  321. const data = {
  322. page: this.currentPage,
  323. size: this.pageSize,
  324. title: this.query.value
  325. }
  326. getTableList(data).then(res => {
  327. console.log(res)
  328. this.data = res.data.data.records
  329. this.total = res.data.data.total
  330. this.loading = false
  331. })
  332. },
  333. // 文件移除的时候
  334. handleRemove(file, fileList) {
  335. this.form.appendix = ''
  336. console.log(file, fileList, this.fileList, '移出')
  337. },
  338. // 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
  339. handleChange(file, fileList) {
  340. console.log(file, fileList, '上传')
  341. if (file.response) {
  342. console.log(file.response, 'file')
  343. if (file.response.code == '200') {
  344. this.form.appendix = file.response.data
  345. } else {
  346. Notification.error({
  347. title: file.response.msg,
  348. duration: 1000
  349. })
  350. this.fileList = []
  351. }
  352. }
  353. },
  354. // 点击文件列表中已上传的文件时的钩子
  355. handlePreview(file) {
  356. console.log(file, 'file1')
  357. // window.location.href = file.url
  358. },
  359. handleExceed(files, fileList) {
  360. this.$message.warning(`当前限制选择 1 个附件,本次选择了 ${files.length} 个文件`)
  361. },
  362. hanndleErr(err, files, fileList) {
  363. console.log(err, 'err')
  364. console.log(files, 'err')
  365. console.log(fileList, 'err')
  366. },
  367. beforeRemove(file, fileList) {
  368. return this.$confirm(`确定移除 ${file.name}?`)
  369. },
  370. // 字典名称提交动作
  371. doSubmit() {
  372. console.log(this.form)
  373. this.$refs['form'].validate((valid) => {
  374. console.log(valid)
  375. if (valid) {
  376. if (this.isAdd) {
  377. // 新增字典
  378. this.buton = true
  379. getQueryAdd(this.form).then((res) => {
  380. if (res.data.code === 200) {
  381. this.dialog = false
  382. this.getDictData()
  383. this.buton = false
  384. this.$message({ message: '操作成功', type: 'success' })
  385. } else {
  386. this.$message({ message: res.data.msg, type: 'error' })
  387. }
  388. this.$refs['form'].resetFields()
  389. }).catch(err => {
  390. this.buton = false
  391. })
  392. } else {
  393. // 更新
  394. getQueryEdit(this.form).then((res) => {
  395. if (res.data.code === 200) {
  396. this.$message({ message: '操作成功', type: 'success' })
  397. } else {
  398. this.$message({ message: res.data.msg, type: 'error' })
  399. }
  400. this.dialog = false
  401. this.getDictData()
  402. })
  403. }
  404. }
  405. })
  406. },
  407. formatDate(date) {
  408. var myyear = date.getFullYear()
  409. var mymonth = date.getMonth() + 1
  410. var myweekday = date.getDate()
  411. if (mymonth < 10) {
  412. mymonth = '0' + mymonth
  413. }
  414. if (myweekday < 10) {
  415. myweekday = '0' + myweekday
  416. }
  417. return myyear + '-' + mymonth + '-' + myweekday
  418. },
  419. // 添加字典
  420. handleAdd: function() {
  421. this.isAdd = true
  422. this.form = {}
  423. const end = new Date()
  424. const start = new Date()
  425. end.setTime(start.getTime() + 3600 * 1000 * 24 * 1)
  426. console.log(this.formatDate(end))
  427. this.form.startTime = this.formatDate(start) + ' 00:00:00'
  428. this.form.endTime = this.formatDate(end) + ' 15:00:00'
  429. this.bidDate = [this.form.startTime, this.form.endTime]
  430. this.form.appendix = null
  431. this.fileList = []
  432. this.dialog = true
  433. if (this.$refs['form']) {
  434. this.$refs['form'].resetFields()
  435. }
  436. },
  437. // 编辑字典
  438. handleEdit: function(row) {
  439. if (this.$refs['form']) {
  440. this.$refs['form'].resetFields()
  441. }
  442. const data = JSON.parse(JSON.stringify(row))
  443. this.form = data
  444. this.bidDate = [data.createTime, data.endTime]
  445. // this.form.
  446. // let name = data.appendix.lastIndexOf('/') ;
  447. if (data.appendix) {
  448. let name = data.appendix.split('tender/')
  449. name = name.pop()
  450. // let name = data.appendix.replace(/(.*\/)*([^.]+).*/ig, "$2");
  451. this.fileList = [{ name: name, url: data.appendix }]
  452. }
  453. this.dialog = true
  454. this.isAdd = false
  455. console.log(data)
  456. },
  457. // 详情
  458. handleView(row) {
  459. this.param.tenderId = row.id
  460. this.param.page = 1
  461. this.getParam()
  462. this.viewDialog = true
  463. },
  464. getParam() {
  465. const data = this.param
  466. getQueryId(data).then((res) => {
  467. console.log(res.data.data.records, '')
  468. this.Paramdata = res.data.data.records
  469. this.total1 = res.data.data.total
  470. })
  471. },
  472. // 删除操作
  473. subDelete(val) {
  474. const data = {
  475. id: val
  476. }
  477. getQueryDelete(data).then(res => {
  478. if (res.data.code === 200) {
  479. this.$message({ message: '已作废', type: 'success' })
  480. this.getDictData()
  481. }
  482. }).catch(err => {
  483. console.log(err.response.data.message)
  484. })
  485. this.$refs[val].doClose()
  486. },
  487. // 换页
  488. handleCurrentChange: function(val) {
  489. this.currentPage = val
  490. this.getDictData()
  491. },
  492. handleSizeChange(val) {
  493. this.pageSize = val
  494. this.getDictData()
  495. },
  496. handleCurrentChangeParam(val) {
  497. this.param.page = val
  498. this.getParam()
  499. },
  500. handleSizeChangeParam(val) {
  501. this.param.size = val
  502. this.getParam()
  503. }
  504. }
  505. }
  506. </script>
  507. <style scoped>
  508. /* 去掉上传附件时候的过度效果 */
  509. ::v-deep .el-upload-list__item{transition: none !important;}
  510. ::v-deep .el-textarea__inner{
  511. padding-bottom: 36px;
  512. }
  513. .padding /deep/ .el-input--medium .el-input__inner {
  514. padding-right: 56px;
  515. }
  516. </style>