自主项目,食堂系统,前端uniapp
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.

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