index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <template>
  2. <div v-if="visible" class="forecast-form-container">
  3. <!-- 销售预测表单容器 - AvueJS版本 -->
  4. <div class="forecast-form-container basic-container">
  5. <!-- 表单内容区域 -->
  6. <div class="forecast-form-content">
  7. <avue-form
  8. ref="forecastForm"
  9. v-model="formData"
  10. :option="formOption"
  11. @submit="handleSubmit"
  12. @reset-change="handleReset"
  13. >
  14. <!-- 客户选择器插槽 -->
  15. <template #customerId>
  16. <customer-select
  17. v-model="formData.customerId"
  18. placeholder="请选择客户"
  19. @customer-selected="handleCustomerSelected"
  20. />
  21. </template>
  22. <!-- 预测年份插槽(使用 $refs.yearPicker 控制禁用) -->
  23. <template #year>
  24. <el-date-picker
  25. ref="yearPicker"
  26. v-model="formData.year"
  27. type="year"
  28. value-format="yyyy"
  29. placeholder="请选择年份"
  30. style="width: 100%"
  31. />
  32. </template>
  33. <!-- 预测月份插槽(使用 $refs.monthSelect 控制禁用) -->
  34. <template #month="{ column }">
  35. <el-select
  36. ref="monthSelect"
  37. v-model="formData.month"
  38. placeholder="请选择月份"
  39. style="width: 100%"
  40. >
  41. <el-option
  42. v-for="opt in (column && column.dicData) ? column.dicData : []"
  43. :key="opt.value"
  44. :label="opt.label"
  45. :value="opt.value"
  46. />
  47. </el-select>
  48. </template>
  49. </avue-form>
  50. <!-- 物料表格区域 -->
  51. <div class="forecast-goods-table">
  52. <div class="table-title">物料列表</div>
  53. <!-- 选择并导入物料工具栏 -->
  54. <div class="table-toolbar">
  55. <el-select
  56. v-model="selectedStockId"
  57. filterable
  58. clearable
  59. :disabled="stockSelectOptions.length === 0"
  60. placeholder="物料名称"
  61. style="width: 360px"
  62. >
  63. <el-option
  64. v-for="opt in stockSelectOptions"
  65. :key="opt.value"
  66. :label="opt.label"
  67. :value="opt.value"
  68. />
  69. </el-select>
  70. <el-button
  71. type="primary"
  72. :disabled="!selectedStockId"
  73. style="margin-left: 8px"
  74. @click="handleImportSelectedStock"
  75. >添加物料</el-button>
  76. </div>
  77. <el-table
  78. :data="stockTableData"
  79. border
  80. stripe
  81. height="360"
  82. v-loading="tableLoading"
  83. >
  84. <el-table-column prop="code" label="物料编码" min-width="140" show-overflow-tooltip />
  85. <el-table-column prop="cname" label="物料名称" min-width="160" show-overflow-tooltip />
  86. <el-table-column prop="brandName" label="品牌名称" min-width="120" show-overflow-tooltip />
  87. <el-table-column prop="typeNo" label="规格" min-width="120" show-overflow-tooltip />
  88. <el-table-column prop="storeInventory" label="库存数量" min-width="120">
  89. <template #default="{ row }">
  90. <span>{{ parseInt(row.storeInventory || 0) }}</span>
  91. </template>
  92. </el-table-column>
  93. <!-- Removed specs/description column: productDescription -->
  94. <el-table-column label="预测数量" min-width="140">
  95. <template #default="{ row }">
  96. <el-input-number
  97. v-model="row.forecastQuantity"
  98. :min="0"
  99. :max="999999"
  100. :step="1"
  101. controls-position="right"
  102. style="width: 120px"
  103. />
  104. </template>
  105. </el-table-column>
  106. <!-- 操作列:删除按钮 -->
  107. <el-table-column label="操作" fixed="right" width="120">
  108. <template #default="{ row, $index }">
  109. <el-button
  110. type="text"
  111. size="small"
  112. icon="el-icon-delete"
  113. @click="handleDelete(row, $index)"
  114. >删除</el-button>
  115. </template>
  116. </el-table-column>
  117. </el-table>
  118. <div class="table-tip">提示:先在上方选择物料并点击“导入物料”,导入后的数据将显示在表格并参与保存流程。</div>
  119. </div>
  120. </div>
  121. </div>
  122. </div>
  123. </template>
  124. <script>
  125. import forecastFormMixin from './forecast-form-mixin.js'
  126. import CustomerSelect from '@/components/common/customer-select.vue'
  127. /**
  128. * 销售预测表单组件实例类型定义
  129. * @typedef {object} ForecastFormAvueComponent
  130. * @property {import('./types').ForecastFormModel} formData - 表单数据
  131. * @property {import('./types').FormOption} formOption - 表单配置选项
  132. * @property {boolean} saveLoading - 保存加载状态
  133. * @property {import('./types').CustomerOption[]} customerOptions - 客户选项列表
  134. * @property {number|null} currentInventory - 当前库存数量
  135. * @property {import('./types').ApprovalStatusOption[]} approvalStatusOptions - 审批状态选项
  136. * @property {import('./types').ForecastFormRules} formRules - 表单验证规则
  137. * @property {boolean} visible - 表单可见性
  138. * @property {boolean} isEdit - 是否为编辑模式
  139. * @property {Object|null} editData - 编辑数据
  140. * @property {Object|null} initialFormData - 初始表单数据
  141. * @property {string} title - 表单标题
  142. * @property {string} forecastId - 预测ID
  143. */
  144. /**
  145. * 销售预测表单组件 - AvueJS版本
  146. * @description 基于AvueJS的销售预测表单组件,支持新增和编辑销售预测功能
  147. */
  148. export default {
  149. name: 'ForecastFormAvue',
  150. mixins: [forecastFormMixin],
  151. /**
  152. * 组件注册
  153. */
  154. components: {
  155. CustomerSelect
  156. },
  157. /**
  158. * @this {import('./types').ForecastFormMixinComponent & Vue}
  159. */
  160. mounted() {
  161. // 在编辑态,初始禁用“年份/月份”两个控件(通过 $refs 设置)
  162. this.$nextTick(() => {
  163. try {
  164. if (this.isEdit) {
  165. if (this.$refs.yearPicker) this.$refs.yearPicker.disabled = true
  166. if (this.$refs.monthSelect) this.$refs.monthSelect.disabled = true
  167. }
  168. } catch (e) {
  169. // 忽略可能的非关键性异常
  170. }
  171. })
  172. },
  173. methods: {
  174. // 通过 $refs 统一设置“年份/月份”的禁用状态
  175. setYearMonthDisabled(disabled) {
  176. this.$nextTick(() => {
  177. try {
  178. if (this.$refs.yearPicker) this.$refs.yearPicker.disabled = disabled
  179. if (this.$refs.monthSelect) this.$refs.monthSelect.disabled = disabled
  180. } catch (e) {
  181. // 忽略可能的非关键性异常
  182. }
  183. })
  184. }
  185. }
  186. }
  187. </script>
  188. <style lang="scss" scoped>
  189. @import './index.scss';
  190. .forecast-goods-table {
  191. margin-top: 12px;
  192. }
  193. .table-title {
  194. font-size: 14px;
  195. color: #333;
  196. margin-bottom: 8px;
  197. }
  198. .table-toolbar {
  199. margin-bottom: 8px;
  200. }
  201. .table-tip {
  202. margin-top: 8px;
  203. font-size: 12px;
  204. color: #909399;
  205. }
  206. </style>