detail.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. <template>
  2. <div class="container" v-loading="loading">
  3. <el-form
  4. :model="form"
  5. :rules="rules"
  6. ref="form"
  7. label-position="right"
  8. label-width="140px">
  9. <div class="flexr">
  10. <div class="content flex1">
  11. <div class="section-title">Group</div>
  12. <el-form-item
  13. prop="groupName"
  14. label="Group Name:">
  15. <el-input
  16. v-model="form.groupName"
  17. class="add-text"
  18. placeholder=""
  19. maxlength="100"/>
  20. </el-form-item>
  21. <el-form-item
  22. prop="groupType"
  23. label="Group Type:">
  24. <el-select
  25. v-model="form.groupType"
  26. class="add-text"
  27. placeholder="">
  28. <el-option
  29. v-for="item in options.groupType"
  30. :key="item.value"
  31. :label="item.name"
  32. :value="item.value">
  33. </el-option>
  34. </el-select>
  35. </el-form-item>
  36. <el-form-item
  37. prop="contactPerson"
  38. label="Contact Person:">
  39. <el-input
  40. class="add-text"
  41. v-model="form.contactPerson"
  42. maxlength="80"/>
  43. </el-form-item>
  44. <el-form-item
  45. prop="contactNumber"
  46. label="Contact Number:">
  47. <div class="add-text flexc">
  48. <el-select
  49. style="min-width: 75px; max-width: 80px;"
  50. v-model="form.callingCode">
  51. <el-option
  52. v-for="item in options.callingCode"
  53. :key="item.callingCode"
  54. :label="'+' + item.callingCode"
  55. :value="item.callingCode"
  56. />
  57. </el-select>
  58. <el-input
  59. v-model="form.contactNumber"
  60. style="margin-left: 10px;"
  61. placeholder=""
  62. maxlength="20"/>
  63. </div>
  64. </el-form-item>
  65. <el-form-item
  66. prop="email"
  67. label="Email Address:">
  68. <el-input
  69. class="add-text"
  70. v-model="form.email"
  71. maxlength="80"/>
  72. </el-form-item>
  73. <!--el-form-item
  74. label="Login ID:">
  75. <el-input
  76. v-model="form.loginId"
  77. class="add-text"
  78. placeholder=""
  79. maxlength="50"/>
  80. </el-form-item>
  81. <el-form-item
  82. label="Password Set:">
  83. <el-input
  84. v-model="form.password"
  85. class="add-text"
  86. type="password"
  87. maxlength="20"/>
  88. </el-form-item-->
  89. <el-form-item
  90. label="Country:">
  91. <el-select
  92. v-model="form.countryCode"
  93. class="add-text"
  94. placeholder="">
  95. <el-option
  96. v-for="item in options.countryOptions"
  97. :key="item.value"
  98. :label="item.name"
  99. :value="item.value">
  100. </el-option>
  101. </el-select>
  102. </el-form-item>
  103. <el-form-item
  104. prop="discount"
  105. label="Basic Discount:">
  106. <el-input
  107. v-model="form.discount"
  108. class="add-text"
  109. maxlength="5"/>
  110. </el-form-item>
  111. <el-form-item
  112. label="Group Logo:">
  113. <el-upload
  114. class="logo-upload"
  115. action
  116. :limit="1"
  117. :show-file-list="false"
  118. :file-list="[]"
  119. :on-remove="file => removeLogo(file)"
  120. :http-request="file => uploadLogo(file)"
  121. accept=".jpg,.jpeg,.png,.gif,.JPG,.JPEG"
  122. v-loading="uploading">
  123. <el-image
  124. v-if="logos.length > 0"
  125. :src="logos[0].url"
  126. title="Click to update logo"/>
  127. <i v-else
  128. class="el-icon-plus avatar-uploader-icon"
  129. title="Click to select file"/>
  130. </el-upload>
  131. </el-form-item>
  132. </div>
  133. <div class="flex2 flexl" v-if="isEdit">
  134. <div class="content">
  135. <div class="section-title">Quick Summary</div>
  136. <Summary :info="form.quickSummary"/>
  137. </div>
  138. <div class="content flex1">
  139. <div class="section-title">Specific Discount Assignment</div>
  140. <discounts
  141. :data="form.discounts"
  142. :group="form.groupPk"
  143. :countryCode="form.countryCode"
  144. @change="getGroupDetail"/>
  145. </div>
  146. </div>
  147. </div>
  148. <div class="content flexcr">
  149. <div class="buttons">
  150. <el-button
  151. @click="onClickCancelButton"
  152. type="primary"
  153. class="cancel-button">
  154. Cancel
  155. </el-button>
  156. <el-button
  157. @click="onClickConfirmButton"
  158. type="primary">
  159. Save
  160. </el-button>
  161. </div>
  162. <div
  163. class="update-by"
  164. v-if="isEdit">
  165. <span
  166. class="add-text"
  167. :title='"CREATED BY " + form.createdBy + " ON " + form.createdOn'>
  168. LAST UPDATED BY {{form.updatedBy}} TIMESTAMP: {{form.updatedOn}}
  169. </span>
  170. </div>
  171. </div>
  172. </el-form>
  173. </div>
  174. </template>
  175. <script>
  176. import site from '@/http/api/site'
  177. import api from '@/http/api/group'
  178. import provider from '../../http/api/provider'
  179. import setting from '../../settings.js'
  180. import {getCountryList} from '../../utils/index.js'
  181. import Summary from './summary.vue'
  182. import discounts from './discounts.vue'
  183. export default {
  184. name: "GroupDetail",
  185. data() {
  186. return {
  187. loading: false,
  188. uploading: false,
  189. form: {
  190. discount: "",
  191. groupPk: "",
  192. groupName: "",
  193. groupType: "",
  194. contactPerson: "",
  195. contactNumber: "",
  196. email: "",
  197. loginId: "",
  198. password: "",
  199. groupLogo: "",
  200. callingCode: setting.defaultCalling,
  201. countryCode: setting.defaultCountry
  202. },
  203. options: {
  204. callingCode: [],
  205. countryOptions: [],
  206. groupType: []
  207. },
  208. logos: [],
  209. isEdit: false,
  210. rules: {
  211. groupType: [{
  212. message: "Please select group type",
  213. trigger: "blur",
  214. required: true,
  215. }],
  216. groupName: [{
  217. message: "Please input group name",
  218. trigger: "blur",
  219. required: true,
  220. }],
  221. contactPerson: [{
  222. message: "required",
  223. trigger: "blur",
  224. required: false,
  225. }],
  226. contactNumber: [{
  227. message: "required",
  228. trigger: "blur",
  229. required: false,
  230. }, {
  231. pattern: /^\d{6,}$/,
  232. trigger: "blur",
  233. message: "Please enter the correct number",
  234. }],
  235. discount: [{
  236. trigger: "blur",
  237. validator: (rule, value, callback, source, options) => {
  238. let pattern = /^\d*(\.)?\d{1,2}$/
  239. if (pattern.test(value)) {
  240. const lang = Number(value);
  241. if (lang < 0 || lang > 100) {
  242. callback("Discount must to be between 0 and 100")
  243. } else {
  244. callback()
  245. }
  246. } else {
  247. callback("Please enter the correct discount")
  248. }
  249. }
  250. }]
  251. }
  252. }
  253. },
  254. components: {Summary, discounts},
  255. created() {
  256. this.getCountryList()
  257. this.getGroupType()
  258. if (this.$route.params.id) {
  259. this.isEdit = true;
  260. this.getGroupDetail()
  261. }
  262. },
  263. methods: {
  264. getCountryList() {
  265. getCountryList(list => {
  266. this.options.callingCode = list
  267. })
  268. site.getCountryList().then(({ data }) => {
  269. this.options.countryOptions = data
  270. })
  271. },
  272. getGroupType() {
  273. this.loading = true;
  274. api.getUserGroupType().then(res => {
  275. if (res.data) {
  276. this.options.groupType = res.data
  277. if (!this.isEdit) {
  278. const defaultType = this.options.groupType[0].value
  279. this.form.groupType = defaultType
  280. }
  281. }
  282. }).catch(error => {
  283. this.$message({
  284. message: error,
  285. type: 'error'
  286. })
  287. }).finally(() => {
  288. this.loading = false;
  289. })
  290. },
  291. getGroupDetail() {
  292. api.getUserGroupInfo({
  293. groupPk: this.$route.params.id,
  294. }).then(res => {
  295. if (res.data) {
  296. this.form = Object.assign(this.form, res.data)
  297. if (!this.form.callingCode) {
  298. this.form.callingCode = setting.defaultCalling
  299. }
  300. if (this.form.groupLogo) {
  301. this.logos.push({
  302. path: this.form.groupLogo,
  303. url: this.$imageSrc(this.form.groupLogo)
  304. });
  305. }
  306. }
  307. }).catch(err => {
  308. this.$message({
  309. message: err,
  310. type: 'error'
  311. })
  312. })
  313. },
  314. onClickCancelButton() {
  315. this.$nextTick(() => {
  316. this.$router.replace({
  317. path: "/partnership-management/group-management"
  318. })
  319. })
  320. },
  321. onClickConfirmButton() {
  322. this.$refs.form.validate(async (valid, fields) => {
  323. if (valid) {
  324. if (this.logos.length > 0) {
  325. this.form.groupLogo = this.logos[0].path
  326. } else {
  327. this.form.groupLogo = "";
  328. }
  329. this.loading = true
  330. this.isEdit ? this.onUpdateGroup() : this.onAddGroup();
  331. }
  332. })
  333. },
  334. onAddGroup() {
  335. api.addUserGroup(this.form).then(res => {
  336. this.$message({
  337. type: 'success',
  338. message: "Add successfully!"
  339. })
  340. this.onClickCancelButton()
  341. }).catch(err => {
  342. this.$message({
  343. type: 'error',
  344. message: err
  345. })
  346. }).finally(() => {
  347. this.loading = false;
  348. })
  349. },
  350. onUpdateGroup() {
  351. api.updateUserGroup(this.form).then(res => {
  352. this.$message({
  353. type: 'success',
  354. message: "Update successfully!"
  355. })
  356. this.onClickCancelButton()
  357. }).catch(err => {
  358. this.$message({
  359. type: 'error',
  360. message: err
  361. })
  362. }).finally(() => {
  363. this.loading = false;
  364. })
  365. },
  366. uploadLogo(file) {
  367. this.uploading = true;
  368. const formData = new FormData()
  369. formData.append('file', file.file)
  370. provider.uploadLogo(formData).then(res => {
  371. //console.log("upload", res);
  372. if (this.logos.length == 0) {
  373. this.logos.push({
  374. url: ""
  375. })
  376. }
  377. this.logos[0] = ({
  378. path: res.data.picturePath,
  379. url: this.$imageSrc(res.data.picturePath)
  380. })
  381. }).catch(err => {
  382. this.$message({
  383. message: err,
  384. type: 'error'
  385. })
  386. }).finally(() => {
  387. this.uploading = false;
  388. })
  389. },
  390. removeLogo(file) {
  391. this.logos = []
  392. this.form.groupLogo = ""
  393. },
  394. }
  395. }
  396. </script>
  397. <style lang="scss" scoped>
  398. @import '../../styles/variables.scss';
  399. .container {
  400. width: 100%;
  401. padding: 20px 40px;
  402. min-height: $mainAppMinHeight;
  403. background-color: #F0F5FC;
  404. }
  405. .content {
  406. margin: 0 8px 16px;
  407. padding: 15px 50px;
  408. border-radius: 6px;
  409. background-color: white;
  410. }
  411. .section-title {
  412. color: #333;
  413. margin-top: 20px;
  414. margin-bottom: 30px;
  415. font-size: 15px;
  416. user-select: none;
  417. line-height: 24px;
  418. font-weight: bold;
  419. font-family: sans-serif;
  420. text-transform: uppercase;
  421. }
  422. .add-text {
  423. width: 100%;
  424. max-width: 300px;
  425. }
  426. .add-text ::v-deep .el-textarea__inner {
  427. font-family: sans-serif;
  428. }
  429. .hr {
  430. height: 2px;
  431. margin: 10px -40px;
  432. background-color: #F0F5FC;
  433. }
  434. .buttons {
  435. padding-top: 15px;
  436. padding-bottom: 15px;
  437. }
  438. @media screen and (max-width: 500px) {
  439. .container {
  440. padding: 0px;
  441. }
  442. .content {
  443. padding: 15px 30px;
  444. }
  445. }
  446. .logo-upload {
  447. width: 148px;
  448. height: 148px;
  449. position: relative;
  450. ::v-deep .el-image {
  451. width: 148px;
  452. height: 148px;
  453. border-radius: 6px;
  454. }
  455. }
  456. .avatar-uploader-icon {
  457. width: 148px;
  458. height: 148px;
  459. color: #8c939d;
  460. cursor: pointer;
  461. font-size: 28px;
  462. text-align: center;
  463. line-height: 148px;
  464. border-radius: 6px;
  465. border: 1px dashed #d9d9d9;
  466. }
  467. </style>