memberInformationDetails.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. <template>
  2. <el-dialog
  3. :title="title"
  4. :visible.sync="open"
  5. width="70%"
  6. append-to-body
  7. :close-on-click-modal="false"
  8. @close="cancel"
  9. >
  10. <div class="form-dialog-box"
  11. v-loading="loading"
  12. :element-loading-text="loadingText"
  13. element-loading-spinner="el-icon-loading"
  14. element-loading-background="rgba(0, 0, 0, 0.8)">
  15. <el-form :model="form" ref="form" :rules="rules" label-width="120px">
  16. <div class="form-title"><span>基本信息</span></div>
  17. <div style="display: flex;">
  18. <el-form-item label="会员名称:">
  19. <span style="display: block; min-width: 250px;">{{ form.realName }}</span>
  20. </el-form-item>
  21. <el-form-item label="性别:">
  22. <span style="display: block;min-width: 250px;">{{ form.sex }}</span>
  23. </el-form-item>
  24. </div>
  25. <div style="display: flex;">
  26. <el-form-item label="手机号:">
  27. <span style="display: block;min-width: 250px;">{{ form.mobile }}</span>
  28. </el-form-item>
  29. <el-form-item label="身份证号:">
  30. <span style="display: block;min-width: 250px;">{{ form.cardId }}</span>
  31. </el-form-item>
  32. </div>
  33. <div style="display: flex;">
  34. <el-form-item label="注册时间:">
  35. <span style="display: block;min-width: 250px;">{{ form.createTime }}</span>
  36. </el-form-item>
  37. </div>
  38. <div class="form-title"><span>会员信息</span></div>
  39. <div style="display: flex;">
  40. <el-form-item label="会员类型:">
  41. <span style="display: block;min-width: 250px;">{{ form.type }}</span>
  42. </el-form-item>
  43. <el-form-item label="会员卡号:">
  44. <span style="display: block;min-width: 250px;">{{ form.name }}</span>
  45. </el-form-item>
  46. </div>
  47. <div style="display: flex;">
  48. <el-form-item label="剩余积分:">
  49. <span style="display: block;min-width: 250px;">{{ form.credit }}</span>
  50. </el-form-item>
  51. <el-form-item label="剩余储值:">
  52. <span style="display: block;min-width: 250px;">{{ form.balance }}</span>
  53. </el-form-item>
  54. </div>
  55. <div class="form-title"><span>消费数据</span></div>
  56. <div style="display: flex;">
  57. <el-form-item label="下单数(单):">
  58. <span style="display: block;min-width: 250px;">{{ form.orderCount }}</span>
  59. </el-form-item>
  60. <el-form-item label="支付成功数(单):">
  61. <span style="display: block;min-width: 250px;">{{ form.buyCount }}</span>
  62. </el-form-item>
  63. </div>
  64. </el-form>
  65. </div>
  66. <span slot="footer" class="dialog-footer" v-if="formStatus==1">
  67. <el-button @click="cancel">关闭</el-button>
  68. </span>
  69. <!-- 添加或修改对话框 End -->
  70. </el-dialog>
  71. </template>
  72. <script>
  73. import {
  74. getTableDeatilsByIdApi,
  75. updateTableApi,
  76. addTableApi
  77. } from '@/api/CURD'
  78. export default {
  79. name: "addAndEdit",
  80. dicts: [],
  81. data() {
  82. return {
  83. title: "",
  84. model: "", // EDIT: 编辑模式 ADD : 新增模式 EDITInit : 编辑模式(需要请求详情)
  85. open: false,
  86. loading: false,
  87. loadingText: "拼命加载数据中...",
  88. formStatus: null, // 0/null : 加载中 1 : 获取详情成功 2 : 获取详情失败
  89. configUrl: {
  90. add: '', // 新增地址
  91. details: '/member/memberInfo/detail', // 详情地址
  92. edit: '', // 编辑地址
  93. },
  94. form: {
  95. id: undefined,
  96. },
  97. rules: {
  98. name: [{ required: false, message: "请输入等级名称", trigger: ["change","blur"] }],
  99. imgUrl: [{ required: false, message: "选上传图片", trigger: ["change","blur"] }],
  100. openDate: [{ required: false, message: "选择开/闭园时间范围", trigger: ["change","blur"] }],
  101. goodId: [{ required: false, message: "请输入景点产品", trigger: ["change","blur"] }],
  102. status: [{ required: false, message: "请输入开放状态", trigger: ["change","blur"] }],
  103. content: [{ required: false, message: "请输入开放状态", trigger: ["change","blur"] }],
  104. },
  105. scenicAreaProducts: [],// 景点产品关联
  106. // 富文本编辑器配置
  107. editorOption: {
  108. modules: {
  109. toolbar: [
  110. ['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线
  111. ['blockquote', 'code-block'], // 引用 代码块
  112. [{ header: 1 }, { header: 2 }], // 1、2 级标题
  113. [{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
  114. [{ script: 'sub' }, { script: 'super' }], // 上标/下标
  115. [{ indent: '-1' }, { indent: '+1' }], // 缩进
  116. [{ direction: 'rtl' }], // 文本方向
  117. [{ size: ['12', '14', '16', '18', '20', '22', '24', '28', '32', '36'] }], // 字体大小
  118. [{ header: [1, 2, 3, 4, 5, 6] }], // 标题
  119. [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
  120. // [{ font: ['songti'] }], // 字体种类
  121. [{ align: [] }], // 对齐方式
  122. ['clean'], // 清除文本格式
  123. ['image', 'video'] // 链接、图片、视频
  124. ]
  125. },
  126. placeholder: '请输入正文'
  127. },
  128. // 上传文件
  129. actionUrl: process.env.VUE_APP_BASE_API + process.env.VUE_APP_UPLOAD_IMAGE,
  130. actionUrlLoading: false,
  131. };
  132. },
  133. methods: {
  134. async initData(title , model,row){
  135. this.title = title
  136. this.open = true
  137. this.loadingText = "拼命加载数据中..."
  138. this.loading = true
  139. this.actionUrlLoading = false
  140. this.model = model
  141. this.formStatus = 0
  142. if(model=='ADD') { // 新增
  143. this.$set(this,'form',{...row,imgUrl:[]})
  144. this.formStatus = 1
  145. }else if(model=='EDIT') { // 新增
  146. let obj = {
  147. ...row,
  148. imgUrl: row.imgUrl?row.imgUrl.split(','):[]
  149. }
  150. this.$set(this,'form',obj)
  151. this.formStatus = 1
  152. }else if(model=='EDITInit') { // 新增
  153. await this.getTableDeatilsFun(row)
  154. }
  155. this.loading = false
  156. this.$nextTick(()=>{
  157. if(this.$refs["form"]) {
  158. this.$refs["form"].clearValidate();
  159. }
  160. })
  161. },
  162. /** 获取详情 */
  163. async getTableDeatilsFun(row) {
  164. const id = row.id
  165. this.loading = true
  166. try {
  167. let res = await getTableDeatilsByIdApi(this.configUrl.details,{id})
  168. if(res.code == 200) {
  169. let obj = {
  170. ...res.data,
  171. imgUrl: res.data.imgUrl?res.data.imgUrl.split(','):[],
  172. }
  173. this.$set(this,'form',JSON.parse(JSON.stringify(obj)))
  174. this.formStatus = 1
  175. }else {
  176. this.$message.error('获取详情失败!!!');
  177. this.formStatus = 2
  178. this.loading = false
  179. this.open = false;
  180. }
  181. this.loading = false
  182. } catch (error) {
  183. console.error('获取详情失败!!!!',error)
  184. this.formStatus = 2
  185. this.loading = false
  186. this.open = false;
  187. }
  188. },
  189. /**
  190. * 保存
  191. * @date 2023-11-22
  192. * @returns {any}
  193. */
  194. submitForm() {
  195. this.$refs["form"].validate(valid => {
  196. if (valid) {
  197. this.loadingText = "提交数据中..."
  198. this.loading = true
  199. if (this.model != 'ADD') {
  200. addTableApi(
  201. this.configUrl.edit,{
  202. ...this.form,
  203. imgUrl: this.form.imgUrl ? this.form.imgUrl.join(','):''
  204. }).then(response => {
  205. this.$modal.msgSuccess("修改成功");
  206. this.loading = false
  207. this.open = false;
  208. this.$emit('refresh')
  209. }).catch(()=>{
  210. this.$message.error("修改失败!!!");
  211. this.loading = false
  212. })
  213. } else {
  214. addTableApi(this.configUrl.edit,{
  215. ...this.form,
  216. imgUrl: this.form.imgUrl ? this.form.imgUrl.join(','):''
  217. }).then(response => {
  218. this.$modal.msgSuccess("新增成功");
  219. this.loading = false
  220. this.open = false;
  221. this.$emit('refresh')
  222. }).catch(()=>{
  223. this.$message.error("新增失败!!!");
  224. this.loading = false
  225. })
  226. }
  227. }
  228. });
  229. },
  230. /**
  231. * 重置
  232. * @date 2023-11-22
  233. * @returns {any}
  234. */
  235. reset() {
  236. if(this.$refs["form"]) {
  237. this.$refs["form"].clearValidate();
  238. }
  239. },
  240. /**
  241. * 关闭弹框
  242. * @date 2023-11-22
  243. * @returns {any}
  244. */
  245. cancel() {
  246. this.reset();
  247. this.open = false;
  248. },
  249. /** 上传图片 单张 */
  250. handleAvatarSuccess(response, file, fileList) {
  251. console.log("res, file",response, file, fileList)
  252. this.actionUrlLoading = false
  253. if(response.code == 200) {
  254. this.form.imgUrl.push(response.data.url)
  255. }
  256. },
  257. beforeAvatarUpload(file) {
  258. const isLt2M = file.size / 1024 / 1024 < 1;
  259. let testmsg = file.name.substring(file.name.lastIndexOf('.')+1)
  260. let typeList = ['png','jepg','jpg']
  261. const isJPG = typeList.includes(testmsg);
  262. if (!isJPG) {
  263. this.$message.error(`上传头像图片只能是 ${typeList} 格式!`);
  264. }
  265. if (!isLt2M) {
  266. this.$message.error('上传头像图片大小不能超过 1MB!');
  267. }
  268. return isJPG && isLt2M;
  269. },
  270. handleAvatarProgress(){
  271. this.actionUrlLoading = true
  272. },
  273. handleAvatarError() {
  274. this.actionUrlLoading = false
  275. },
  276. handleRemove(index) {
  277. this.form.imgUrl.splice(index,1)
  278. },
  279. },
  280. };
  281. </script>
  282. <style lang="scss" scoped>
  283. .form-dialog-box {
  284. padding: 0 30px;
  285. padding: 0 30px;
  286. min-height: 50vh;
  287. max-height: 65vh;
  288. overflow-y: auto;
  289. .form-title {
  290. padding: 0 0 10px 0;
  291. span {
  292. display: flex;
  293. color: rgba(65,80,88,1);
  294. font-size: 16px;
  295. font-family: SourceHanSansSC;
  296. font-weight: 700;
  297. line-height: 23px;
  298. border-left: 4px solid rgb(22, 132, 252);
  299. padding-left: 10px;
  300. }
  301. }
  302. ::v-deep .ql-editor {
  303. height: 400px;
  304. }
  305. .upload-btn {
  306. width: 100px;
  307. height: 100px;
  308. background-color: #fbfdff;
  309. border: dashed 1px #c0ccda;
  310. border-radius: 5px;
  311. i {
  312. font-size: 30px;
  313. margin-top: 20px;
  314. }
  315. &-text {
  316. margin-top: -10px;
  317. }
  318. }
  319. .avatar {
  320. cursor: pointer;
  321. }
  322. }
  323. .el-table{
  324. .upload-btn {
  325. width: 100px;
  326. height: 100px;
  327. background-color: #fbfdff;
  328. border: dashed 1px #c0ccda;
  329. border-radius: 5px;
  330. i {
  331. font-size: 30px;
  332. margin-top: 20px;
  333. }
  334. &-text {
  335. margin-top: -10px;
  336. }
  337. }
  338. .avatar {
  339. cursor: pointer;
  340. }
  341. }
  342. .area-container {
  343. min-height: 400px;
  344. }
  345. ::v-deep .area-wrap-city.el-cascader {
  346. line-height: normal;
  347. .el-input {
  348. cursor: pointer;
  349. width: 100% !important;
  350. height: 28px !important;
  351. .el-input__inner {
  352. display: none !important;
  353. }
  354. span.el-input__suffix {
  355. position: inherit !important;
  356. i.el-input__icon {
  357. line-height: inherit;
  358. margin-left: 5px;
  359. }
  360. }
  361. .el-input__wrapper {
  362. box-shadow: none;
  363. input {
  364. display: none;
  365. }
  366. }
  367. }
  368. .el-cascader__tags {
  369. display: none;
  370. }
  371. }
  372. .area-city-popper {
  373. .el-cascader-panel {
  374. .el-scrollbar.el-cascader-menu {
  375. .el-cascader-menu__wrap.el-scrollbar__wrap {
  376. height: 315px;
  377. }
  378. }
  379. }
  380. }
  381. ::v-deep .avatar-uploader .el-upload {
  382. border: 1px dashed #d9d9d9;
  383. border-radius: 6px;
  384. cursor: pointer;
  385. position: relative;
  386. overflow: hidden;
  387. }
  388. ::v-deep .avatar-uploader .el-upload:hover {
  389. border-color: #409EFF;
  390. }
  391. ::v-deep .avatar-uploader-icon {
  392. font-size: 28px;
  393. color: #8c939d;
  394. width: 100px;
  395. height: 100px;
  396. line-height: 100px;
  397. text-align: center;
  398. }
  399. ::v-deep .avatar {
  400. width: 100px;
  401. height: 100px;
  402. display: block;
  403. }
  404. </style>
  405. <style>
  406. .custom-class-box {
  407. z-index: 999999 !important;
  408. }
  409. </style>