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

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