add.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <?php defined('YII_ENV') or exit('Access Denied'); ?>
  2. <?php
  3. use common\helpers\ComponentHelper;
  4. ComponentHelper::loadComponentView('com-image');
  5. ?>
  6. <style>
  7. .form-body {
  8. background-color: #fff;
  9. padding: 20px 68% 20px 0;
  10. }
  11. .button-item {
  12. margin-top: 12px;
  13. padding: 9px 25px;
  14. }
  15. .tip {
  16. margin-left: 10px;
  17. display: inline-block;
  18. height: 30px;
  19. line-height: 30px;
  20. color: #ff4544;
  21. background-color: #FEF0F0;
  22. padding: 0 20px;
  23. border-radius: 5px;
  24. }
  25. .el-table th>.cell{
  26. color: #333;
  27. font-weight: bold;
  28. font-size: 14px;
  29. }
  30. .el-dialog {
  31. border-radius:5px;
  32. }
  33. .el-dialog__header {
  34. background-color: #333;
  35. border-radius:5px 5px 0 0;
  36. }
  37. .el-dialog__title {
  38. color: #fff;
  39. }
  40. .search-form {
  41. padding: 30px 20px;
  42. background-color: #f4f7fb;
  43. display: flex;
  44. }
  45. .search-form .el-form-item {
  46. width: 60%;
  47. /* float: left; */
  48. }
  49. .claer {
  50. clear: both;
  51. }
  52. .el-dialog--center .el-dialog__body {
  53. padding: 15px 15px 20px;
  54. }
  55. .search-form .el-button {
  56. /* margin: 0 0 0 120px; */
  57. width: 100px;
  58. }
  59. </style>
  60. <section id="app" v-cloak>
  61. <el-card class="box-card" style="border:0" shadow="never" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  62. <div slot="header" class="clearfix">
  63. <el-breadcrumb separator="/">
  64. <el-breadcrumb-item><span style="color: #409EFF;cursor: pointer"
  65. @click="$navigate({r:'mall/user/index'})">用户管理</span></el-breadcrumb-item>
  66. <el-breadcrumb-item>用户{{editTitle}}</el-breadcrumb-item>
  67. </el-breadcrumb>
  68. <span></span>
  69. </div>
  70. <div class="form-body">
  71. <el-form :model="form" label-width="100px" :rules="FormRules" ref="form" v-loading="listLoading">
  72. <el-form-item v-if="form.id" label="会员 ID" prop="id">
  73. <el-input disabled size="small" v-model="form.id" autocomplete="off"></el-input>
  74. </el-form-item>
  75. <el-form-item label="用户">
  76. <com-image width="70px" height="70px" mode="aspectFill" :src="form.avatar? form.avatar:'resources/img/mall/default_avatar_url.png'" style="border-radius: 50%;"></com-image>
  77. </el-form-item>
  78. <el-form-item label="会员等级" prop="level">
  79. <el-select size="small" v-model="form.level" placeholder="请选择会员等级" style="width: 100%;">
  80. <el-option key="普通用户" label="普通用户" :value="0"></el-option>
  81. <el-option
  82. v-for="item in mall_members"
  83. :key="item.name"
  84. :label="item.name"
  85. :value="item.level">
  86. </el-option>
  87. </el-select>
  88. </el-form-item>
  89. <el-form-item label="昵称" prop="nickname">
  90. <el-input v-if="form.id" disabled size="small" v-model="form.nickname" autocomplete="off"></el-input>
  91. <el-input v-if="!form.id" size="small" v-model="form.nickname" autocomplete="off"></el-input>
  92. </el-form-item>
  93. <el-form-item label="真实姓名" prop="username">
  94. <el-input v-if="form.id" disabled size="small" v-model="form.username" autocomplete="off"></el-input>
  95. <el-input v-if="!form.id" size="small" v-model="form.username" autocomplete="off"></el-input>
  96. </el-form-item>
  97. <el-form-item label="上级推荐人" prop="parent_id">
  98. <div class="parent_left" style="width: 70%;float: left;">
  99. <com-image width="40px" height="40px" mode="aspectFill" :src="form.parent_avatar_url? form.parent_avatar_url:'resources/img/mall/default_avatar_url.png'" style="float: left;border-radius: 50%;"></com-image>
  100. <div style="float:left;line-height:22px;margin-left: 15px">{{form.parent_name}}<br />ID:{{form.parent_id}}</div>
  101. </div>
  102. <div class="parent_right" style="width: 30%;float: right;">
  103. <el-button type="primary" size="small" @click="showDialog" style="float: right;">修改上级推荐人</el-button>
  104. </div>
  105. </el-form-item>
  106. <el-form-item label="手机号" prop="mobile">
  107. <el-input size="small" v-model="form.mobile" placeholder="请输入手机号" ></el-input>
  108. <span class="tip" style="margin-left: 0;">请谨慎修改手机号</span>
  109. </el-form-item>
  110. </el-form-item>
  111. <el-form-item v-if="form.id" label="注册时间">
  112. <div>{{form.created_at}}</div>
  113. </el-form-item>
  114. </el-form>
  115. </div>
  116. <el-button class="button-item" :loading="btnLoading" type="primary" @click="onSubmit">提交</el-button>
  117. </el-card>
  118. <el-dialog
  119. :close-on-click-modal="false"
  120. class = "user-dialog"
  121. title="选择上级推荐人"
  122. :visible.sync="dialogVisible"
  123. width="40%"
  124. center>
  125. <el-form class="search-form" v-model="searchForm" label-width="100px">
  126. <el-input size="small" style="width: 180px;margin-right: 20px;" v-model="searchForm.inviter_id" placeholder="请输入会员ID"></el-input>
  127. <el-input size="small" style="width: 180px;" v-model="searchForm.keyword" placeholder="请输入手机号"></el-input>
  128. <div style="flex: 1;text-align: center;">
  129. <el-tooltip class="item" effect="dark" content="没有推广资格的用户,搜索不出来" placement="top">
  130. <el-button type="primary" size="small" @click="searchFun">查 询</el-button>
  131. </div>
  132. </el-tooltip>
  133. <div class="claer"></div>
  134. </el-form>
  135. <el-table border v-loading="listLoading2" :data="list" style="margin-top: 24px;"
  136. @selection-change="selectionChange">
  137. <el-table-column width="100px" label="ID" props="id" align="center">
  138. <template slot-scope="props">
  139. <el-radio-group v-model="radioSelection" @change="selectionChange(props.row)">
  140. <el-radio :label="props.row.id"></el-radio>
  141. </el-radio-group>
  142. </template>
  143. </el-table-column>
  144. <el-table-column label="头像">
  145. <template slot-scope="props">
  146. <div><com-image width="40px" height="40px" mode="aspectFill" :src="props.row.avatar_url? props.row.avatar_url:'/resources/img/common/default-avatar.png'" style="border-radius: 50%;"></com-image></div>
  147. </template>
  148. </el-table-column>
  149. <el-table-column label="昵称">
  150. <template slot-scope="props">
  151. <div>{{props.row.nickname}}</div>
  152. </template>
  153. </el-table-column>
  154. <el-table-column label="手机">
  155. <template slot-scope="props">
  156. <div>{{props.row.mobile}}</div>
  157. </template>
  158. </el-table-column>
  159. <el-table-column label="会员等级">
  160. <template slot-scope="props">
  161. <div>{{props.row.level_name}}</div>
  162. </template>
  163. </el-table-column>
  164. <el-table-column label="已绑定推荐人">
  165. <template slot-scope="props">
  166. <div>{{props.row.parent_name}}</div>
  167. </template>
  168. </el-table-column>
  169. </el-table>
  170. <span slot="footer" class="dialog-footer">
  171. <el-button @click="cancelSelect">取 消</el-button>
  172. <el-button type="primary" @click="confirmSelectUser">确 认</el-button>
  173. </span>
  174. </el-dialog>
  175. </section>
  176. <script>
  177. const app = new Vue({
  178. el: '#app',
  179. data() {
  180. // 联合验证国内和香港手机号
  181. const validatePhoneNumber = (rule, value, callback) => {
  182. // 国内手机号正则:11位数字,以1开头,第二位为3-9
  183. const mainlandReg = /^1[3-9]\d{9}$/;
  184. // 香港手机号正则:8位数字
  185. const hongkongReg = /^(?:\+852|00852)?[1-9]\d{7}$/;
  186. if (!value) {
  187. return callback(new Error('请输入联系电话'));
  188. }
  189. // 检查是否符合国内或香港手机号格式
  190. if (!mainlandReg.test(value) && !hongkongReg.test(value)) {
  191. return callback(new Error('请输入正确的手机号(国内11位或香港8位数字)'));
  192. }
  193. callback();
  194. };
  195. return {
  196. form: {
  197. share: {},
  198. level: ''
  199. },
  200. searchForm: {
  201. inviter_id: null,
  202. nickname: null,
  203. mobile: null,
  204. keyword: '',
  205. },
  206. mall_members: [],
  207. keyword: '',
  208. listLoading: false,
  209. btnLoading: false,
  210. FormRules: {
  211. mobile: [
  212. {required: true, message: '请输入手机号', trigger: 'change'},
  213. {validator: validatePhoneNumber, trigger: ['blur', 'change'] }
  214. ],
  215. nickname: [
  216. {required: true, message: '请输入昵称', trigger: 'change'},
  217. ],
  218. level: [
  219. {required: true, message: '请请选择会员等级', trigger: 'change'},
  220. ],
  221. },
  222. autocompleteValue:'',
  223. dialogVisible:false,
  224. list:[],
  225. radioSelection:0,
  226. selectUser:null,
  227. listLoading2:false,
  228. editTitle : '添加',
  229. };
  230. },
  231. methods: {
  232. //搜索
  233. querySearchAsync(queryString, cb) {
  234. this.keyword = queryString;
  235. this.searchUser(cb);
  236. },
  237. inviterClick(row) {
  238. this.autocompleteValue ="修改为:" + row.nickname;
  239. this.form.parent_id = row.id;
  240. },
  241. searchUser(cb) {
  242. if (!this.searchForm.inviter_id && !this.searchForm.mobile && !this.searchForm.nickname && !this.searchForm.keyword){
  243. this.$message.error('查询内容不能为空');
  244. this.listLoading2 = false;
  245. return false;
  246. }
  247. this.listLoading2 = true;
  248. request({
  249. params: {
  250. r: 'mall/user/get-can-bind-inviter',
  251. inviter_id: this.searchForm.inviter_id,
  252. mobile: this.searchForm.mobile,
  253. nickname: this.searchForm.nickname,
  254. keyword: this.searchForm.keyword,
  255. user_id: this.form.id,
  256. },
  257. }).then(e => {
  258. this.listLoading2 = false;
  259. if (e.data.code === 0) {
  260. this.list = e.data.data.list.list;
  261. } else {
  262. this.$message.error(e.data.msg);
  263. }
  264. }).catch(e => {
  265. this.listLoading2 = false;
  266. });
  267. },
  268. onSubmit() {
  269. if (this.btnLoading === true) return;
  270. this.$refs.form.validate((valid) => {
  271. if (valid) {
  272. this.btnLoading = true;
  273. let para = Object.assign({}, this.form);
  274. request({
  275. params: {
  276. r: 'mall/user/add',
  277. },
  278. data: para,
  279. method: 'post'
  280. }).then(e => {
  281. this.btnLoading = false;
  282. if (e.data.code === 0) {
  283. navigateTo({r: 'mall/user/index', page: getQuery('page')});
  284. } else {
  285. this.$message.error(e.data.msg);
  286. }
  287. });
  288. }
  289. });
  290. },
  291. //获取基础信息
  292. getAdd() {
  293. this.listLoading = true;
  294. request({
  295. params: {
  296. r: 'mall/user/add',
  297. },
  298. }).then(e => {
  299. if (e.data.code === 0) {
  300. this.mall_members = e.data.data;
  301. } else {
  302. this.$message.error(e.data.msg);
  303. }
  304. this.listLoading = false;
  305. }).catch(e => {
  306. this.listLoading = false;
  307. });
  308. },
  309. selectionChange(e){
  310. this.selectUser = e;
  311. },
  312. showDialog(){
  313. this.dialogVisible = true;
  314. this.radioSelection = 0;
  315. },
  316. confirmSelectUser(){
  317. this.dialogVisible = false;
  318. if(this.selectUser){
  319. this.form.parent_id = this.selectUser.id;
  320. this.form.parent_name = this.selectUser.nickname;
  321. this.form.parent_avatar_url = this.selectUser.avatar_url;
  322. }
  323. },
  324. cancelSelect(){
  325. this.selectUser = null;
  326. this.dialogVisible = false;
  327. },
  328. searchFun(){
  329. this.searchUser();
  330. }
  331. },
  332. computed: {
  333. cForm() {
  334. let form = {};
  335. let ruleForm = JSON.parse(JSON.stringify(this.ruleForm));
  336. if (this.form) {
  337. form = Object.assign(ruleForm, JSON.parse(JSON.stringify(this.form)));
  338. } else {
  339. form = ruleForm;
  340. }
  341. if (getQuery('id')) {
  342. form.id = getQuery('id')
  343. }
  344. return form;
  345. },
  346. cRule() {
  347. return this.rule ? Object.assign({}, this.rules, this.rule) : this.rules;
  348. },
  349. isConfineCount() {
  350. return this.ruleForm.confine_count === -1;
  351. },
  352. },
  353. mounted() {
  354. this.editTitle = '添加';
  355. this.getAdd();
  356. }
  357. })
  358. </script>