EditModal.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <template>
  2. <el-dialog :visible.sync="visible" v-bind="modalOptions" append-to-body>
  3. <div class="tree-container">
  4. <el-tree
  5. :data="[ formData ]" :props="{ children: 'childs' }" node-key="shopGroupId" default-expand-all
  6. draggable
  7. :expand-on-click-node="false"
  8. >
  9. <div slot-scope="{ node, data }">
  10. <div style="display: flex;align-items: center;justify-content: space-between;padding: 10px 0;">
  11. <div v-if="data.depth <= 3" style="margin-right: 14px;">
  12. <el-input
  13. v-model="data.groupName" maxlength="10" size="mini" style="width: 280px;"
  14. :placeholder="{ 1: '输入一级分组名称(最大6个字符)', 2: '输入二级分组名称(最大6个字符)', 2: '输入三级分组名称(最大10个字符)' }[data.depth]"
  15. />
  16. <el-input v-model="data.groupDescribe" size="mini" style="width: 340px;" placeholder="请输入分组描述" />
  17. </div>
  18. <div>
  19. <el-button type="text" size="mini">
  20. 分组商品详情
  21. </el-button>
  22. <el-button type="text" size="mini" @click="handleAddProduct(data, node)">
  23. 添加分组商品
  24. </el-button>
  25. <el-button v-if="data.depth < 3" type="text" size="mini" @click="handleAppend(data)">
  26. {{ { 1: '添加二级分组名称', 2: '添加三级分组名称' }[data.depth] }}
  27. </el-button>
  28. <el-button type="text" size="mini" @click="handleDelete(data, node)">
  29. 删除
  30. </el-button>
  31. </div>
  32. </div>
  33. </div>
  34. </el-tree>
  35. <div>
  36. <el-button type="primary" size="small" @click="handleSubmit">
  37. 保存
  38. </el-button>
  39. <el-button type="danger" size="small" @click="handleClose">
  40. 取消
  41. </el-button>
  42. </div>
  43. <el-dialog title="手动添加商品" :visible.sync="isShowManualAdd" width="900px" top="50px" append-to-body>
  44. <div class="filter-container" style="display: flex;align-items: center;flex-wrap: wrap;">
  45. <el-input
  46. v-model="listQuery.search" clearable size="mini" class="filter-item"
  47. style="width: 200px;"
  48. placeholder="搜索商品名称或商品ID"
  49. />
  50. <div style="margin-left: 10px;">
  51. <span>库存数量:</span>
  52. <el-input
  53. v-model="listQuery.minStock" size="mini" class="filter-item" style="width: 200px;"
  54. maxlength="9"
  55. />
  56. <span></span>
  57. <el-input
  58. v-model="listQuery.maxStock" size="mini" class="filter-item" style="width: 200px;"
  59. maxlength="9"
  60. />
  61. </div>
  62. <div style="margin-left: 10px;">
  63. <span>价格:</span>
  64. <el-input
  65. v-model="listQuery.minPrice" size="mini" class="filter-item" style="width: 200px;"
  66. maxlength="9"
  67. />
  68. <span></span>
  69. <el-input
  70. v-model="listQuery.maxPrice" size="mini" class="filter-item" style="width: 200px;"
  71. maxlength="9"
  72. />
  73. </div>
  74. <el-button
  75. size="mini" class="filter-item" type="primary" icon="el-icon-search"
  76. style="margin-left: 10px;"
  77. @click="getInfo(formData.shopGroupId)"
  78. >
  79. 查找
  80. </el-button>
  81. <el-button
  82. size="mini" class="filter-item" type="info" plain
  83. style="margin-left: 10px; padding: 7px 22px; border: 0" @click="clearData"
  84. >
  85. 重置
  86. </el-button>
  87. </div>
  88. <div>
  89. <el-table
  90. ref="multipleTable" :data="productDataList" border
  91. :header-cell-style="{ background: '#EEF3FF', color: '#333333' }" tooltip-effect="dark" style="width: 100%"
  92. max-height="550" @selection-change="(e) => multipleSelection = e"
  93. >
  94. <el-table-column type="selection" width="55" />
  95. <el-table-column label="产品主图" width="220" align="center">
  96. <template slot-scope="scope">
  97. <img height="80" width="80" :src="scope.row.image" alt srcset>
  98. </template>
  99. </el-table-column>
  100. <el-table-column prop="productName" label="产品名称" width="220" align="center" />
  101. <el-table-column prop="originalPrice" label="价格(元)" align="center" show-overflow-tooltip />
  102. <el-table-column prop="stockNumber" label="库存(件)" align="center" show-overflow-tooltip />
  103. </el-table>
  104. <div>
  105. <el-pagination
  106. :current-page="listQuery.page" :page-sizes="[10, 20, 50, 100]"
  107. :page-size="listQuery.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="productTotal"
  108. @size-change="(val) => ((listQuery.pageSize = val) && getInfo(formData.shopGroupId))"
  109. @current-change="(val) => ((listQuery.page = val) && getInfo(formData.shopGroupId))"
  110. />
  111. <span slot="footer">
  112. <el-button type="primary" @click="handleSaveIdList">确 定</el-button>
  113. <el-button @click="isShowManualAdd = false">取 消</el-button>
  114. </span>
  115. </div>
  116. </div>
  117. </el-dialog>
  118. </div>
  119. </el-dialog>
  120. </template>
  121. <script>
  122. import { commodityListAdd, commodityListUpdate, getGroupList, commodityListGetById, commodityListDelete } from '@/api/commodity'
  123. import XeUtils from 'xe-utils'
  124. export default {
  125. name: 'EditModal',
  126. props: {
  127. groupId: {
  128. type: Number,
  129. default: 0
  130. }
  131. },
  132. data() {
  133. return {
  134. modalOptions: {
  135. closeOnClickModal: false,
  136. width: '1120px',
  137. title: ''
  138. },
  139. visible: false,
  140. formData: {
  141. shopGroupId: '',
  142. shopId: '',
  143. groupName: '',
  144. groupImage: '',
  145. groupDescribe: '',
  146. groupLevel: '',
  147. depth: 1,
  148. groupPid: 0,
  149. childs: []
  150. },
  151. isShowManualAdd: false, // 手动添加商品模态框
  152. selectedGroupId: '',
  153. productDataList: [],
  154. productTotal: 0,
  155. listQuery: {
  156. maxPrice: null, // 价格最大值
  157. maxStock: null, // 库存数量最大值
  158. minPrice: null, // 价格最小值
  159. minStock: null, // 库存数量最小值
  160. page: 1, // 当前页
  161. pageSize: 10, // 每页记录数
  162. search: '' // 搜索字段
  163. },
  164. multipleSelection: []
  165. }
  166. },
  167. methods: {
  168. handleClose() {
  169. this.visible = false
  170. },
  171. async initList() {
  172. const res = await getGroupList(this.listQuery)
  173. this.productTotal = res.data.total
  174. this.productDataList = res.data.list
  175. },
  176. handleOpen(params = {}) {
  177. this.modalOptions.title = params.shopGroupId ? '编辑分组' : '添加分组'
  178. this.visible = true
  179. this.initList()
  180. if (params.shopGroupId) {
  181. this.getInfo(params.shopGroupId)
  182. } else {
  183. this.formData = {
  184. shopGroupId: '',
  185. shopId: '',
  186. groupName: '',
  187. groupImage: '',
  188. groupDescribe: '',
  189. groupLevel: '',
  190. depth: 1,
  191. groupPid: 0,
  192. products: [],
  193. childs: [],
  194. ids: [] // 自设
  195. }
  196. }
  197. },
  198. async getInfo(id) {
  199. const loading = this.$loading({ text: '加载中' })
  200. try {
  201. const res = await commodityListGetById({ shopGroupId: id })
  202. this.formData = Object.assign(this.$options.data().formData, res.data, {
  203. shopGroupId: res.data.shopGroupId || '',
  204. shopId: res.data.shopId || '',
  205. groupName: res.data.groupName || '',
  206. groupImage: res.data.groupImage || '',
  207. groupDescribe: res.data.groupDescribe || '',
  208. groupLevel: res.data.groupLevel || '',
  209. depth: res.data.depth || 1,
  210. groupPid: res.data.groupPid || 0,
  211. products: res.data.products || [],
  212. childs: res.data.childs || [],
  213. ids: res.data.ids || []
  214. })
  215. XeUtils.eachTree([ this.formData ], (item) => {
  216. item.ids = item.products.map((i) => i.productId)
  217. }, { children: 'childs' })
  218. } finally {
  219. loading.close()
  220. }
  221. },
  222. handleAppend(data) {
  223. if (data.depth < 3) {
  224. data.childs.push({
  225. shopGroupId: '',
  226. shopId: '',
  227. groupName: '',
  228. groupImage: '',
  229. groupDescribe: '',
  230. groupLevel: '',
  231. depth: data.depth + 1,
  232. groupPid: 0,
  233. childs: [],
  234. ids: []
  235. })
  236. }
  237. },
  238. handleDelete(data, node) {
  239. this.$confirm('选中数据将被永久删除, 是否继续?', '提示', {
  240. confirmButtonText: '确定',
  241. cancelButtonText: '取消',
  242. type: 'warning'
  243. })
  244. .then(async () => {
  245. await commodityListDelete({ shopGroupId: data.shopGroupId })
  246. this.$message({ message: '删除成功!', type: 'success' })
  247. this.getInfo(this.formData.shopGroupId)
  248. this.$emit('success')
  249. })
  250. },
  251. handleAddProduct(data, node) {
  252. this.multipleSelection = []
  253. this.selectedGroupId = data.shopGroupId
  254. this.isShowManualAdd = true
  255. },
  256. clearData() {
  257. this.listQuery = {
  258. maxPrice: null, // 价格最大值
  259. maxStock: null, // 库存数量最大值
  260. minPrice: null, // 价格最小值
  261. minStock: null, // 库存数量最小值
  262. page: 1, // 当前页
  263. pageSize: 10, // 每页记录数
  264. search: '' // 搜索字段
  265. }
  266. this.getInfo(this.formData.shopGroupId)
  267. },
  268. handleSaveIdList() {
  269. XeUtils.eachTree([ this.formData ], (item) => {
  270. if (item.shopGroupId === this.selectedGroupId) {
  271. if (this.multipleSelection.length) {
  272. item.ids = this.multipleSelection.map((i) => i.productId)
  273. } else {
  274. item.ids = []
  275. }
  276. }
  277. }, { children: 'childs' })
  278. this.isShowManualAdd = false
  279. },
  280. // 保存提交
  281. async handleSubmit() {
  282. let isGroupNameEmpty = false
  283. XeUtils.eachTree([ this.formData ], (item) => {
  284. if (!item.groupName) isGroupNameEmpty = true
  285. }, { children: 'childs' })
  286. if (isGroupNameEmpty) return this.$message({ message: '分组名称不能为空', type: 'warning' })
  287. this.formData.conditions = []
  288. this.formData.condition = null
  289. const loading = this.$loading({ text: '提交中,请稍候……' })
  290. try {
  291. const { ...otps } = this.formData
  292. const params = {
  293. ...otps
  294. }
  295. this.formData.shopGroupId ? await commodityListUpdate(params) : await commodityListAdd(params)
  296. loading.close()
  297. this.$message({ message: `${this.formData.shopGroupId ? '编辑' : '添加'}成功!`, type: 'success' })
  298. this.$emit('success')
  299. this.visible = false
  300. } catch (e) {
  301. loading.close()
  302. } finally {
  303. loading.close()
  304. }
  305. }
  306. }
  307. }
  308. </script>
  309. <style lang="scss" scoped>
  310. .tree-container {
  311. ::v-deep .el-tree-node__content {
  312. height: auto;
  313. }
  314. .filter-container {
  315. .filter-item {
  316. display: inline-block;
  317. vertical-align: middle;
  318. margin-bottom: 10px;
  319. }
  320. }
  321. }
  322. </style>