index.vue 7.2 KB

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