index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <template>
  2. <div class="purchase-habit-container">
  3. <!-- 顶部返回 -->
  4. <div class="page-header">
  5. <el-button link @click="handleBack">
  6. <el-icon><ArrowLeft /></el-icon>
  7. <span>返回</span>
  8. </el-button>
  9. <span class="page-title">企业采购习惯</span>
  10. </div>
  11. <div class="page-content">
  12. <el-form ref="formRef" :model="form" label-position="top">
  13. <!-- 采购金额 -->
  14. <el-row :gutter="40">
  15. <el-col :span="12">
  16. <el-form-item label="月度采购金额">
  17. <el-input v-model="form.monthlyAmount" placeholder="请输入">
  18. <template #suffix>万</template>
  19. </el-input>
  20. </el-form-item>
  21. </el-col>
  22. <el-col :span="12">
  23. <el-form-item label="年度采购金额">
  24. <el-input v-model="form.yearlyAmount" placeholder="请输入">
  25. <template #suffix>万</template>
  26. </el-input>
  27. </el-form-item>
  28. </el-col>
  29. </el-row>
  30. <!-- 产品选型 -->
  31. <el-form-item label="产品选型">
  32. <div class="tag-group">
  33. <div
  34. v-for="item in productTypeOptions"
  35. :key="item"
  36. :class="['tag-item', { active: form.productTypes.includes(item) }]"
  37. @click="toggleTag(form.productTypes, item)"
  38. >
  39. {{ item }}
  40. </div>
  41. </div>
  42. </el-form-item>
  43. <!-- 日常打印量 -->
  44. <el-form-item label="日常打印量">
  45. <div class="tag-group">
  46. <div
  47. v-for="item in printVolumeOptions"
  48. :key="item"
  49. :class="['tag-item', { active: form.printVolume === item }]"
  50. @click="form.printVolume = item"
  51. >
  52. {{ item }}
  53. </div>
  54. </div>
  55. </el-form-item>
  56. <!-- 购买原装耗材 & 专人进行技术服务 -->
  57. <el-row :gutter="40">
  58. <el-col :span="12">
  59. <el-form-item label="购买原装耗材">
  60. <el-radio-group v-model="form.buyOriginal">
  61. <el-radio v-for="dict in sys_platform_yes_no" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
  62. </el-radio-group>
  63. </el-form-item>
  64. </el-col>
  65. <el-col :span="12">
  66. <el-form-item label="专人进行技术服务">
  67. <el-radio-group v-model="form.technologyService">
  68. <el-radio v-for="dict in sys_platform_yes_no" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
  69. </el-radio-group>
  70. </el-form-item>
  71. </el-col>
  72. </el-row>
  73. <!-- 主要办公采购类目 -->
  74. <el-form-item label="主要办公采购类目">
  75. <div class="tag-group">
  76. <div
  77. v-for="item in categoryOptions"
  78. :key="item"
  79. :class="['tag-item', { active: form.categories.includes(item) }]"
  80. @click="toggleTag(form.categories, item)"
  81. >
  82. {{ item }}
  83. </div>
  84. </div>
  85. <el-input v-model="form.otherCategory" placeholder="其他采购类目" maxlength="50" show-word-limit class="other-input" />
  86. </el-form-item>
  87. <!-- 企业福利 -->
  88. <el-form-item label="企业福利">
  89. <div class="tag-group">
  90. <div
  91. v-for="item in welfareOptions"
  92. :key="item"
  93. :class="['tag-item', { active: form.welfares.includes(item) }]"
  94. @click="toggleTag(form.welfares, item)"
  95. >
  96. {{ item }}
  97. </div>
  98. </div>
  99. <el-input v-model="form.otherScene" placeholder="其他福利" maxlength="50" show-word-limit class="other-input" />
  100. </el-form-item>
  101. <!-- 产品定制需求 -->
  102. <el-form-item label="产品定制需求">
  103. <div class="tag-group">
  104. <div
  105. v-for="item in customOptions"
  106. :key="item"
  107. :class="['tag-item', { active: form.customs.includes(item) }]"
  108. @click="toggleTag(form.customs, item)"
  109. >
  110. {{ item }}
  111. </div>
  112. </div>
  113. <el-input v-model="form.otherCustomize" placeholder="其他需求" maxlength="50" show-word-limit class="other-input" />
  114. </el-form-item>
  115. </el-form>
  116. <!-- 底部按钮 -->
  117. <div class="form-footer">
  118. <el-button type="danger" @click="handleSave">保存</el-button>
  119. <el-button @click="handleBack">取消</el-button>
  120. </div>
  121. </div>
  122. </div>
  123. </template>
  124. <script setup lang="ts">
  125. import { reactive, getCurrentInstance, toRefs, onMounted, ComponentInternalInstance, computed } from 'vue';
  126. import { useRouter } from 'vue-router';
  127. import { ArrowLeft } from '@element-plus/icons-vue';
  128. import { ElMessage } from 'element-plus';
  129. import { updatePurchaseHabit, getCustomerPurchaseHabitData } from '@/api/pc/enterprise/purchaseHabit';
  130. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  131. const { welfare_item, sys_platform_yes_no, product_types_choosing, purchase_item, product_customization, daily_print_volume } = toRefs<any>(
  132. proxy?.useDict('welfare_item', 'sys_platform_yes_no', 'product_types_choosing', 'purchase_item', 'product_customization', 'daily_print_volume')
  133. );
  134. const router = useRouter();
  135. // 根据字典数据生成选项
  136. const productTypeOptions = computed(() => product_types_choosing.value?.map((item: any) => item.label) || []);
  137. const printVolumeOptions = computed(() => daily_print_volume.value?.map((item: any) => item.label) || []);
  138. const categoryOptions = computed(() => purchase_item.value?.map((item: any) => item.label) || []);
  139. const welfareOptions = computed(() => welfare_item.value?.map((item: any) => item.label) || []);
  140. const customOptions = computed(() => product_customization.value?.map((item: any) => item.label) || []);
  141. const form = reactive({
  142. id: undefined,
  143. customerId: undefined,
  144. customerNo: '',
  145. permanentOfficer: '',
  146. monthlyAmount: '',
  147. yearlyAmount: '',
  148. productTypes: [] as string[],
  149. printVolume: '',
  150. printAmount: '',
  151. buyOriginal: '',
  152. technologyService: '',
  153. categories: [] as string[],
  154. otherCategory: '',
  155. welfares: [] as string[],
  156. customs: [] as string[],
  157. adaptScenes: [] as string[],
  158. otherScene: '',
  159. otherCustomize: '',
  160. choiceModel: '',
  161. remark: ''
  162. });
  163. const toggleTag = (arr: string[], item: string) => {
  164. const index = arr.indexOf(item);
  165. if (index > -1) arr.splice(index, 1);
  166. else arr.push(item);
  167. };
  168. const handleBack = () => {
  169. router.push('/enterprise/companyInfo');
  170. };
  171. const handleSave = async () => {
  172. try {
  173. // 将表单数据映射为接口所需格式
  174. const submitData = {
  175. id: form.id,
  176. customerId: form.customerId,
  177. customerNo: form.customerNo,
  178. monthPurchase: form.monthlyAmount ? parseFloat(form.monthlyAmount) : undefined,
  179. yearPurchase: form.yearlyAmount ? parseFloat(form.yearlyAmount) : undefined,
  180. permanentOfficer: form.permanentOfficer,
  181. choiceModel: form.productTypes.length > 0 ? product_types_choosing.value?.find((i: any) => i.label === form.productTypes[0])?.value || '' : '',
  182. printAmount: form.printVolume ? daily_print_volume.value?.find((i: any) => i.label === form.printVolume)?.value || '' : '',
  183. buyOriginal: form.buyOriginal,
  184. technologyService: form.technologyService,
  185. purchaseCategory:
  186. form.categories.length > 0
  187. ? form.categories
  188. .map((label) => {
  189. const item = purchase_item.value?.find((i: any) => i.label === label);
  190. return item ? item.value : '';
  191. })
  192. .filter(Boolean)
  193. .join(',')
  194. : undefined,
  195. otherCategory: form.otherCategory || undefined,
  196. adaptScene:
  197. form.welfares.length > 0
  198. ? form.welfares
  199. .map((label) => {
  200. const item = welfare_item.value?.find((i: any) => i.label === label);
  201. return item ? item.value : '';
  202. })
  203. .filter(Boolean)
  204. .join(',')
  205. : undefined,
  206. otherScene: form.otherScene || undefined,
  207. customizeDemand:
  208. form.customs.length > 0
  209. ? form.customs
  210. .map((label) => {
  211. const item = product_customization.value?.find((i: any) => i.label === label);
  212. return item ? item.value : '';
  213. })
  214. .filter(Boolean)
  215. .join(',')
  216. : undefined,
  217. otherCustomize: form.otherCustomize || undefined,
  218. remark: form.remark || undefined
  219. };
  220. await updatePurchaseHabit(submitData);
  221. ElMessage.success('保存成功');
  222. handleBack();
  223. } catch (error) {
  224. ElMessage.error('保存失败');
  225. }
  226. };
  227. const getPurchaseHabitData = async () => {
  228. try {
  229. const res = await getCustomerPurchaseHabitData();
  230. if (res.code === 200 && res.data) {
  231. const data = res.data;
  232. // 映射数据到表单
  233. form.id = data.id;
  234. form.customerId = data.customerId;
  235. form.customerNo = data.customerNo || '';
  236. form.permanentOfficer = data.permanentOfficer || '';
  237. form.monthlyAmount = data.monthPurchase || '';
  238. form.yearlyAmount = data.yearPurchase || '';
  239. // 处理产品选型(单选)
  240. form.productTypes = data.choiceModel ? [product_types_choosing.value?.find((i: any) => i.value === data.choiceModel)?.label || ''] : [];
  241. // 处理日常打印量(单选)
  242. form.printVolume = data.printAmount ? daily_print_volume.value?.find((i: any) => i.value === data.printAmount)?.label || '' : '';
  243. form.categories = data.purchaseCategory
  244. ? data.purchaseCategory
  245. .split(',')
  246. .map((id: string) => {
  247. const item = purchase_item.value?.find((i: any) => i.value === id);
  248. return item ? item.label : '';
  249. })
  250. .filter(Boolean)
  251. : [];
  252. form.welfares = data.adaptScene
  253. ? data.adaptScene
  254. .split(',')
  255. .map((id: string) => {
  256. const item = welfare_item.value?.find((i: any) => i.value === id);
  257. return item ? item.label : '';
  258. })
  259. .filter(Boolean)
  260. : [];
  261. form.customs = data.customizeDemand
  262. ? data.customizeDemand
  263. .split(',')
  264. .map((id: string) => {
  265. const item = product_customization.value?.find((i: any) => i.value === id);
  266. return item ? item.label : '';
  267. })
  268. .filter(Boolean)
  269. : [];
  270. // 处理单选字段
  271. form.printAmount = data.printAmount || '';
  272. form.buyOriginal = data.buyOriginal || '';
  273. form.technologyService = data.technologyService;
  274. form.choiceModel = data.choiceModel || '';
  275. // 其他字段
  276. form.otherCategory = data.otherCategory || '';
  277. form.otherCustomize = data.otherCustomize || '';
  278. form.otherScene = data.otherScene || '';
  279. form.otherCustomize = data.otherCustomize || '';
  280. form.remark = data.remark || '';
  281. }
  282. } catch (error) {
  283. console.error('获取采购习惯数据失败:', error);
  284. ElMessage.error('获取数据失败');
  285. }
  286. };
  287. onMounted(() => {
  288. getPurchaseHabitData();
  289. });
  290. </script>
  291. <style scoped lang="scss">
  292. .purchase-habit-container {
  293. background: #f5f5f5;
  294. min-height: 100%;
  295. }
  296. .page-header {
  297. background: #fff;
  298. padding: 15px 20px;
  299. display: flex;
  300. align-items: center;
  301. gap: 10px;
  302. border-bottom: 1px solid #eee;
  303. .page-title {
  304. font-size: 16px;
  305. font-weight: bold;
  306. color: #333;
  307. }
  308. }
  309. .page-content {
  310. padding: 20px;
  311. background: #fff;
  312. margin: 20px;
  313. border-radius: 8px;
  314. }
  315. .tag-group {
  316. display: flex;
  317. flex-wrap: wrap;
  318. gap: 10px;
  319. .tag-item {
  320. padding: 8px 20px;
  321. border: 1px solid #ddd;
  322. border-radius: 4px;
  323. cursor: pointer;
  324. font-size: 14px;
  325. color: #666;
  326. transition: all 0.2s;
  327. &:hover {
  328. border-color: #e60012;
  329. color: #e60012;
  330. }
  331. &.active {
  332. border-color: #e60012;
  333. color: #e60012;
  334. background: #fff5f5;
  335. }
  336. }
  337. }
  338. .other-input {
  339. margin-top: 10px;
  340. }
  341. .form-footer {
  342. text-align: center;
  343. padding-top: 30px;
  344. border-top: 1px solid #eee;
  345. margin-top: 20px;
  346. }
  347. :deep(.el-form-item__label) {
  348. font-weight: 500;
  349. color: #333;
  350. }
  351. :deep(.el-radio) {
  352. margin-right: 30px;
  353. }
  354. </style>