edit.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <template>
  2. <div class="intelligentReplenishmentEdit-wrap">
  3. <a-spin :spinning="spinning" tip="Loading...">
  4. <a-page-header :ghost="false" :backIcon="false" class="intelligentReplenishmentEdit-back">
  5. <!-- 自定义的二级文字标题 -->
  6. <template slot="subTitle">
  7. <a id="intelligentReplenishmentEdit-back-btn" href="javascript:;" @click="handleBack"><a-icon type="left" /> 返回列表</a>
  8. </template>
  9. </a-page-header>
  10. <a-card size="small" :bordered="false" class="intelligentReplenishmentEdit-cont">
  11. <div class="steps-cont">
  12. <a-steps :current="current" size="small">
  13. <a-step title="产品设置" />
  14. <a-step title="参数设置" />
  15. <a-step title="系统计算" />
  16. </a-steps>
  17. </div>
  18. <a-form-model
  19. id="intelligentReplenishmentEdit-form"
  20. ref="ruleForm"
  21. :model="form"
  22. :rules="rules"
  23. :label-col="formItemLayout.labelCol"
  24. :wrapper-col="formItemLayout.wrapperCol"
  25. >
  26. <!-- 产品设置 -->
  27. <div v-if="current==0">
  28. <div class="module-cont">
  29. <p class="title">产品范围</p>
  30. <a-form-model-item label=" " :colon="false" prop="stockPredictRange" class="form-item">
  31. <a-radio-group name="radioGroup" v-model="form.stockPredictRange" placeholder="请选择">
  32. <a-radio :value="1">全部产品</a-radio>
  33. <a-radio :value="0">自选产品</a-radio>
  34. </a-radio-group>
  35. </a-form-model-item>
  36. <productRange v-if="form.stockPredictRange==0" ref="productRange" :tableHeight="tableHeight" :itemSn="$route.params.sn" @ok="handleProductOk" />
  37. </div>
  38. </div>
  39. <!-- 参数设置 -->
  40. <div v-if="current==1">
  41. <div class="module-cont">
  42. <p class="title">销售保障法<a-button type="link" size="small" class="link-btn" @click="handleExplain('xsbz')">算法说明</a-button></p>
  43. <a-form-model-item label="保障倍数" prop="saleEnsureNum" class="form-item">
  44. <a-input-number
  45. id="intelligentReplenishmentEdit-saleEnsureNum"
  46. v-model="form.saleEnsureNum"
  47. :precision="2"
  48. :min="1"
  49. :max="3"
  50. placeholder="请输入1~3之间的数字,最多两位小数"
  51. style="width: 100%;" />
  52. </a-form-model-item>
  53. </div>
  54. <div class="module-cont">
  55. <p class="title">趋势平均法<a-button type="link" size="small" class="link-btn" @click="handleExplain('qspj')">算法说明</a-button></p>
  56. <a-form-model-item label="服务水平" prop="trendSn" class="form-item">
  57. <div class="intelligentReplenishmentEdit-trendSn" @click="openModal=true">{{ form.serviceLevel || '--' }}%(对应的安全系数为{{ form.safetyFactor || '--' }})</div>
  58. </a-form-model-item>
  59. </div>
  60. </div>
  61. <!-- 系统计算 -->
  62. <div v-if="current==2">
  63. <div class="item-cont">
  64. <img src="@/assets/explain/def_calculation.png" width="200" class="item-pic" />
  65. <p class="item-txt">按照上一步的参数设置,系统正在<br/>计算中...点击左上角的返回列表可查看该条预测记录</p>
  66. </div>
  67. </div>
  68. </a-form-model>
  69. <div class="btn-cont" v-if="current==0 || current==1">
  70. <a-button
  71. type="primary"
  72. id="intelligentReplenishmentLevel-submit"
  73. size="large"
  74. class="button-primary"
  75. @click="handleNext"
  76. style="padding: 0 60px;">下一步</a-button>
  77. </div>
  78. </a-card>
  79. </a-spin>
  80. <!-- 服务水平 -->
  81. <replenishment-service-level-modal :openModal="openModal" :itemSn="form.trendSn" @close="openModal=false" @ok="handleOk" />
  82. </div>
  83. </template>
  84. <script>
  85. import { commonMixin } from '@/utils/mixin'
  86. import ReplenishmentServiceLevelModal from './serviceLevelModal.vue'
  87. import productRange from './productRange.vue'
  88. import { predictDetail, predictRangeSave, predictSave, predictTrendList, predictRun } from '@/api/predict'
  89. export default {
  90. name: 'IntelligentReplenishmentEdit',
  91. mixins: [commonMixin],
  92. components: { ReplenishmentServiceLevelModal, productRange },
  93. data () {
  94. return {
  95. spinning: false,
  96. tableHeight: 0,
  97. formItemLayout: {
  98. labelCol: { span: 2 },
  99. wrapperCol: { span: 16 }
  100. },
  101. form: {
  102. stockPredictRange: 1,
  103. saleEnsureNum: '',
  104. trendSn: '',
  105. serviceLevel: '',
  106. safetyFactor: ''
  107. },
  108. rules: {
  109. saleEnsureNum: [ { required: true, message: '请输入保障倍数', trigger: 'blur' } ],
  110. trendSn: [ { required: true, message: '请选择服务水平', trigger: ['blur', 'change'] } ]
  111. },
  112. openModal: false,
  113. current: 0,
  114. detailData: null
  115. }
  116. },
  117. methods: {
  118. // 返回
  119. handleBack () {
  120. this.$router.push({ path: `/inventoryManagement/intelligentReplenishment/list`, query: { closeLastOldTab: true } })
  121. },
  122. // 详情
  123. getDetail () {
  124. this.spinning = true
  125. predictDetail({ sn: this.$route.params.sn }).then(res => {
  126. if (res.status == 200) {
  127. this.detailData = res.data
  128. this.form.stockPredictRange = res.data.stockPredictRange != undefined ? Number(res.data.stockPredictRange) : 1
  129. if (res.data.state == 'RUN') {
  130. this.current = 2
  131. this.spinning = false
  132. } else {
  133. this.current = 0
  134. }
  135. if (this.form.stockPredictRange == 0) {
  136. this.getTrendSn()
  137. }
  138. } else {
  139. this.detailData = null
  140. this.spinning = false
  141. }
  142. })
  143. },
  144. // 产品范围 ok
  145. handleProductOk (params) {
  146. predictRangeSave(params).then(res => {
  147. if (res.status == 200) {
  148. this.$refs.productRange.refreshList()
  149. if (this.current == 0) { // 产品设置
  150. this.handleSave(true)
  151. }
  152. }
  153. })
  154. },
  155. // 下一步
  156. handleNext () {
  157. const _this = this
  158. if (this.current == 0) { // 产品设置
  159. this.handleSave(false)
  160. } else if (this.current == 1) { // 参数设置
  161. this.$refs.ruleForm.validate(valid => {
  162. if (valid) {
  163. const params = {
  164. id: this.detailData.id,
  165. stockPredictSn: _this.$route.params.sn,
  166. saleEnsureNum: _this.form.saleEnsureNum,
  167. trendSn: _this.form.trendSn,
  168. trendServiceLevel: _this.form.serviceLevel,
  169. trendSafetyFactor: _this.form.safetyFactor,
  170. stockPredictRange: this.form.stockPredictRange
  171. }
  172. _this.handleRun(params)
  173. } else {
  174. return false
  175. }
  176. })
  177. }
  178. },
  179. // 保存
  180. handleSave (noNext) {
  181. const params = {
  182. id: this.detailData.id,
  183. stockPredictSn: this.$route.params.sn,
  184. stockPredictRange: this.form.stockPredictRange
  185. }
  186. this.spinning = true
  187. predictSave(params).then(res => {
  188. if (res.status == 200) {
  189. if (!noNext) {
  190. this.current++
  191. this.spinning = false
  192. }else{
  193. this.getTrendSn()
  194. }
  195. } else {
  196. this.spinning = false
  197. }
  198. })
  199. },
  200. // 计算
  201. handleRun (params) {
  202. this.spinning = true
  203. predictRun(params).then(res => {
  204. if (res.status == 200) {
  205. this.current++
  206. this.spinning = false
  207. } else {
  208. this.spinning = false
  209. }
  210. })
  211. },
  212. // 算法说明
  213. handleExplain (type) {
  214. if (type == 'xsbz') {
  215. this.$router.push({ path: `/inventoryManagement/intelligentReplenishment/explainXsbz` })
  216. } else if (type == 'qspj') {
  217. this.$router.push({ path: `/inventoryManagement/intelligentReplenishment/explainQspj` })
  218. }
  219. },
  220. // 服务水平选择
  221. handleOk (val) {
  222. console.log(val)
  223. this.form.trendSn = val.trendSn
  224. this.form.serviceLevel = val.serviceLevel
  225. this.form.safetyFactor = val.safetyFactor
  226. this.openModal = false
  227. },
  228. // 获取默认服务水平
  229. getTrendSn () {
  230. this.spinning = true
  231. predictTrendList({ defaultFlag: 1 }).then(res => {
  232. if (res.status == 200) {
  233. this.form.trendSn = (res.data && res.data[0] && res.data[0].trendSn) ? res.data[0].trendSn : undefined
  234. this.form.serviceLevel = (res.data && res.data[0] && res.data[0].serviceLevel) ? res.data[0].serviceLevel : undefined
  235. this.form.safetyFactor = (res.data && res.data[0] && res.data[0].safetyFactor) ? res.data[0].safetyFactor : undefined
  236. } else {
  237. this.form.trendSn = ''
  238. this.form.serviceLevel = ''
  239. this.form.safetyFactor = ''
  240. }
  241. this.spinning = false
  242. })
  243. },
  244. setTableH () {
  245. this.tableHeight = window.innerHeight - 550
  246. },
  247. pageInit () {
  248. this.form = {
  249. stockPredictRange: 1,
  250. saleEnsureNum: '',
  251. trendSn: '',
  252. serviceLevel: '',
  253. safetyFactor: ''
  254. }
  255. this.$refs.ruleForm.resetFields()
  256. this.getDetail()
  257. const _this = this
  258. this.$nextTick(() => { // 页面渲染完成后的回调
  259. _this.setTableH()
  260. })
  261. }
  262. },
  263. mounted () {
  264. if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
  265. this.pageInit()
  266. }
  267. },
  268. activated () {
  269. // 如果是新页签打开或者进入新的子页(例:存在列表第2条数据编辑页页签时再打开第4条数据的编辑页),则重置当前页面
  270. if (this.$store.state.app.isNewTab || !this.$store.state.app.isNewSubTab) {
  271. this.pageInit()
  272. }
  273. },
  274. beforeRouteEnter (to, from, next) {
  275. next(vm => {})
  276. }
  277. }
  278. </script>
  279. <style lang="less">
  280. .intelligentReplenishmentEdit-wrap{
  281. height: 100%;
  282. >.ant-spin-nested-loading{
  283. height: 100%;
  284. .ant-spin-container{
  285. height: 93%;
  286. }
  287. }
  288. .intelligentReplenishmentEdit-back{
  289. margin-bottom: 10px;
  290. }
  291. .intelligentReplenishmentEdit-cont{
  292. height: 100%;
  293. .steps-cont{
  294. width: 50%;
  295. margin: 30px auto 10px;
  296. }
  297. .module-cont{
  298. border: 1px dashed #e8e8e8;
  299. border-radius: 12px;
  300. position: relative;
  301. margin: 30px 0;
  302. padding: 20px 15px 15px;
  303. .title{
  304. position: absolute;
  305. left: 50px;
  306. top: -12px;
  307. padding: 0 10px;
  308. font-size: 15px;
  309. background-color: #fff;
  310. .link-btn{
  311. font-size: 12px;
  312. }
  313. }
  314. .form-item{
  315. margin-top: 25px;
  316. }
  317. .intelligentReplenishmentEdit-trendSn{
  318. border: 1px solid #d9d9d9;
  319. border-radius: 4px;
  320. line-height: 1.5;
  321. padding: 4px 11px;
  322. margin-top: 4px;
  323. }
  324. }
  325. .item-cont{
  326. text-align: center;
  327. padding: 130px 0 100px;
  328. .item-txt{
  329. margin: 20px 0 50px;
  330. font-size: 12px;
  331. line-height: 24px;
  332. }
  333. }
  334. .btn-cont{
  335. margin: 30px 0 20px;
  336. text-align: center;
  337. }
  338. }
  339. }
  340. </style>