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

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