自主产品,供应链食堂系统。将两个端拆开了。
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.

410 lines
10 KiB

  1. <template>
  2. <view>
  3. <view class="box">
  4. <view class="title">报价清单</view>
  5. <view class="lf-font-24 lf-color-gray lf-m-t-5">请在以下物资信息表内填写报价</view>
  6. </view>
  7. <!-- 修饰条 -->
  8. <self-line></self-line>
  9. <view class="box lf-row-between relation">
  10. <view>
  11. <text class="title">关联食堂</text>
  12. <text class="lf-font-24 lf-color-555 lf-m-l-10">(多选)</text>
  13. </view>
  14. <view class="lf-font-24 lf-color-gray lf-text-right lf-row-center" style="width: 370rpx; justify-content: flex-end;" @click="switchRelation">
  15. <view class="lf-line-1">{{ selectName }}</view>
  16. <u-icon name="arrow-right" class="lf-text-vertical"></u-icon>
  17. </view>
  18. <view class="mask" :style="{top: node_top +'px'}" v-if="is_show" @click="is_show = false">
  19. <view class="list">
  20. <view class="lf-row-between item" v-for="(item, index) in relation_list" :key="index" @click.stop="selectItem(index)">
  21. <view>{{ item.canteen_name }}</view>
  22. <u-icon name="checkmark-circle" color="#1833F2" size="40" v-if="item.checked"></u-icon>
  23. </view>
  24. </view>
  25. </view>
  26. </view>
  27. <self-line></self-line>
  28. <!-- 物料table -->
  29. <view class="box">
  30. <wyb-table :first-line-fixed="true"
  31. contentBgColor="#eef6fe"
  32. :headers="headers"
  33. :contents="contents"
  34. @onInputChange="onInputChange"
  35. @onButtonClick="onButtonClick"
  36. width="100%" height="80vh"></wyb-table>
  37. </view>
  38. <view style="height: 140rpx;"></view>
  39. <!-- 操作按钮 -->
  40. <view class="fixed-bottom">
  41. <button class="btn btn1" @click="save(0)">临时保存</button>
  42. <button class="btn btn2" @click="save(1)">直接报价</button>
  43. </view>
  44. </view>
  45. </template>
  46. <script>
  47. import wybTable from '@/components/wyb-table/wyb-table';
  48. let app = getApp();
  49. export default {
  50. components: {
  51. wybTable
  52. },
  53. data(){
  54. return {
  55. headers: [{
  56. label: '物资名称',
  57. key: 'name'
  58. },{
  59. label: '规格',
  60. key: 'spec'
  61. },{
  62. label: '品牌',
  63. key: 'brand'
  64. },{
  65. label: '品级',
  66. key: 'quality_level'
  67. },{
  68. label: '编号',
  69. key: 'number'
  70. },{
  71. label: '起购数',
  72. key: 'purchase_limit'
  73. },{
  74. label: '含税价',
  75. key: 'tax_price'
  76. },{
  77. label: '非含税价',
  78. key: 'non_tax_price'
  79. },{
  80. label: '操作',
  81. key: 'operation'
  82. }],
  83. contents: [],
  84. is_show: false,
  85. relation_list: [], // 关联食堂列表
  86. node_top: 0,
  87. code: '', // 订单号,批次号,如果有
  88. type: 0
  89. }
  90. },
  91. computed: {
  92. selectName(){
  93. let arr = [];
  94. this.relation_list.map(item => {
  95. if(item.checked){
  96. arr.push(item.canteen_name);
  97. }
  98. });
  99. let str = '请选择...';
  100. if(arr.length > 0){
  101. str = arr.join(',');
  102. }
  103. return str;
  104. }
  105. },
  106. onLoad(options){
  107. this.code = options.code || '';
  108. this.type = options.type || 0;
  109. if(options.type == 1){
  110. // 编辑,不可更换食堂
  111. this.materialListByOrder();
  112. }else if(options.type == 2){
  113. // 复用订单号
  114. this.materialListByOrder();
  115. }else if(options.type == 3){
  116. // 复用批次号
  117. this.materialListByBatch();
  118. }else{
  119. // 单纯发起报价
  120. this.getMaterialList();
  121. }
  122. },
  123. onReady(){
  124. let that = this;
  125. let info = uni.createSelectorQuery().select(".relation");
  126.     info.boundingClientRect(function(data) {
  127. let num = app.globalData.customBarH;
  128. num += data.height;
  129. num += data.top;
  130. that.node_top = num;
  131.    }).exec()
  132. },
  133. onPageScroll(){
  134. if(this.is_show){
  135. this.is_show = false;
  136. }
  137. },
  138. methods: {
  139. // 获取物资列表
  140. getMaterialList(){
  141. this.$http(this.API.API_SUPPLIER_MATERIALLIST).then(res => {
  142. let list = res.data.spec || [];
  143. let contents = list.map(item => {
  144. return {
  145. name: item?.material?.m_name || '',
  146. material_id: item?.material?.id || 0,
  147. spec: item.name,
  148. spec_id: item.id,
  149. brand: item?.material?.brand || '',
  150. quality_level: item?.material?.quality_level || '',
  151. number: item?.material?.m_sn || '',
  152. purchase_limit: {edit: true, value: 1},
  153. tax_price: {edit: true, value: ''},
  154. non_tax_price: {edit: true, value: ''},
  155. operation: {button: true, key: 'delete', value: '删除'}
  156. }
  157. })
  158. this.contents = contents;
  159. this.getCanteenList();
  160. })
  161. },
  162. // 复用报价订单号 & 编辑共用
  163. materialListByOrder(){
  164. this.$http(this.API.API_SUPPLIER_QUOTATIONREUSEBYORDER, {
  165. q_sn: this.code
  166. }).then(res => {
  167. console.log("materialListByOrder", res);
  168. let list = res.data.order || [];
  169. let canteen = res.data.canteen || [];
  170. let contents = list.map(item => {
  171. let obj = {
  172. name: item?.material?.m_name || '',
  173. material_id: item?.material?.id || 0,
  174. spec: item.name,
  175. spec_id: item.id,
  176. brand: item?.material?.brand || '',
  177. quality_level: item?.material?.quality_level || '',
  178. number: item?.material?.m_sn || '',
  179. purchase_limit: {edit: true, value: item?.quotation?.purchase_limit || ''},
  180. tax_price: {edit: true, value: item?.quotation?.tax_price || ''},
  181. non_tax_price: {edit: true, value: item?.quotation?.non_tax_price || ''},
  182. quotation_id: item?.quotation?.id || 0,
  183. operation: {button: true, key: 'delete', value: '删除'}
  184. }
  185. if(item?.material?.state && item?.material?.state != '启用'){
  186. obj.disabled = true;
  187. }
  188. return obj;
  189. })
  190. this.contents = contents;
  191. this.getCanteenList(canteen);
  192. })
  193. },
  194. // 复用批次号
  195. materialListByBatch(){
  196. this.$http(this.API.API_SUPPLIER_QUOTATIONREUSEBYBATCH, {
  197. batch_sn: this.code
  198. }).then(res => {
  199. console.log("materialListByBatch", res);
  200. let list = res.data.order || [];
  201. let canteen = res.data.canteen || [];
  202. let contents = list.map(item => {
  203. return {
  204. name: item?.material?.m_name || '',
  205. material_id: item?.material?.id || 0,
  206. spec: item.name,
  207. spec_id: item.id,
  208. brand: item?.material?.brand || '',
  209. quality_level: item?.material?.quality_level || '',
  210. number: item?.material?.m_sn || '',
  211. purchase_limit: {edit: true, value: item?.quotation?.purchase_limit || ''},
  212. tax_price: {edit: true, value: item?.quotation?.tax_price || ''},
  213. non_tax_price: {edit: true, value: item?.quotation?.non_tax_price || ''}
  214. }
  215. })
  216. this.contents = contents;
  217. this.getCanteenList(canteen);
  218. })
  219. },
  220. // 关联食堂列表
  221. getCanteenList(canteen = []){
  222. this.$http(this.API.API_SUPPLIER_CANTEENLIST).then(res => {
  223. let list = res.data.list.map(item => {
  224. item.checked = false;
  225. canteen.map(ct => {
  226. if(ct == item.id){
  227. item.checked = true;
  228. }
  229. })
  230. return item;
  231. })
  232. this.relation_list = list;
  233. })
  234. },
  235. // 监听表格被输入
  236. onInputChange(event){
  237. this.contents[event.contentIndex][event.key].value = event.detailValue;
  238. },
  239. // table操作按钮被点击
  240. onButtonClick(event){
  241. if(event.content.key == 'delete'){
  242. let contentIndex = event.lineData.contentIndex;
  243. this.contents.splice(contentIndex, 1);
  244. }
  245. },
  246. // 切换显示关联食堂modal
  247. switchRelation(){
  248. if(this.type == 1) return this.$msg('编辑不可更换关联食堂哦');
  249. this.is_show = !this.is_show;
  250. },
  251. // 选择食堂
  252. selectItem(index){
  253. this.relation_list[index].checked = !this.relation_list[index].checked;
  254. },
  255. // 报价订单编辑时保存
  256. editMaterial(_t){
  257. // 物资列表
  258. let list = [];
  259. this.contents.map(item => {
  260. list.push({
  261. id: item.quotation_id,
  262. tax_price: item.tax_price.value,
  263. non_tax_price: item.non_tax_price.value,
  264. purchase_limit: Number(item.purchase_limit.value) || 1
  265. })
  266. });
  267. // 操作状态,是保存还是直接发起
  268. let state = ['待发起', '待审核'][_t];
  269. this.$http(this.API.API_SUPPLIER_QUOTATIONSAVE, {
  270. data: list,
  271. state: state,
  272. q_sn: this.code
  273. }).then(res => {
  274. this.$msg('操作成功').then(result => {
  275. this.$toBack();
  276. })
  277. })
  278. },
  279. // 保存
  280. save(_t){
  281. // 拦截是编辑的情况
  282. if(this.type == 1){
  283. this.editMaterial(_t);
  284. return;
  285. }
  286. // 物资列表
  287. let list = [];
  288. this.contents.map(item => {
  289. if(item.tax_price.value && item.non_tax_price.value){
  290. list.push({
  291. m_id: item.material_id,
  292. m_spec_id: item.spec_id,
  293. tax_price: item.tax_price.value,
  294. non_tax_price: item.non_tax_price.value,
  295. purchase_limit: Number(item.purchase_limit.value) || 1
  296. })
  297. }
  298. });
  299. // 关联食堂
  300. let canteen_ids = [];
  301. this.relation_list.map(item => {
  302. if(item.checked){
  303. canteen_ids.push(item.id);
  304. }
  305. })
  306. if(canteen_ids.length <= 0){
  307. return this.$msg('您未选择关联食堂哦')
  308. }
  309. if(list.length <= 0){
  310. return this.$msg('没有需要报价的物资')
  311. }
  312. // 操作状态,是保存还是直接发起
  313. let state = ['待发起', '待审核'][_t];
  314. this.$http(this.API.API_SUPPLIER_QUOTATIONAPPLY, {
  315. data: list,
  316. state: state,
  317. canteen_ids: canteen_ids
  318. }).then(res => {
  319. this.$msg(res.data).then(result => {
  320. this.$toBack();
  321. })
  322. })
  323. }
  324. }
  325. }
  326. </script>
  327. <style>
  328. page{
  329. overflow: hidden;
  330. }
  331. </style>
  332. <style lang="scss" scoped="scoped">
  333. .lf-m-t-5{
  334. margin-top: 5rpx;
  335. }
  336. .box{
  337. padding: 30rpx 32rpx;
  338. width: 100%;
  339. height: max-content;
  340. box-sizing: border-box;
  341. }
  342. .title{
  343. color: #222222;
  344. font-size: 28rpx;
  345. font-weight: bold;
  346. }
  347. .fixed-bottom{
  348. position: fixed;
  349. bottom: 0rpx;
  350. left: 0rpx;
  351. z-index: 99;
  352. width: 750rpx;
  353. height: 98rpx;
  354. display: flex;
  355. justify-content: center;
  356. align-items: center;
  357. border-top: 1rpx solid #E5E5E5;
  358. background-color: #fff;
  359. .btn{
  360. width: 320rpx;
  361. height: 82rpx;
  362. border-radius: 41rpx;
  363. margin: 0;
  364. padding: 0;
  365. font-size: 32rpx;
  366. display: flex;
  367. justify-content: center;
  368. align-items: center;
  369. }
  370. .btn1{
  371. border: 2rpx solid #555555;
  372. opacity: .5;
  373. }
  374. .btn2{
  375. background: #1833F2;
  376. color: #FFFFFF;
  377. margin-left: 50rpx;
  378. }
  379. }
  380. .relation{
  381. position: relative;
  382. border-bottom: 1rpx solid #E5E5E5;
  383. }
  384. .mask{
  385. position: fixed;
  386. background-color: rgba(0,0,0,0.4);
  387. width: 100%;
  388. // top: 149px;
  389. bottom: 0;
  390. left: 0;
  391. z-index: 100;
  392. .list{
  393. min-height: max-content;
  394. max-height: 500rpx;
  395. overflow: scroll;
  396. background-color: #FFFFFF;
  397. width: 100%;
  398. .item{
  399. height: 92rpx;
  400. padding: 0 32rpx;
  401. border-bottom: 1rpx solid #E5E5E5;
  402. color: #222222;
  403. font-size: 28rpx;
  404. }
  405. }
  406. }
  407. </style>