index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <template>
  2. <div class="layout-container">
  3. <From :form-items="dynamicFormItems" @formSubmitted="handleFormSubmitted" @formReset="handleFormReset" />
  4. <div class="layout-container">
  5. <Table @getTableData="changeTableData" v-model:page="page" ref="table" :data="tableData"
  6. @selection-change="handleSelectionChange" style="margin-top: 10px">
  7. <el-table-column prop="" label="查看ecpm" width="110">
  8. <template #default="scope">
  9. <el-button type="primary" size="small" @click="viewEcpm(scope.row)">查看ecpm</el-button>
  10. </template>
  11. </el-table-column>
  12. <el-table-column prop="id" width="80" label="用户id" ></el-table-column>
  13. <el-table-column prop="nickName" label="用户昵称" />
  14. <el-table-column prop="openId" label="openId" />
  15. <el-table-column prop="userState" width="90" label="用户状态">
  16. <template #default="scope">
  17. {{ scope.row.userState == 0?'正常':'封禁' }}
  18. </template>
  19. </el-table-column>
  20. <el-table-column prop="gameName" label="游戏名称" width="120" />
  21. <el-table-column prop="todayAdPlay" label="今日激励广告播放数" width="160" />
  22. <el-table-column prop="totalAdPlay" label="广告播放总数" width="110" />
  23. <el-table-column prop="contribution" label="用户贡献(当日/总共)" width="160" />
  24. <el-table-column label="操作" width="90" >
  25. <template #default="scope">
  26. <el-button type="text" size="default" style="color: red;" v-if="scope.row.userState == 0" @click="block(scope.row)">封禁</el-button>
  27. <el-button type="text" size="default" style="color: green;" v-else @click="unblock(scope.row)">解封</el-button>
  28. </template>
  29. </el-table-column>
  30. </Table>
  31. </div>
  32. <Layer :layer="layer" @confirm="confirm(ruleFormRef)">
  33. <el-form ref="ruleFormRef" :rules="rules" :model="updateForm" label-width="100px" class="demo-ruleForm">
  34. <el-form-item label="用户状态:" v-if="layer.title=='更改用户状态'" prop="statusCode" label-width="120">
  35. 正常
  36. </el-form-item>
  37. <el-form-item label=" 封禁期限:" v-else prop="banDuration" label-width="120">
  38. <el-input v-model="updateForm.banDuration" type="number" placeholder="请输入封禁期限" >
  39. <template #append>小时</template>
  40. </el-input>
  41. </el-form-item>
  42. <el-form-item :label="layer.title=='更改用户状态' ?'解封原因:': '封禁原因:'" prop="banReason" label-width="120">
  43. <el-input :placeholder="layer.title=='更改用户状态' ?'请输入解封原因:': '请输入封禁原因:'" maxlength="15" v-model="updateForm.banReason">
  44. </el-input>
  45. </el-form-item>
  46. </el-form>
  47. </Layer>
  48. <Layer :layer="layerView" @close="adType = null">
  49. <el-form ref="ruleFormRef" :rules="rules" :model="updateForm" label-width="100px" class="demo-ruleForm">
  50. <el-row>
  51. <el-form-item label="广告类型:" prop="adType" label-width="120">
  52. <el-select v-model="adType" placeholder="请选择" style="width: 240px">
  53. <el-option
  54. v-for="item in options"
  55. :key="item.value"
  56. :label="item.label"
  57. :value="item.value"
  58. />
  59. </el-select>
  60. </el-form-item>
  61. <el-form-item label="" label-width="20">
  62. <el-button type="primary" @click="ecpmSearch">查询</el-button>
  63. <el-button @click="ecpmReset">重置</el-button>
  64. </el-form-item>
  65. </el-row>
  66. </el-form>
  67. <Table ref="tableECPM" v-model:page="ecpmPage" :data="ecpmList" style="margin-top: 10px;max-height: 500px;overflow-y: auto;">
  68. <el-table-column prop="id" label="用户id" ></el-table-column>
  69. <el-table-column prop="advertisingType" label="广告类型" >
  70. <template #default="scope">
  71. {{ scope.row.advertisingType == '1'?'激励广告':scope.row.advertisingType == '2'?'插屏广告':'bannner广告' }}
  72. </template>
  73. </el-table-column>
  74. <el-table-column prop="ecpm" label="ECPM" />
  75. <el-table-column prop="earnings" label="收益" width="120" />
  76. <el-table-column prop="accomplishTime" label="完成时间" width="150" />
  77. </Table>
  78. </Layer>
  79. </div>
  80. </template>
  81. <script setup>
  82. import { onBeforeMount, ref, reactive } from "vue";
  83. import { ElMessage } from "element-plus";
  84. import Table from "@/components/table/index.vue";
  85. import From from "@/components/from/index.vue";
  86. import Layer from "@/components/layer/index.vue";
  87. import { sysUserUpdate, sysUserRegister, sysUserPage, becomeHead,
  88. queryUserList,disableUser,enableUser,updateUserStatus,queryUserEcpm } from '@/api/sysUser'
  89. import { queryGameList } from '@/api/common.js'
  90. import { beforeAvatarUpload } from '@/utils/index.js'
  91. import { Plus } from "@element-plus/icons-vue";
  92. import OssUploader from "@/utils/ossUploader.js";
  93. const partnerList = ['普通用户','初级合伙人','高级合伙人','团长']
  94. const ossUploader = new OssUploader();
  95. // const gameList=
  96. onBeforeMount(async() => {
  97. searchFormList();
  98. let res = await queryGameList()
  99. if(res.length){
  100. res = res.map(item=>{
  101. return{
  102. label:item.gameName,
  103. value:item.gameCode
  104. }
  105. })
  106. }
  107. dynamicFormItems.value[0].options = res
  108. console.log('res',res)
  109. });
  110. const adType = ref('')
  111. const options = [
  112. {
  113. value: '1',
  114. label: '激励',
  115. },
  116. {
  117. value: '2',
  118. label: '插屏',
  119. },
  120. {
  121. value: '3',
  122. label: 'banner',
  123. },
  124. ]
  125. const ecpmList = ref([])
  126. const ecpmUserId = ref('')
  127. const searchEcpmList = async() =>{
  128. // 获取对应的数据
  129. const res = await queryUserEcpm({
  130. advertisingType:adType.value,
  131. userId:ecpmUserId.value,
  132. })
  133. ecpmList.value = res
  134. ecpmPage.total = res.length;
  135. }
  136. // ecpm 查询/重置
  137. const ecpmSearch = ()=>{
  138. searchEcpmList()
  139. }
  140. // ecpm 查询/重置
  141. const ecpmReset = ()=>{
  142. adType.value = null
  143. searchEcpmList()
  144. }
  145. const tableData = ref([]);
  146. // 分页参数, 供table使用
  147. const page = reactive({
  148. pageNum: 1,
  149. pageSize: 20,
  150. total: 0,
  151. });
  152. const ecpmPage = reactive({
  153. pageNum: 1,
  154. pageSize: 100,
  155. total: 0,
  156. });
  157. const ruleFormRef = ref(null);
  158. const layer = ref({
  159. show: false,
  160. title: "新增",
  161. showButton: true,
  162. });
  163. const layerView = ref({
  164. show: false,
  165. title: "查看ECPM",
  166. showButton: false,
  167. });
  168. const dynamicFormItems = ref([
  169. { label: "游戏名称",
  170. prop: "gameCode",
  171. type: "select",
  172. options: [
  173. { label: "游戏1", value: 0 },
  174. { label: "游戏2", value: 1 },
  175. ],},
  176. { label: "用户id", prop: "userId", type: "input" },
  177. { label: "openId", prop: "openId", type: "input" },//"daterange"
  178. {
  179. label: "用户状态",
  180. prop: "userState",
  181. type: "select",
  182. options: [
  183. { label: "正常", value: 0 },
  184. { label: "封禁", value: 1 },
  185. ],
  186. },
  187. // 其他动态的表单项配置
  188. ]);
  189. const handleFormSubmitted = (formData) => {
  190. console.log("接收到子组件传递的数据", formData);
  191. if (formData.createdTime) {
  192. formSearch.value.beginTime = new Date(formData.createdTime[0])
  193. .toLocaleDateString()
  194. .slice()
  195. .replace(/\//g, "-");
  196. formSearch.value.endTime = new Date(formData.createdTime[1])
  197. .toLocaleDateString()
  198. .slice()
  199. .replace(/\//g, "-");
  200. } else {
  201. formSearch.value.beginTime = null;
  202. formSearch.value.endTime = null;
  203. }
  204. // 其他处理逻辑
  205. Object.assign(formSearch.value, formData)
  206. formSearch.value.createdTime = undefined
  207. searchFormList();
  208. };
  209. const updateForm = ref({
  210. userId: '',//用户id
  211. banDuration: '',//封禁时长(小时)
  212. banReason: '',// 封禁原因
  213. });
  214. const checkLoginName = (rule, value, callback) => {
  215. // 判断传入的值是否可以通过校验
  216. const regex = /^[a-zA-Z0-9]{3,10}$/;
  217. if (value && !regex.test(value)) {
  218. callback(new Error("用户名限3-10位以内数字、字母"));
  219. } else {
  220. callback();
  221. }
  222. };
  223. const checkNickName = (rule, value, callback) => {
  224. // 判断传入的值是否可以通过校验
  225. // const regex = /^[A-Za-z0-9\u4e00-\u9fa5]{1,10}$/;
  226. // if (value && !regex.test(value)) {
  227. // callback(new Error("昵称限3-15位以内中文、数字或字母"));
  228. // } else {
  229. callback();
  230. // }
  231. };
  232. const checkEncodedPassword = (rule, value, callback) => {
  233. // 判断传入的值是否可以通过校验
  234. // const regex = /^[A-Za-z\d]{6,16}$/;
  235. // if (value && !regex.test(value)) {
  236. // callback(new Error("密码限6-16位数字、字母组成"));
  237. // } else {
  238. callback();
  239. // }
  240. };
  241. const rules = reactive({
  242. userLoginName: [
  243. {
  244. required: true,
  245. message: "请输入用户名",
  246. trigger: "blur",
  247. },
  248. { validator: checkLoginName, trigger: "blur" },
  249. ],
  250. banDuration: [
  251. {
  252. required: true,
  253. message: "请输入封禁期限",
  254. trigger: "blur",
  255. },
  256. // { validator: checkNickName, trigger: "blur" },
  257. ],
  258. banReason: [
  259. {
  260. required: true ,
  261. message: "请输入原因",
  262. trigger: "blur",
  263. },
  264. // { validator: checkEncodedPassword, trigger: "blur" },
  265. ],
  266. // statusCode: [
  267. // {
  268. // required: true,
  269. // message: "请选择状态",
  270. // trigger: "change",
  271. // },
  272. // ],
  273. });
  274. const confirm = async (formEl) => {
  275. let data = updateForm.value
  276. console.log('data',data)
  277. await formEl.validate(async (valid, fields) => {
  278. if (valid) {
  279. // data.id ? await sysUserUpdate(data) : await sysUserRegister(data)
  280. if(layer.value.title=='更改用户状态'){ // 解封
  281. // enableUser 、 updateUserStatus
  282. enableUser({
  283. userId:data.userId,
  284. id:data.userId,
  285. deblockingReason:data.banReason,
  286. userState:0, // 解封
  287. }).then(res=>{
  288. layer.value.show = false;
  289. ElMessage.success("解封成功");
  290. })
  291. }else{ // 封禁
  292. disableUser({
  293. userId:data.userId,
  294. banDuration:data.banDuration,
  295. banReason:data.banReason
  296. }).then(res=>{
  297. layer.value.show = false;
  298. ElMessage.success("封禁成功");
  299. })
  300. }
  301. setTimeout(()=>{
  302. searchFormList();
  303. },300)
  304. } else {
  305. console.log("error submit!", fields);
  306. }
  307. });
  308. };
  309. // 查询
  310. const searchFormList = async () => {
  311. // const res = await sysUserPage(formSearch.value);
  312. const res = await queryUserList(formSearch.value);
  313. tableData.value = res.records;
  314. page.total = res.total;
  315. };
  316. const changeTableData = () => {
  317. formSearch.value.pageNum = page.pageNum;
  318. formSearch.value.pageSize = page.pageSize;
  319. searchFormList();
  320. };
  321. const handleFormReset = () => {
  322. formSearch.value = {
  323. hours: "", //用户真实名称查询
  324. userLoginName: "", //用户用户名查询
  325. id: "", //用户ID
  326. pageNum: 1,
  327. pageSize: 20,
  328. };
  329. // 其他处理逻辑
  330. searchFormList();
  331. };
  332. const formSearch = ref({
  333. hours: "", //用户真实名称查询
  334. userLoginName: "", //用户用户名查询
  335. userPhone: "", //用户手机号
  336. pageNum: 1,
  337. pageSize: 20,
  338. });
  339. const handleSelectionChange = (val) => {
  340. chooseData.value = val;
  341. };
  342. // 查看ecpm
  343. const viewEcpm = async(row)=>{
  344. layerView.value.show = true
  345. ecpmUserId.value = row.id
  346. searchEcpmList()
  347. }
  348. // 封禁
  349. const block = async(row)=>{
  350. layer.value.title = "封禁用户";
  351. layer.value.show = true
  352. setTimeout(() => { ruleFormRef.value.clearValidate();updateForm.value.userId = row.id })
  353. // ElMessage.success('操作成功')
  354. }
  355. // 解除封禁
  356. const unblock = async(row)=>{
  357. layer.value.title = "更改用户状态";
  358. layer.value.show = true
  359. setTimeout(() => { ruleFormRef.value.clearValidate();updateForm.value.userId = row.id })
  360. // ElMessage.success('操作成功')
  361. }
  362. // 编辑
  363. const edit = async (row) => {
  364. // console.log(row);
  365. // storage.value = row;
  366. layer.value.title = "编辑";
  367. layer.value.show = true;
  368. updateForm.value.userLoginName = row.userLoginName
  369. // updateForm.value.reason = row.reason
  370. updateForm.value.hours = row.hours
  371. updateForm.value.userImg = row.userImg
  372. updateForm.value.id = row.id
  373. setTimeout(() => { ruleFormRef.value.clearValidate() })
  374. };
  375. // 删除
  376. const del = async (row) => {
  377. await sysUserUpdate({ id: row.id, delInd: '1' });
  378. ElMessage.success("删除成功");
  379. searchFormList();
  380. };
  381. const selfUpload = (param) => {
  382. const file = param.file;
  383. const currentPath = "admin/";
  384. // const formData = new FormData();
  385. // formData.append("file", file); // 这里可以根据需要设置其他表单字段
  386. // // formData.append("filePath", currentPath);
  387. // uploadFile(formData).then((res) => {
  388. // if(res.statusCode === 200){
  389. // ElMessage.success('上传成功');
  390. // }
  391. // // console.log(res,8);
  392. // updateForm.value.userImg = res;
  393. // });
  394. // return formData;
  395. ossUploader
  396. .uploadFile(file, currentPath)
  397. .then((res) => {
  398. ElMessage.success("上传成功");
  399. updateForm.value.userImg = res;
  400. })
  401. .catch((error) => {
  402. ElMessage.error("上传失败");
  403. });
  404. };
  405. </script>
  406. <style lang="scss" scoped>
  407. .btn {
  408. display: flex;
  409. margin: 10px;
  410. }
  411. .avatar {
  412. width: 50px;
  413. height: 50px;
  414. }
  415. .avatar-uploader .avatar {
  416. width: 178px;
  417. height: 178px;
  418. display: block;
  419. }
  420. .el-icon.avatar-uploader-icon {
  421. font-size: 28px;
  422. color: #8c939d;
  423. height: 178px;
  424. width: 178px;
  425. text-align: center;
  426. }
  427. </style>