edit.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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. <!-- 算法说明 -->
  83. <commonModal
  84. :modalTit="explainType=='qspj'?'趋势平均法说明':'销售保障法说明'"
  85. bodyPadding="10px"
  86. width="1024px"
  87. :showFooter="false"
  88. :openModal="showDetailModal"
  89. @cancel="showDetailModal=false">
  90. <explainQspj v-if="explainType=='qspj'" @close="showDetailModal=false"></explainQspj>
  91. <explainXsbz v-if="explainType=='xsbz'" @close="showDetailModal=false"></explainXsbz>
  92. </commonModal>
  93. </div>
  94. </template>
  95. <script>
  96. import { commonMixin } from '@/utils/mixin'
  97. import commonModal from '@/views/common/commonModal.vue'
  98. import ReplenishmentServiceLevelModal from './serviceLevelModal.vue'
  99. import explainQspj from './explainQspj.vue'
  100. import explainXsbz from './explainXsbz.vue'
  101. import productRange from './productRange.vue'
  102. import { predictDetail, predictRangeSave, predictSave, predictTrendList, predictRun } from '@/api/predict'
  103. export default {
  104. name: 'IntelligentReplenishmentEdit',
  105. mixins: [commonMixin],
  106. components: { ReplenishmentServiceLevelModal, productRange, commonModal, explainQspj, explainXsbz },
  107. data () {
  108. return {
  109. spinning: false,
  110. showDetailModal: false,
  111. explainType: 0,
  112. tableHeight: 0,
  113. formItemLayout: {
  114. labelCol: { span: 2 },
  115. wrapperCol: { span: 16 }
  116. },
  117. form: {
  118. stockPredictRange: 1,
  119. saleEnsureNum: '',
  120. trendSn: '',
  121. serviceLevel: '',
  122. safetyFactor: ''
  123. },
  124. rules: {
  125. saleEnsureNum: [ { required: true, message: '请输入保障倍数', trigger: 'blur' } ],
  126. trendSn: [ { required: true, message: '请选择服务水平', trigger: ['blur', 'change'] } ]
  127. },
  128. openModal: false,
  129. current: 0,
  130. detailData: null
  131. }
  132. },
  133. methods: {
  134. // 返回
  135. handleBack () {
  136. this.$router.push({ path: `/inventoryManagement/intelligentReplenishment/list`, query: { closeLastOldTab: true } })
  137. },
  138. // 详情
  139. getDetail () {
  140. this.spinning = true
  141. predictDetail({ sn: this.$route.params.sn }).then(res => {
  142. if (res.status == 200) {
  143. this.detailData = res.data
  144. this.form.stockPredictRange = res.data.stockPredictRange != undefined ? Number(res.data.stockPredictRange) : 1
  145. if (res.data.state == 'RUN') {
  146. this.current = 2
  147. this.spinning = false
  148. } else {
  149. this.current = 0
  150. }
  151. this.getTrendSn()
  152. } else {
  153. this.detailData = null
  154. this.spinning = false
  155. }
  156. })
  157. },
  158. // 产品范围 ok
  159. handleProductOk (params) {
  160. predictRangeSave(params).then(res => {
  161. if (res.status == 200) {
  162. this.$refs.productRange.refreshList()
  163. if (this.current == 0) { // 产品设置
  164. this.handleSave(true)
  165. }
  166. }
  167. })
  168. },
  169. // 下一步
  170. handleNext () {
  171. const _this = this
  172. if (this.current == 0) { // 产品设置
  173. this.handleSave(false)
  174. } else if (this.current == 1) { // 参数设置
  175. this.$refs.ruleForm.validate(valid => {
  176. if (valid) {
  177. const params = {
  178. id: this.detailData.id,
  179. stockPredictSn: _this.$route.params.sn,
  180. saleEnsureNum: _this.form.saleEnsureNum,
  181. trendSn: _this.form.trendSn,
  182. trendServiceLevel: _this.form.serviceLevel,
  183. trendSafetyFactor: _this.form.safetyFactor,
  184. stockPredictRange: this.form.stockPredictRange
  185. }
  186. _this.handleRun(params)
  187. } else {
  188. return false
  189. }
  190. })
  191. }
  192. },
  193. // 保存
  194. handleSave (noNext) {
  195. const params = {
  196. id: this.detailData.id,
  197. stockPredictSn: this.$route.params.sn,
  198. stockPredictRange: this.form.stockPredictRange
  199. }
  200. this.spinning = true
  201. predictSave(params).then(res => {
  202. if (res.status == 200) {
  203. if (!noNext) {
  204. this.current++
  205. this.spinning = false
  206. } else {
  207. this.getTrendSn()
  208. }
  209. } else {
  210. this.spinning = false
  211. }
  212. })
  213. },
  214. // 计算
  215. handleRun (params) {
  216. this.spinning = true
  217. predictRun(params).then(res => {
  218. if (res.status == 200) {
  219. this.current++
  220. this.spinning = false
  221. } else {
  222. this.spinning = false
  223. }
  224. })
  225. },
  226. // 算法说明
  227. handleExplain (type) {
  228. this.explainType = type
  229. this.showDetailModal = true
  230. },
  231. // 服务水平选择
  232. handleOk (val) {
  233. console.log(val)
  234. this.form.trendSn = val.trendSn
  235. this.form.serviceLevel = val.serviceLevel
  236. this.form.safetyFactor = val.safetyFactor
  237. this.openModal = false
  238. },
  239. // 获取默认服务水平
  240. getTrendSn () {
  241. this.spinning = true
  242. predictTrendList({ defaultFlag: 1 }).then(res => {
  243. if (res.status == 200) {
  244. this.form.trendSn = (res.data && res.data[0] && res.data[0].trendSn) ? res.data[0].trendSn : undefined
  245. this.form.serviceLevel = (res.data && res.data[0] && res.data[0].serviceLevel) ? res.data[0].serviceLevel : undefined
  246. this.form.safetyFactor = (res.data && res.data[0] && res.data[0].safetyFactor) ? res.data[0].safetyFactor : undefined
  247. } else {
  248. this.form.trendSn = ''
  249. this.form.serviceLevel = ''
  250. this.form.safetyFactor = ''
  251. }
  252. this.spinning = false
  253. })
  254. },
  255. setTableH () {
  256. this.tableHeight = window.innerHeight - 550
  257. },
  258. pageInit () {
  259. this.form = {
  260. stockPredictRange: 1,
  261. saleEnsureNum: '',
  262. trendSn: '',
  263. serviceLevel: '',
  264. safetyFactor: ''
  265. }
  266. this.$refs.ruleForm.resetFields()
  267. this.getDetail()
  268. const _this = this
  269. this.$nextTick(() => { // 页面渲染完成后的回调
  270. _this.setTableH()
  271. })
  272. }
  273. },
  274. mounted () {
  275. if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
  276. this.pageInit()
  277. }
  278. },
  279. activated () {
  280. // 如果是新页签打开或者进入新的子页(例:存在列表第2条数据编辑页页签时再打开第4条数据的编辑页),则重置当前页面
  281. if (this.$store.state.app.isNewTab || !this.$store.state.app.isNewSubTab) {
  282. this.pageInit()
  283. }
  284. },
  285. beforeRouteEnter (to, from, next) {
  286. next(vm => {})
  287. }
  288. }
  289. </script>
  290. <style lang="less">
  291. .intelligentReplenishmentEdit-wrap{
  292. height: 100%;
  293. >.ant-spin-nested-loading{
  294. height: 100%;
  295. .ant-spin-container{
  296. height: 93%;
  297. }
  298. }
  299. .intelligentReplenishmentEdit-back{
  300. margin-bottom: 6px;
  301. }
  302. .intelligentReplenishmentEdit-cont{
  303. height: 100%;
  304. .steps-cont{
  305. width: 50%;
  306. margin: 30px auto 10px;
  307. }
  308. .module-cont{
  309. border: 1px dashed #e8e8e8;
  310. border-radius: 12px;
  311. position: relative;
  312. margin: 30px 0;
  313. padding: 20px 15px 15px;
  314. .title{
  315. position: absolute;
  316. left: 50px;
  317. top: -12px;
  318. padding: 0 10px;
  319. font-size: 15px;
  320. background-color: #fff;
  321. .link-btn{
  322. font-size: 12px;
  323. }
  324. }
  325. .form-item{
  326. margin-top: 25px;
  327. }
  328. .intelligentReplenishmentEdit-trendSn{
  329. border: 1px solid #d9d9d9;
  330. border-radius: 4px;
  331. line-height: 1.5;
  332. padding: 4px 11px;
  333. margin-top: 4px;
  334. }
  335. }
  336. .item-cont{
  337. text-align: center;
  338. padding: 130px 0 100px;
  339. .item-txt{
  340. margin: 20px 0 50px;
  341. font-size: 12px;
  342. line-height: 24px;
  343. }
  344. }
  345. .btn-cont{
  346. margin: 30px 0 20px;
  347. text-align: center;
  348. }
  349. }
  350. }
  351. </style>